summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java57
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java72
3 files changed, 135 insertions, 6 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a8e66ec..789fe40 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2479,6 +2479,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to specify that the status bar should temporarily overlay underlying content
+ * that is otherwise assuming the status bar is hidden. The status bar will typically
+ * have some degree of transparency while in this temporary overlay mode.
+ */
+ public static final int STATUS_BAR_OVERLAY = 0x04000000;
+
+ /**
+ * @hide
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index d98f08e..498d869 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -132,6 +132,9 @@ public class PhoneStatusBar extends BaseStatusBar {
private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
+ private static final long AUTOHIDE_TIMEOUT_MS = 3000;
+ private static final float TRANSPARENT_ALPHA = 0.7f;
+
// fling gesture tuning parameters, scaled to display density
private float mSelfExpandVelocityPx; // classic value: 2000px/s
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -304,6 +307,15 @@ public class PhoneStatusBar extends BaseStatusBar {
}
};
+ private boolean mAutohideSuspended;
+
+ private final Runnable mAutohide = new Runnable() {
+ @Override
+ public void run() {
+ int requested = mSystemUiVisibility & ~View.STATUS_BAR_OVERLAY;
+ notifyUiVisibilityChanged(requested);
+ }};
+
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
@@ -1384,6 +1396,8 @@ public class PhoneStatusBar extends BaseStatusBar {
}
visibilityChanged(true);
+
+ suspendAutohide();
}
public void animateCollapsePanels() {
@@ -1666,6 +1680,11 @@ public class PhoneStatusBar extends BaseStatusBar {
mPostCollapseCleanup.run();
mPostCollapseCleanup = null;
}
+
+ // Reschedule suspended auto-hide if necessary
+ if (mAutohideSuspended) {
+ scheduleAutohide();
+ }
}
/**
@@ -1812,6 +1831,7 @@ public class PhoneStatusBar extends BaseStatusBar {
hideCling();
}
+ suspendAutohide();
return false;
}
@@ -1855,10 +1875,41 @@ public class PhoneStatusBar extends BaseStatusBar {
setStatusBarLowProfile(lightsOut);
}
- notifyUiVisibilityChanged();
+ if (0 != (diff & View.STATUS_BAR_OVERLAY)) {
+ boolean overlay = 0 != (vis & View.STATUS_BAR_OVERLAY);
+ if (overlay) {
+ setTransparent(true);
+ scheduleAutohide();
+ } else {
+ setTransparent(false);
+ cancelAutohide();
+ }
+ }
+ notifyUiVisibilityChanged(mSystemUiVisibility);
}
}
+ private void suspendAutohide() {
+ mHandler.removeCallbacks(mAutohide);
+ mAutohideSuspended = (0 != (mSystemUiVisibility & View.STATUS_BAR_OVERLAY));
+ }
+
+ private void cancelAutohide() {
+ mAutohideSuspended = false;
+ mHandler.removeCallbacks(mAutohide);
+ }
+
+ private void scheduleAutohide() {
+ cancelAutohide();
+ mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
+ }
+
+ private void setTransparent(boolean transparent) {
+ float alpha = transparent ? TRANSPARENT_ALPHA : 1;
+ if (DEBUG) Slog.d(TAG, "Setting alpha to " + alpha);
+ mStatusBarView.setAlpha(alpha);
+ }
+
private void setStatusBarLowProfile(boolean lightsOut) {
if (mLightsOutAnimation == null) {
final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
@@ -1913,9 +1964,9 @@ public class PhoneStatusBar extends BaseStatusBar {
}
}
- private void notifyUiVisibilityChanged() {
+ private void notifyUiVisibilityChanged(int vis) {
try {
- mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
+ mWindowManagerService.statusBarVisibilityChanged(vis);
} catch (RemoteException ex) {
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 9283243..2988727 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -146,6 +146,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
+ static public final String ACTION_HIDEYBARS = "android.intent.action.HIDEYBARS";
+
/**
* These are the system UI flags that, when changing, can cause the layout
* of the screen to change.
@@ -544,6 +546,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
MyOrientationListener mOrientationListener;
+ private static final int HIDEYBARS_NONE = 0;
+ private static final int HIDEYBARS_SHOWING = 1;
+ private static final int HIDEYBARS_HIDING = 2;
+ private int mHideybars;
+
+ BroadcastReceiver mHideybarsReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ receivedHideybars(intent.getAction());
+ }
+ };
+
IStatusBarService getStatusBarService() {
synchronized (mServiceAquireLock) {
if (mStatusBarService == null) {
@@ -892,6 +906,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
context.registerReceiver(mMultiuserReceiver, filter);
+ // register for hideybars
+ filter = new IntentFilter();
+ filter.addAction(ACTION_HIDEYBARS);
+ context.registerReceiver(mHideybarsReceiver, filter);
+
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_longPressVibePattern);
@@ -2480,6 +2499,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public int adjustSystemUiVisibilityLw(int visibility) {
+ if (mHideybars == HIDEYBARS_SHOWING && 0 == (visibility & View.STATUS_BAR_OVERLAY)) {
+ mHideybars = HIDEYBARS_HIDING;
+ mStatusBar.hideLw(true);
+ }
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
mResettingSystemUiFlags &= visibility;
@@ -2715,9 +2738,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// For layout, the status bar is always at the top with our fixed height.
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
+ boolean statusBarOverlay = (mLastSystemUiFlags & View.STATUS_BAR_OVERLAY) != 0;
+
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
- if (mStatusBar.isVisibleLw()) {
+ if (mStatusBar.isVisibleLw() && !statusBarOverlay) {
// Status bar may go away, so the screen area it occupies
// is available to apps but just covering them when the
// status bar is visible.
@@ -2735,12 +2760,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContentLeft, mContentTop, mContentRight, mContentBottom,
mCurLeft, mCurTop, mCurRight, mCurBottom));
}
- if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()) {
+ if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() && !statusBarOverlay) {
// If the status bar is currently requested to be visible,
// and not in the process of animating on or off, then
// we can tell the app that it is covered by it.
mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
}
+ if (mHideybars == HIDEYBARS_HIDING && !mStatusBar.isVisibleLw()) {
+ // Hideybars have finished animating out, cleanup and reset alpha
+ mHideybars = HIDEYBARS_NONE;
+ updateSystemUiVisibilityLw();
+ }
}
}
}
@@ -3320,7 +3350,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
- if (topIsFullscreen) {
+ if (mHideybars == HIDEYBARS_SHOWING) {
+ if (mStatusBar.showLw(true)) {
+ changes |= FINISH_LAYOUT_REDO_LAYOUT;
+ }
+ } else if (topIsFullscreen) {
if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
if (mStatusBar.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT;
@@ -4060,6 +4094,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
+ private void receivedHideybars(String action) {
+ synchronized(mLock) {
+ if (action.equals(ACTION_HIDEYBARS)) {
+ if (mHideybars == HIDEYBARS_SHOWING) {
+ if (DEBUG) Slog.d(TAG, "Not showing hideybars, already shown");
+ return;
+ }
+ if (mStatusBar.isDisplayedLw()) {
+ if (DEBUG) Slog.d(TAG, "Not showing hideybars, status bar already visible");
+ return;
+ }
+ mHideybars = HIDEYBARS_SHOWING;
+ updateSystemUiVisibilityLw();
+ }
+ }
+ }
+
@Override
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
@@ -4794,12 +4845,27 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// will quickly lose focus once it correctly gets hidden.
return 0;
}
+
int tmpVisibility = mFocusedWindow.getSystemUiVisibility()
& ~mResettingSystemUiFlags
& ~mForceClearedSystemUiFlags;
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
}
+
+ boolean hideybarsAllowed =
+ (mFocusedWindow.getAttrs().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
+ || mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
+ if (mHideybars == HIDEYBARS_SHOWING) {
+ if (!hideybarsAllowed) {
+ mHideybars = HIDEYBARS_NONE;
+ } else {
+ tmpVisibility |= View.STATUS_BAR_OVERLAY;
+ if ((mLastSystemUiFlags & View.STATUS_BAR_OVERLAY) == 0) {
+ mStatusBar.showLw(true);
+ }
+ }
+ }
final int visibility = tmpVisibility;
int diff = visibility ^ mLastSystemUiFlags;
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);