[Status Bar Refactor] Move logic about hiding status bar icons for

bouncer into a separate class and reference that in
CollapsedStatusBarFragment.

This may be a bit of a heavy-handed way of removing the StatusBar
reference from CollapsedStatusBarFragment, but I think the dedicated
class makes the logic super obvious and easy to dump for bug reports.

Bug: 204792508
Test: manual
Test: atest SystemUITests
Test: Will add new unit tests if general structure is approved
Change-Id: Ia8c4ddd84c20ca4a4e31b8079e56cbf3867efc79
This commit is contained in:
Caitlin Cassidy
2021-11-01 19:19:52 +00:00
parent 8a9fb9c249
commit c3f9521f01
8 changed files with 177 additions and 72 deletions

View File

@@ -104,6 +104,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private final NotificationIconAreaController mNotificationIconAreaController;
private final PanelExpansionStateManager mPanelExpansionStateManager;
private final StatusBarIconController mStatusBarIconController;
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
private List<String> mBlockedIcons = new ArrayList<>();
@@ -132,6 +133,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
FeatureFlags featureFlags,
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
StatusBarIconController statusBarIconController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
KeyguardStateController keyguardStateController,
NetworkController networkController,
StatusBarStateController statusBarStateController,
@@ -147,6 +149,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mFeatureFlags = featureFlags;
mStatusBarOptionalLazy = statusBarOptionalLazy;
mStatusBarIconController = statusBarIconController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mKeyguardStateController = keyguardStateController;
mNetworkController = networkController;
mStatusBarStateController = statusBarStateController;
@@ -372,10 +375,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
StatusBar::hideStatusBarIconsWhenExpanded).orElse(false)) {
return true;
}
if (statusBarOptional.map(StatusBar::hideStatusBarIconsForBouncer).orElse(false)) {
return true;
}
return false;
return mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer();
}
private void hideSystemIconArea(boolean animate) {

View File

@@ -341,6 +341,12 @@ public class StatusBar extends SystemUI implements
void setWindowState(int state) {
mStatusBarWindowState = state;
mStatusBarWindowHidden = state == WINDOW_STATE_HIDDEN;
mStatusBarHideIconsForBouncerManager.setStatusBarWindowHidden(mStatusBarWindowHidden);
if (getStatusBarView() != null) {
// Should #updateHideIconsForBouncer always be called, regardless of whether we have a
// status bar view? If so, we can make #updateHideIconsForBouncer private.
mStatusBarHideIconsForBouncerManager.updateHideIconsForBouncer(/* animate= */ false);
}
}
void acquireGestureWakeLock(long time) {
@@ -360,14 +366,6 @@ public class StatusBar extends SystemUI implements
return mStatusBarMode;
}
boolean getWereIconsJustHidden() {
return mWereIconsJustHidden;
}
void setWereIconsJustHidden(boolean justHidden) {
mWereIconsJustHidden = justHidden;
}
void resendMessage(int msg) {
mMessageRouter.cancelMessages(msg);
mMessageRouter.sendMessage(msg);
@@ -510,6 +508,7 @@ public class StatusBar extends SystemUI implements
private final SystemStatusAnimationScheduler mAnimationScheduler;
private final StatusBarLocationPublisher mStatusBarLocationPublisher;
private final StatusBarIconController mStatusBarIconController;
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
// expanded notifications
// the sliding/resizing panel within the notification window
@@ -642,10 +641,7 @@ public class StatusBar extends SystemUI implements
private int mLastLoggedStateFingerprint;
private boolean mTopHidesStatusBar;
private boolean mStatusBarWindowHidden;
private boolean mHideIconsForBouncer;
private boolean mIsOccluded;
private boolean mWereIconsJustHidden;
private boolean mBouncerWasShowingWhenHidden;
private boolean mIsLaunchingActivityOverLockscreen;
private final UserSwitcherController mUserSwitcherController;
@@ -778,6 +774,7 @@ public class StatusBar extends SystemUI implements
SystemStatusAnimationScheduler animationScheduler,
StatusBarLocationPublisher locationPublisher,
StatusBarIconController statusBarIconController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -874,6 +871,7 @@ public class StatusBar extends SystemUI implements
mAnimationScheduler = animationScheduler;
mStatusBarLocationPublisher = locationPublisher;
mStatusBarIconController = statusBarIconController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mFeatureFlags = featureFlags;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mMainHandler = mainHandler;
@@ -939,6 +937,7 @@ public class StatusBar extends SystemUI implements
mDisplay = mContext.getDisplay();
mDisplayId = mDisplay.getDisplayId();
updateDisplaySize();
mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);
// start old BaseStatusBar.start().
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -1200,6 +1199,7 @@ public class StatusBar extends SystemUI implements
mFeatureFlags,
() -> Optional.of(this),
mStatusBarIconController,
mStatusBarHideIconsForBouncerManager,
mKeyguardStateController,
mNetworkController,
mStatusBarStateController,
@@ -1874,7 +1874,7 @@ public class StatusBar extends SystemUI implements
mNotificationLogger.onPanelExpandedChanged(isExpanded);
}
mPanelExpanded = isExpanded;
updateHideIconsForBouncer(false /* animate */);
mStatusBarHideIconsForBouncerManager.setPanelExpandedAndTriggerUpdate(isExpanded);
mNotificationShadeWindowController.setPanelExpanded(isExpanded);
mStatusBarStateController.setPanelExpanded(isExpanded);
if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
@@ -1918,46 +1918,8 @@ public class StatusBar extends SystemUI implements
public void setOccluded(boolean occluded) {
mIsOccluded = occluded;
mStatusBarHideIconsForBouncerManager.setIsOccludedAndTriggerUpdate(occluded);
mScrimController.setKeyguardOccluded(occluded);
updateHideIconsForBouncer(false /* animate */);
}
public boolean hideStatusBarIconsForBouncer() {
return mHideIconsForBouncer || mWereIconsJustHidden;
}
/**
* Decides if the status bar (clock + notifications + signal cluster) should be visible
* or not when showing the bouncer.
*
* We want to hide it when:
* • User swipes up on the keyguard
* • Locked activity that doesn't show a status bar requests the bouncer
*
* @param animate should the change of the icons be animated.
*/
void updateHideIconsForBouncer(boolean animate) {
boolean hideBecauseApp = mTopHidesStatusBar && mIsOccluded
&& (mStatusBarWindowHidden || mBouncerShowing);
boolean hideBecauseKeyguard = !mPanelExpanded && !mIsOccluded && mBouncerShowing;
boolean shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard;
if (mHideIconsForBouncer != shouldHideIconsForBouncer) {
mHideIconsForBouncer = shouldHideIconsForBouncer;
if (!shouldHideIconsForBouncer && mBouncerWasShowingWhenHidden) {
// We're delaying the showing, since most of the time the fullscreen app will
// hide the icons again and we don't want them to fade in and out immediately again.
mWereIconsJustHidden = true;
mMainExecutor.executeDelayed(() -> {
mWereIconsJustHidden = false;
mCommandQueue.recomputeDisableFlags(mDisplayId, true);
}, 500);
} else {
mCommandQueue.recomputeDisableFlags(mDisplayId, animate);
}
}
if (shouldHideIconsForBouncer) {
mBouncerWasShowingWhenHidden = mBouncerShowing;
}
}
public boolean headsUpShouldBeVisible() {
@@ -3514,7 +3476,7 @@ public class StatusBar extends SystemUI implements
mKeyguardBypassController.setBouncerShowing(bouncerShowing);
mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
setBouncerShowingForStatusBarComponents(bouncerShowing);
updateHideIconsForBouncer(true /* animate */);
mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
updateScrimController();
if (!mBouncerShowing) {

View File

@@ -95,6 +95,7 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
private final SysuiStatusBarStateController mStatusBarStateController;
private final NotificationShadeWindowView mNotificationShadeWindowView;
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
private final PowerManager mPowerManager;
private final VibratorHelper mVibratorHelper;
private final Optional<Vibrator> mVibratorOptional;
@@ -132,6 +133,7 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
SysuiStatusBarStateController statusBarStateController,
NotificationShadeWindowView notificationShadeWindowView,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
PowerManager powerManager,
VibratorHelper vibratorHelper,
Optional<Vibrator> vibratorOptional,
@@ -158,6 +160,7 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
mStatusBarStateController = statusBarStateController;
mNotificationShadeWindowView = notificationShadeWindowView;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mPowerManager = powerManager;
mVibratorHelper = vibratorHelper;
mVibratorOptional = vibratorOptional;
@@ -509,14 +512,8 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
@Override
public void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) {
mStatusBar.setTopHidesStatusBar(topAppHidesStatusBar);
if (!topAppHidesStatusBar && mStatusBar.getWereIconsJustHidden()) {
// Immediately update the icon hidden state, since that should only apply if we're
// staying fullscreen.
mStatusBar.setWereIconsJustHidden(false);
mCommandQueue.recomputeDisableFlags(mDisplayId, true);
}
mStatusBar.updateHideIconsForBouncer(true /* animate */);
mStatusBarHideIconsForBouncerManager
.setTopAppHidesStatusBarAndTriggerUpdate(topAppHidesStatusBar);
}
@Override
@@ -534,13 +531,11 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
if (StatusBar.DEBUG_WINDOW_STATE) {
Log.d(StatusBar.TAG, "Status bar " + windowStateToString(state));
}
if (mStatusBar.getStatusBarView() != null) {
if (!showing && mStatusBarStateController.getState() == StatusBarState.SHADE) {
if (mStatusBar.getStatusBarView() != null
&& !showing
&& mStatusBarStateController.getState() == StatusBarState.SHADE) {
mNotificationPanelViewController.collapsePanel(
false /* animate */, false /* delayed */, 1.0f /* speedUpFactor */);
}
mStatusBar.updateHideIconsForBouncer(false /* animate */);
}
}

View File

@@ -0,0 +1,133 @@
package com.android.systemui.statusbar.phone
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
/**
* A class that manages if the status bar (clock + notifications + signal cluster) should be visible
* or not when showing the bouncer.
*
* We want to hide it when:
* • User swipes up on the keyguard
* • Locked activity that doesn't show a status bar requests the bouncer.
*
* [getShouldHideStatusBarIconsForBouncer] is the main exported method for this class. The other
* methods set state variables that are used in the calculation or manually trigger an update.
*/
@SysUISingleton
class StatusBarHideIconsForBouncerManager @Inject constructor(
private val commandQueue: CommandQueue,
@Main private val mainExecutor: DelayableExecutor,
dumpManager: DumpManager
) : Dumpable {
// State variables set by external classes.
private var panelExpanded: Boolean = false
private var isOccluded: Boolean = false
private var bouncerShowing: Boolean = false
private var topAppHidesStatusBar: Boolean = false
private var statusBarWindowHidden: Boolean = false
private var displayId: Int = 0
// State variables calculated internally.
private var hideIconsForBouncer: Boolean = false
private var bouncerWasShowingWhenHidden: Boolean = false
private var wereIconsJustHidden: Boolean = false
init {
dumpManager.registerDumpable(this)
}
/** Returns true if the status bar icons should be hidden in the bouncer. */
fun getShouldHideStatusBarIconsForBouncer(): Boolean {
return hideIconsForBouncer || wereIconsJustHidden
}
fun setStatusBarWindowHidden(statusBarWindowHidden: Boolean) {
this.statusBarWindowHidden = statusBarWindowHidden
}
fun setDisplayId(displayId: Int) {
this.displayId = displayId
}
fun setPanelExpandedAndTriggerUpdate(panelExpanded: Boolean) {
this.panelExpanded = panelExpanded
updateHideIconsForBouncer(animate = false)
}
fun setIsOccludedAndTriggerUpdate(isOccluded: Boolean) {
this.isOccluded = isOccluded
updateHideIconsForBouncer(animate = false)
}
fun setBouncerShowingAndTriggerUpdate(bouncerShowing: Boolean) {
this.bouncerShowing = bouncerShowing
updateHideIconsForBouncer(animate = true)
}
fun setTopAppHidesStatusBarAndTriggerUpdate(topAppHidesStatusBar: Boolean) {
this.topAppHidesStatusBar = topAppHidesStatusBar
if (!topAppHidesStatusBar && wereIconsJustHidden) {
// Immediately update the icon hidden state, since that should only apply if we're
// staying fullscreen.
wereIconsJustHidden = false
commandQueue.recomputeDisableFlags(displayId, /* animate= */ true)
}
updateHideIconsForBouncer(animate = true)
}
/**
* Updates whether the status bar icons should be hidden in the bouncer. May trigger
* [commandQueue.recomputeDisableFlags] if the icon visibility status changes.
*/
fun updateHideIconsForBouncer(animate: Boolean) {
val hideBecauseApp =
topAppHidesStatusBar &&
isOccluded &&
(statusBarWindowHidden || bouncerShowing)
val hideBecauseKeyguard = !panelExpanded && !isOccluded && bouncerShowing
val shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard
if (hideIconsForBouncer != shouldHideIconsForBouncer) {
hideIconsForBouncer = shouldHideIconsForBouncer
if (!shouldHideIconsForBouncer && bouncerWasShowingWhenHidden) {
// We're delaying the showing, since most of the time the fullscreen app will
// hide the icons again and we don't want them to fade in and out immediately again.
wereIconsJustHidden = true
mainExecutor.executeDelayed(
{
wereIconsJustHidden = false
commandQueue.recomputeDisableFlags(displayId, true)
},
500
)
} else {
commandQueue.recomputeDisableFlags(displayId, animate)
}
}
if (shouldHideIconsForBouncer) {
bouncerWasShowingWhenHidden = bouncerShowing
}
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.println("---- State variables set externally ----")
pw.println("panelExpanded=$panelExpanded")
pw.println("isOccluded=$isOccluded")
pw.println("bouncerShowing=$bouncerShowing")
pw.println("topAppHideStatusBar=$topAppHidesStatusBar")
pw.println("statusBarWindowHidden=$statusBarWindowHidden")
pw.println("displayId=$displayId")
pw.println("---- State variables calculated internally ----")
pw.println("hideIconsForBouncer=$hideIconsForBouncer")
pw.println("bouncerWasShowingWhenHidden=$bouncerWasShowingWhenHidden")
pw.println("wereIconsJustHidden=$wereIconsJustHidden")
}
}

View File

@@ -92,6 +92,7 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
@@ -224,6 +225,7 @@ public interface StatusBarPhoneModule {
SystemStatusAnimationScheduler animationScheduler,
StatusBarLocationPublisher locationPublisher,
StatusBarIconController statusBarIconController,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
LockscreenShadeTransitionController transitionController,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -322,6 +324,7 @@ public interface StatusBarPhoneModule {
animationScheduler,
locationPublisher,
statusBarIconController,
statusBarHideIconsForBouncerManager,
transitionController,
featureFlags,
keyguardUnlockAnimationController,

View File

@@ -38,6 +38,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker;
@@ -50,6 +51,8 @@ import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Ignore;
@@ -264,6 +267,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mock(FeatureFlags.class),
() -> Optional.of(mStatusBar),
mStatusBarIconController,
new StatusBarHideIconsForBouncerManager(
mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
mKeyguardStateController,
mNetworkController,
mStatusBarStateController,

View File

@@ -36,6 +36,7 @@ import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -45,6 +46,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import org.junit.Before;
@@ -109,6 +112,8 @@ public class StatusBarCommandQueueCallbacksTest extends SysuiTestCase {
mStatusBarStateController,
mNotificationShadeWindowView,
mNotificationStackScrollLayoutController,
new StatusBarHideIconsForBouncerManager(
mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
mPowerManager,
mVibratorHelper,
Optional.of(mVibrator),

View File

@@ -279,6 +279,7 @@ public class StatusBarTest extends SysuiTestCase {
private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
private FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock);
private InitController mInitController = new InitController();
private final DumpManager mDumpManager = new DumpManager();
@Before
public void setup() throws Exception {
@@ -332,7 +333,7 @@ public class StatusBarTest extends SysuiTestCase {
}).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
WakefulnessLifecycle wakefulnessLifecycle =
new WakefulnessLifecycle(mContext, mIWallpaperManager, mock(DumpManager.class));
new WakefulnessLifecycle(mContext, mIWallpaperManager, mDumpManager);
wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
wakefulnessLifecycle.dispatchFinishedWakingUp();
@@ -390,7 +391,7 @@ public class StatusBarTest extends SysuiTestCase {
mNetworkController,
mBatteryController,
mColorExtractor,
new ScreenLifecycle(mock(DumpManager.class)),
new ScreenLifecycle(mDumpManager),
wakefulnessLifecycle,
mStatusBarStateController,
Optional.of(mBubblesManager),
@@ -440,6 +441,7 @@ public class StatusBarTest extends SysuiTestCase {
mAnimationScheduler,
mLocationPublisher,
mIconController,
new StatusBarHideIconsForBouncerManager(mCommandQueue, mMainExecutor, mDumpManager),
mLockscreenTransitionController,
mFeatureFlags,
mKeyguardUnlockAnimationController,
@@ -450,7 +452,7 @@ public class StatusBarTest extends SysuiTestCase {
mUnlockedScreenOffAnimationController,
Optional.of(mStartingSurface),
mTunerService,
mock(DumpManager.class),
mDumpManager,
mActivityLaunchAnimator);
when(mKeyguardViewMediator.registerStatusBar(
any(StatusBar.class),