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

Commit 341c3fb8 authored by Nick Chameyev's avatar Nick Chameyev
Browse files

Hide navigation bar view immediately when folding to AOD

This CL addresses two problems with navbar visibility
when folding a foldable device to AOD:
* Hiding of navbar insets sometimes doesn't work when
  calling hide() immediately after creation of a window
  because of a race in insets controller.
  As a workaround added applying visibility to the
  view itself when doing the fold to AOD animation.
* Navigation bar creation happens in onConfigChange
  of SysUI and it is not synchronized with starting
  doze mode event from DozeService. So sometimes
  we skipped hiding the navbar because it hasn't been
  created yet at the moment when we started dozing.
  To avoid this issue added applying of the initial
  visibility to navigation bar when creating.

Bug: 202844967
Test: aod enabled, fold => navbar is not visible
Test: aod enabled, fold, turn on => navbar is visible
Test: lock/unlock using power button when aod enabled/disabled
Change-Id: I2773e1eb4221e1a97860478b2d772b91803e6bf5
parent 0d5f2aed
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        return mNavigationBarView;
    }

    public View createView(Bundle savedState) {
    public View createView(Bundle savedState, boolean initialVisibility) {
        mFrame = (NavigationBarFrame) LayoutInflater.from(mContext).inflate(
                R.layout.navigation_bar_window, null);
        View barView = LayoutInflater.from(mFrame.getContext()).inflate(
@@ -550,6 +550,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        barView.addOnAttachStateChangeListener(this);
        mNavigationBarView = barView.findViewById(R.id.navigation_bar_view);

        mNavigationBarView.setVisibility(initialVisibility ? View.VISIBLE : View.INVISIBLE);

        if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + barView);
        mWindowManager.addView(mFrame,
                getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
+6 −1
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.pip.Pip;
@@ -84,6 +85,7 @@ public class NavigationBarController implements
    private final NavigationBar.Factory mNavigationBarFactory;
    private final DisplayManager mDisplayManager;
    private final TaskbarDelegate mTaskbarDelegate;
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private int mNavMode;
    @VisibleForTesting boolean mIsTablet;

@@ -107,6 +109,7 @@ public class NavigationBarController implements
            NavBarHelper navBarHelper,
            TaskbarDelegate taskbarDelegate,
            NavigationBar.Factory navigationBarFactory,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            DumpManager dumpManager,
            AutoHideController autoHideController,
            LightBarController lightBarController,
@@ -121,6 +124,7 @@ public class NavigationBarController implements
        mConfigChanges.applyNewConfig(mContext.getResources());
        mNavMode = navigationModeController.addListener(this);
        mTaskbarDelegate = taskbarDelegate;
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
        mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
                navBarHelper, navigationModeController, sysUiFlagsContainer,
                dumpManager, autoHideController, lightBarController, pipOptional,
@@ -320,7 +324,8 @@ public class NavigationBarController implements

        mNavigationBars.put(displayId, navBar);

        View navigationBarView = navBar.createView(savedState);
        boolean navBarVisible = mStatusBarKeyguardViewManager.isNavBarVisible();
        View navigationBarView = navBar.createView(savedState, navBarVisible);
        navigationBarView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View v) {
+34 −8
Original line number Diff line number Diff line
@@ -68,10 +68,13 @@ import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.unfold.FoldAodAnimationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Optional;

import javax.inject.Inject;

@@ -87,7 +90,7 @@ import dagger.Lazy;
public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
        StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
        PanelExpansionListener, NavigationModeController.ModeChangedListener,
        KeyguardViewController {
        KeyguardViewController, FoldAodAnimationController.FoldAodAnimationStatus {

    // When hiding the Keyguard with timing supplied from WindowManager, better be early than late.
    private static final long HIDE_TIMING_CORRECTION_MS = - 16 * 3;
@@ -113,6 +116,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    private final KeyguardBouncer.Factory mKeyguardBouncerFactory;
    private final KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
    private final DreamOverlayStateController mDreamOverlayStateController;
    @Nullable
    private final FoldAodAnimationController mFoldAodAnimationController;
    private KeyguardMessageAreaController mKeyguardMessageAreaController;
    private final Lazy<ShadeController> mShadeController;
    private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
@@ -186,6 +191,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    private boolean mPulsing;
    private boolean mGesturalNav;
    private boolean mIsDocked;
    private boolean mScreenOffAnimationPlaying;

    protected boolean mFirstUpdate = true;
    protected boolean mLastShowing;
@@ -199,6 +205,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    private boolean mLastIsDocked;
    private boolean mLastPulsing;
    private int mLastBiometricMode;
    private boolean mLastScreenOffAnimationPlaying;
    private boolean mQsExpanded;

    private OnDismissAction mAfterKeyguardGoneAction;
@@ -246,6 +253,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
            NotificationMediaManager notificationMediaManager,
            KeyguardBouncer.Factory keyguardBouncerFactory,
            KeyguardMessageAreaController.Factory keyguardMessageAreaFactory,
            Optional<SysUIUnfoldComponent> sysUIUnfoldComponent,
            Lazy<ShadeController> shadeController,
            LatencyTracker latencyTracker) {
        mContext = context;
@@ -264,6 +272,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        mKeyguardMessageAreaFactory = keyguardMessageAreaFactory;
        mShadeController = shadeController;
        mLatencyTracker = latencyTracker;
        mFoldAodAnimationController = sysUIUnfoldComponent
                .map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
    }

    @Override
@@ -317,6 +327,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        mConfigurationController.addCallback(this);
        mGesturalNav = QuickStepContract.isGesturalMode(
                mNavigationModeController.addListener(this));
        if (mFoldAodAnimationController != null) {
            mFoldAodAnimationController.addCallback(this);
        }
        if (mDockManager != null) {
            mDockManager.addListener(mDockEventListener);
            mIsDocked = mDockManager.isDocked();
@@ -965,6 +978,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() {
        @Override
        public void run() {
            NavigationBarView view = mStatusBar.getNavigationBarView();
            if (view != null) {
                view.setVisibility(View.VISIBLE);
            }
            mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
                    .show(navigationBars());
        }
@@ -1019,6 +1036,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        mLastRemoteInputActive = remoteInputActive;
        mLastDozing = mDozing;
        mLastPulsing = mPulsing;
        mLastScreenOffAnimationPlaying = mScreenOffAnimationPlaying;
        mLastBiometricMode = mBiometricUnlockController.getMode();
        mLastGesturalNav = mGesturalNav;
        mLastIsDocked = mIsDocked;
@@ -1054,14 +1072,15 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    /**
     * @return Whether the navigation bar should be made visible based on the current state.
     */
    protected boolean isNavBarVisible() {
        int biometricMode = mBiometricUnlockController.getMode();
    public boolean isNavBarVisible() {
        boolean isWakeAndUnlockPulsing = mBiometricUnlockController != null
                && mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING;
        boolean keyguardShowing = mShowing && !mOccluded;
        boolean hideWhileDozing = mDozing && biometricMode != MODE_WAKE_AND_UNLOCK_PULSING;
        boolean hideWhileDozing = mDozing && !isWakeAndUnlockPulsing;
        boolean keyguardWithGestureNav = (keyguardShowing && !mDozing || mPulsing && !mIsDocked)
                && mGesturalNav;
        return (!keyguardShowing && !hideWhileDozing || mBouncer.isShowing()
                || mRemoteInputActive || keyguardWithGestureNav
        return (!keyguardShowing && !hideWhileDozing && !mScreenOffAnimationPlaying
                || mBouncer.isShowing() || mRemoteInputActive || keyguardWithGestureNav
                || mGlobalActionsVisible);
    }

@@ -1073,8 +1092,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        boolean hideWhileDozing = mLastDozing && mLastBiometricMode != MODE_WAKE_AND_UNLOCK_PULSING;
        boolean keyguardWithGestureNav = (keyguardShowing && !mLastDozing
                || mLastPulsing && !mLastIsDocked) && mLastGesturalNav;
        return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing
                || mLastRemoteInputActive || keyguardWithGestureNav
        return (!keyguardShowing && !hideWhileDozing && !mLastScreenOffAnimationPlaying
                || mLastBouncerShowing || mLastRemoteInputActive || keyguardWithGestureNav
                || mLastGlobalActionsVisible);
    }

@@ -1224,6 +1243,13 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        setDozing(isDozing);
    }

    @Override
    public void onFoldToAodAnimationChanged() {
        if (mFoldAodAnimationController != null) {
            mScreenOffAnimationPlaying = mFoldAodAnimationController.shouldPlayAnimation();
        }
    }

    /**
     * Whether qs is currently expanded.
     */
+14 −13
Original line number Diff line number Diff line
@@ -48,17 +48,17 @@ constructor(
    private var pendingScrimReadyCallback: Runnable? = null

    private var shouldPlayAnimation = false
    private var isAnimationPlaying = false

    private val statusListeners = arrayListOf<FoldAodAnimationStatus>()

    private val startAnimationRunnable = Runnable {
        statusBar.notificationPanelViewController.startFoldToAodAnimation {
            // End action
            isAnimationPlaying = false
            setAnimationState(playing = false)
        }
    }

    private var isAnimationPlaying = false

    override fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {
        this.statusBar = statusBar

@@ -71,17 +71,13 @@ constructor(
    override fun startAnimation(): Boolean =
        if (alwaysOnEnabled &&
            wakefulnessLifecycle.lastSleepReason == PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD &&
            globalSettings.getString(Settings.Global.ANIMATOR_DURATION_SCALE) != "0") {
            shouldPlayAnimation = true

            isAnimationPlaying = true
            globalSettings.getString(Settings.Global.ANIMATOR_DURATION_SCALE) != "0"
        ) {
            setAnimationState(playing = true)
            statusBar.notificationPanelViewController.prepareFoldToAodAnimation()

            statusListeners.forEach(FoldAodAnimationStatus::onFoldToAodAnimationChanged)

            true
        } else {
            shouldPlayAnimation = false
            setAnimationState(playing = false)
            false
        }

@@ -91,8 +87,13 @@ constructor(
            statusBar.notificationPanelViewController.cancelFoldToAodAnimation();
        }

        shouldPlayAnimation = false
        isAnimationPlaying = false
        setAnimationState(playing = false)
    }

    private fun setAnimationState(playing: Boolean) {
        shouldPlayAnimation = playing
        isAnimationPlaying = playing
        statusListeners.forEach(FoldAodAnimationStatus::onFoldToAodAnimationChanged)
    }

    /**
+2 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.pip.Pip;
@@ -90,6 +91,7 @@ public class NavigationBarControllerTest extends SysuiTestCase {
                        mock(NavBarHelper.class),
                        mock(TaskbarDelegate.class),
                        mNavigationBarFactory,
                        mock(StatusBarKeyguardViewManager.class),
                        mock(DumpManager.class),
                        mock(AutoHideController.class),
                        mock(LightBarController.class),
Loading