Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32beb2c6 authored by John Spurlock's avatar John Spurlock
Browse files

Hideybars part I - Overlay status bar via an intent.

Implement new mode for status bar, allowing it to overlay
windows that use WM.LP.FLAG_FULLSCREEN, and introduce
transparency.

No gesture is implemented yet, for now the auto-hiding
status bar can be shown using a debugging intent.
  android.intent.action.HIDEYBARS

The auto-hiding status bar hides 3 seconds after shown,
or 3 seconds after last user-interaction with the shade.

Change-Id: Ie4bd625b9cbcddea8f818154719c7a6075972f2a
parent 9c3b3aec
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -2477,6 +2477,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
     */
    public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
    public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
    /**
     * @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
     * @hide
     */
     */
+54 −3
Original line number Original line Diff line number Diff line
@@ -132,6 +132,9 @@ public class PhoneStatusBar extends BaseStatusBar {
    private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
    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 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
    // fling gesture tuning parameters, scaled to display density
    private float mSelfExpandVelocityPx; // classic value: 2000px/s
    private float mSelfExpandVelocityPx; // classic value: 2000px/s
    private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
    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
    @Override
    public void start() {
    public void start() {
        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
@@ -1384,6 +1396,8 @@ public class PhoneStatusBar extends BaseStatusBar {
        }
        }


        visibilityChanged(true);
        visibilityChanged(true);

        suspendAutohide();
    }
    }


    public void animateCollapsePanels() {
    public void animateCollapsePanels() {
@@ -1666,6 +1680,11 @@ public class PhoneStatusBar extends BaseStatusBar {
            mPostCollapseCleanup.run();
            mPostCollapseCleanup.run();
            mPostCollapseCleanup = null;
            mPostCollapseCleanup = null;
        }
        }

        // Reschedule suspended auto-hide if necessary
        if (mAutohideSuspended) {
            scheduleAutohide();
        }
    }
    }


    /**
    /**
@@ -1812,6 +1831,7 @@ public class PhoneStatusBar extends BaseStatusBar {
            hideCling();
            hideCling();
        }
        }


        suspendAutohide();
        return false;
        return false;
    }
    }


@@ -1855,8 +1875,39 @@ public class PhoneStatusBar extends BaseStatusBar {
                setStatusBarLowProfile(lightsOut);
                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) {
    private void setStatusBarLowProfile(boolean lightsOut) {
@@ -1913,9 +1964,9 @@ public class PhoneStatusBar extends BaseStatusBar {
        }
        }
    }
    }


    private void notifyUiVisibilityChanged() {
    private void notifyUiVisibilityChanged(int vis) {
        try {
        try {
            mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
            mWindowManagerService.statusBarVisibilityChanged(vis);
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
        }
        }
    }
    }
+69 −3
Original line number Original line Diff line number Diff line
@@ -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_HOME_KEY = "homekey";
    static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
    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
     * These are the system UI flags that, when changing, can cause the layout
     * of the screen to change.
     * of the screen to change.
@@ -544,6 +546,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }
    }
    MyOrientationListener mOrientationListener;
    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() {
    IStatusBarService getStatusBarService() {
        synchronized (mServiceAquireLock) {
        synchronized (mServiceAquireLock) {
            if (mStatusBarService == null) {
            if (mStatusBarService == null) {
@@ -892,6 +906,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
        filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
        context.registerReceiver(mMultiuserReceiver, filter);
        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);
        mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
        mLongPressVibePattern = getLongIntArray(mContext.getResources(),
        mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                com.android.internal.R.array.config_longPressVibePattern);
                com.android.internal.R.array.config_longPressVibePattern);
@@ -2480,6 +2499,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {


    @Override
    @Override
    public int adjustSystemUiVisibilityLw(int visibility) {
    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
        // Reset any bits in mForceClearingStatusBarVisibility that
        // are now clear.
        // are now clear.
        mResettingSystemUiFlags &= visibility;
        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.
                // For layout, the status bar is always at the top with our fixed height.
                mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
                mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;


                boolean statusBarOverlay = (mLastSystemUiFlags & View.STATUS_BAR_OVERLAY) != 0;

                // If the status bar is hidden, we don't want to cause
                // If the status bar is hidden, we don't want to cause
                // windows behind it to scroll.
                // windows behind it to scroll.
                if (mStatusBar.isVisibleLw()) {
                if (mStatusBar.isVisibleLw() && !statusBarOverlay) {
                    // Status bar may go away, so the screen area it occupies
                    // Status bar may go away, so the screen area it occupies
                    // is available to apps but just covering them when the
                    // is available to apps but just covering them when the
                    // status bar is visible.
                    // status bar is visible.
@@ -2735,12 +2760,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                            mContentLeft, mContentTop, mContentRight, mContentBottom,
                            mContentLeft, mContentTop, mContentRight, mContentBottom,
                            mCurLeft, mCurTop, mCurRight, mCurBottom));
                            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,
                    // If the status bar is currently requested to be visible,
                    // and not in the process of animating on or off, then
                    // and not in the process of animating on or off, then
                    // we can tell the app that it is covered by it.
                    // we can tell the app that it is covered by it.
                    mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
                    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
                // 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
                // has the FLAG_FULLSCREEN set.  Not sure if there is another way that to be the
                // case though.
                // 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 (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
                    if (mStatusBar.hideLw(true)) {
                    if (mStatusBar.hideLw(true)) {
                        changes |= FINISH_LAYOUT_REDO_LAYOUT;
                        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
    @Override
    public void screenTurnedOff(int why) {
    public void screenTurnedOff(int why) {
        EventLog.writeEvent(70000, 0);
        EventLog.writeEvent(70000, 0);
@@ -4794,12 +4845,27 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // will quickly lose focus once it correctly gets hidden.
            // will quickly lose focus once it correctly gets hidden.
            return 0;
            return 0;
        }
        }

        int tmpVisibility = mFocusedWindow.getSystemUiVisibility()
        int tmpVisibility = mFocusedWindow.getSystemUiVisibility()
                & ~mResettingSystemUiFlags
                & ~mResettingSystemUiFlags
                & ~mForceClearedSystemUiFlags;
                & ~mForceClearedSystemUiFlags;
        if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
        if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
            tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
            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;
        final int visibility = tmpVisibility;
        int diff = visibility ^ mLastSystemUiFlags;
        int diff = visibility ^ mLastSystemUiFlags;
        final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
        final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);