[Status Bar Refactor] Move status bar window state tracking into a
centralized class and add some listeners for it. Bug: 212424936 Test: manual (verified callbacks trigger) Test: new StatusBarWindowStateControllerTest Change-Id: Ib75206c05551ddf6512dd608295b9043dabd7c88
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
@@ -197,6 +198,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
|
||||
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.unfold.SysUIUnfoldComponent;
|
||||
import com.android.systemui.util.Utils;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
@@ -732,7 +734,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
CommunalStateController communalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
StatusBarStateController statusBarStateController, DozeLog dozeLog,
|
||||
StatusBarStateController statusBarStateController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
DozeLog dozeLog,
|
||||
DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper,
|
||||
LatencyTracker latencyTracker, PowerManager powerManager,
|
||||
AccessibilityManager accessibilityManager, @DisplayId int displayId,
|
||||
@@ -862,6 +866,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
mQs.animateHeaderSlidingOut();
|
||||
}
|
||||
});
|
||||
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
|
||||
mThemeResId = mView.getContext().getThemeResId();
|
||||
mKeyguardBypassController = bypassController;
|
||||
mUpdateMonitor = keyguardUpdateMonitor;
|
||||
@@ -5006,4 +5011,14 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
public PhoneStatusBarView.TouchEventHandler getStatusBarTouchEventHandler() {
|
||||
return mStatusBarViewTouchEventHandler;
|
||||
}
|
||||
|
||||
private void onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState int state) {
|
||||
if (state != WINDOW_STATE_SHOWING
|
||||
&& mStatusBarStateController.getState() == StatusBarState.SHADE) {
|
||||
collapsePanel(
|
||||
false /* animate */,
|
||||
false /* delayed */,
|
||||
1.0f /* speedUpFactor */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +232,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.util.DumpUtilsKt;
|
||||
import com.android.systemui.util.WallpaperController;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
@@ -337,9 +338,11 @@ public class StatusBar extends CoreStartable implements
|
||||
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||
private StatusBarCommandQueueCallbacks mCommandQueueCallbacks;
|
||||
|
||||
void setWindowState(int state) {
|
||||
mStatusBarWindowState = state;
|
||||
void onStatusBarWindowStateChanged(@WindowVisibleState int state) {
|
||||
updateBubblesVisibility();
|
||||
mStatusBarWindowState = state;
|
||||
mStatusBarWindowHidden = state == WINDOW_STATE_HIDDEN;
|
||||
// TODO(b/212424936): Have this icon manager just implement its own listener.
|
||||
mStatusBarHideIconsForBouncerManager.setStatusBarWindowHidden(mStatusBarWindowHidden);
|
||||
if (mStatusBarView != null) {
|
||||
// Should #updateHideIconsForBouncer always be called, regardless of whether we have a
|
||||
@@ -464,7 +467,7 @@ public class StatusBar extends CoreStartable implements
|
||||
private PhoneStatusBarViewController mPhoneStatusBarViewController;
|
||||
private PhoneStatusBarTransitions mStatusBarTransitions;
|
||||
private AuthRippleController mAuthRippleController;
|
||||
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
|
||||
@WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
|
||||
protected NotificationShadeWindowController mNotificationShadeWindowController;
|
||||
private final StatusBarWindowController mStatusBarWindowController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@@ -692,6 +695,7 @@ public class StatusBar extends CoreStartable implements
|
||||
LightBarController lightBarController,
|
||||
AutoHideController autoHideController,
|
||||
StatusBarWindowController statusBarWindowController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
StatusBarSignalPolicy statusBarSignalPolicy,
|
||||
PulseExpansionHandler pulseExpansionHandler,
|
||||
@@ -872,6 +876,7 @@ public class StatusBar extends CoreStartable implements
|
||||
mStartingSurfaceOptional = startingSurfaceOptional;
|
||||
mNotifPipelineFlags = notifPipelineFlags;
|
||||
lockscreenShadeTransitionController.setStatusbar(this);
|
||||
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
|
||||
|
||||
mScreenOffAnimationController = screenOffAnimationController;
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
|
||||
import static android.app.StatusBarManager.windowStateToString;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
import static android.view.InsetsState.containsType;
|
||||
|
||||
@@ -58,7 +56,6 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.qs.QSPanelController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.DisableFlagsLogger;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||
@@ -514,30 +511,6 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
|
||||
.setTopAppHidesStatusBarAndTriggerUpdate(topAppHidesStatusBar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindowState(
|
||||
int displayId, @StatusBarManager.WindowType int window,
|
||||
@StatusBarManager.WindowVisibleState int state) {
|
||||
if (displayId != mDisplayId) {
|
||||
return;
|
||||
}
|
||||
boolean showing = state == WINDOW_STATE_SHOWING;
|
||||
if (mNotificationShadeWindowView != null
|
||||
&& window == StatusBarManager.WINDOW_STATUS_BAR
|
||||
&& !mStatusBar.isSameStatusBarState(state)) {
|
||||
mStatusBar.setWindowState(state);
|
||||
if (StatusBar.DEBUG_WINDOW_STATE) {
|
||||
Log.d(StatusBar.TAG, "Status bar " + windowStateToString(state));
|
||||
}
|
||||
if (!showing && mStatusBarStateController.getState() == StatusBarState.SHADE) {
|
||||
mNotificationPanelViewController.collapsePanel(
|
||||
false /* animate */, false /* delayed */, 1.0f /* speedUpFactor */);
|
||||
}
|
||||
}
|
||||
|
||||
mStatusBar.updateBubblesVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showAssistDisclosure() {
|
||||
mAssistManager.showDisclosure();
|
||||
|
||||
@@ -105,6 +105,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.util.WallpaperController;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.concurrency.MessageRouter;
|
||||
@@ -140,6 +141,7 @@ public interface StatusBarPhoneModule {
|
||||
LightBarController lightBarController,
|
||||
AutoHideController autoHideController,
|
||||
StatusBarWindowController statusBarWindowController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
StatusBarSignalPolicy statusBarSignalPolicy,
|
||||
PulseExpansionHandler pulseExpansionHandler,
|
||||
@@ -235,6 +237,7 @@ public interface StatusBarPhoneModule {
|
||||
lightBarController,
|
||||
autoHideController,
|
||||
statusBarWindowController,
|
||||
statusBarWindowStateController,
|
||||
keyguardUpdateMonitor,
|
||||
statusBarSignalPolicy,
|
||||
pulseExpansionHandler,
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.window
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.app.StatusBarManager.WindowVisibleState
|
||||
import android.app.StatusBarManager.WINDOW_STATE_SHOWING
|
||||
import android.app.StatusBarManager.WINDOW_STATUS_BAR
|
||||
import android.app.StatusBarManager.windowStateToString
|
||||
import android.util.Log
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.DisplayId
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.android.systemui.statusbar.phone.StatusBar
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A centralized class maintaining the state of the status bar window.
|
||||
*
|
||||
* Classes that want to get updates about the status bar window state should subscribe to this class
|
||||
* via [addListener] and should NOT add their own callback on [CommandQueue].
|
||||
*/
|
||||
@SysUISingleton
|
||||
class StatusBarWindowStateController @Inject constructor(
|
||||
@DisplayId private val thisDisplayId: Int,
|
||||
commandQueue: CommandQueue
|
||||
) {
|
||||
private val commandQueueCallback = object : CommandQueue.Callbacks {
|
||||
override fun setWindowState(
|
||||
displayId: Int,
|
||||
@StatusBarManager.WindowType window: Int,
|
||||
@WindowVisibleState state: Int
|
||||
) {
|
||||
this@StatusBarWindowStateController.setWindowState(displayId, window, state)
|
||||
}
|
||||
}
|
||||
private val listeners: MutableSet<StatusBarWindowStateListener> = HashSet()
|
||||
|
||||
@WindowVisibleState private var windowState: Int = WINDOW_STATE_SHOWING
|
||||
|
||||
init {
|
||||
commandQueue.addCallback(commandQueueCallback)
|
||||
}
|
||||
|
||||
/** Adds a listener. */
|
||||
fun addListener(listener: StatusBarWindowStateListener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
private fun setWindowState(
|
||||
displayId: Int,
|
||||
@StatusBarManager.WindowType window: Int,
|
||||
@WindowVisibleState state: Int
|
||||
) {
|
||||
if (displayId != thisDisplayId) {
|
||||
return
|
||||
}
|
||||
if (window != WINDOW_STATUS_BAR) {
|
||||
return
|
||||
}
|
||||
if (windowState == state) {
|
||||
return
|
||||
}
|
||||
|
||||
windowState = state
|
||||
if (StatusBar.DEBUG_WINDOW_STATE) {
|
||||
Log.d(StatusBar.TAG, "Status bar " + windowStateToString(state))
|
||||
}
|
||||
listeners.forEach { it.onStatusBarWindowStateChanged(state) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.window
|
||||
|
||||
import android.app.StatusBarManager
|
||||
|
||||
/** Listener interface for changes in the status bar window state. */
|
||||
interface StatusBarWindowStateListener {
|
||||
fun onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState state: Int)
|
||||
}
|
||||
@@ -141,6 +141,7 @@ import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.unfold.SysUIUnfoldComponent;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
@@ -358,6 +359,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
private NotificationsQSContainerController mNotificationsQSContainerController;
|
||||
@Mock
|
||||
private QsFrameTranslateController mQsFrameTranslateController;
|
||||
@Mock
|
||||
private StatusBarWindowStateController mStatusBarWindowStateController;
|
||||
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
|
||||
private SysuiStatusBarStateController mStatusBarStateController;
|
||||
private NotificationPanelViewController mNotificationPanelViewController;
|
||||
@@ -491,7 +494,9 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
|
||||
mFalsingManager, new FalsingCollectorFake(),
|
||||
mNotificationLockscreenUserManager, mNotificationEntryManager,
|
||||
mCommunalStateController, mKeyguardStateController, mStatusBarStateController,
|
||||
mCommunalStateController, mKeyguardStateController,
|
||||
mStatusBarStateController,
|
||||
mStatusBarWindowStateController,
|
||||
mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
|
||||
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
|
||||
mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController,
|
||||
|
||||
@@ -147,6 +147,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowController;
|
||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.util.WallpaperController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.concurrency.MessageRouterImpl;
|
||||
@@ -228,6 +229,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
@Mock private DynamicPrivacyController mDynamicPrivacyController;
|
||||
@Mock private AutoHideController mAutoHideController;
|
||||
@Mock private StatusBarWindowController mStatusBarWindowController;
|
||||
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
|
||||
@Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
|
||||
@Mock private UserSwitcherController mUserSwitcherController;
|
||||
@Mock private NetworkController mNetworkController;
|
||||
@@ -374,6 +376,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
mLightBarController,
|
||||
mAutoHideController,
|
||||
mStatusBarWindowController,
|
||||
mStatusBarWindowStateController,
|
||||
mKeyguardUpdateMonitor,
|
||||
mStatusBarSignalPolicy,
|
||||
mPulseExpansionHandler,
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.window
|
||||
|
||||
import android.app.StatusBarManager.WindowVisibleState
|
||||
import android.app.StatusBarManager.WINDOW_NAVIGATION_BAR
|
||||
import android.app.StatusBarManager.WINDOW_STATE_HIDDEN
|
||||
import android.app.StatusBarManager.WINDOW_STATE_SHOWING
|
||||
import android.app.StatusBarManager.WINDOW_STATUS_BAR
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
class StatusBarWindowStateControllerTest : SysuiTestCase() {
|
||||
private lateinit var controller: StatusBarWindowStateController
|
||||
private lateinit var callback: CommandQueue.Callbacks
|
||||
|
||||
@Mock
|
||||
private lateinit var commandQueue: CommandQueue
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
controller = StatusBarWindowStateController(DISPLAY_ID, commandQueue)
|
||||
|
||||
val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
|
||||
verify(commandQueue).addCallback(callbackCaptor.capture())
|
||||
callback = callbackCaptor.value!!
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setWindowState_notSameDisplayId_listenersNotNotified() {
|
||||
val listener = TestListener()
|
||||
controller.addListener(listener)
|
||||
|
||||
callback.setWindowState(DISPLAY_ID + 1, WINDOW_STATUS_BAR, WINDOW_STATE_HIDDEN)
|
||||
|
||||
assertThat(listener.state).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setWindowState_notStatusBarWindow_listenersNotNotified() {
|
||||
val listener = TestListener()
|
||||
controller.addListener(listener)
|
||||
|
||||
callback.setWindowState(DISPLAY_ID, WINDOW_NAVIGATION_BAR, WINDOW_STATE_HIDDEN)
|
||||
|
||||
assertThat(listener.state).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setWindowState_sameState_listenersNotNotified() {
|
||||
val listener = TestListener()
|
||||
controller.addListener(listener)
|
||||
|
||||
callback.setWindowState(DISPLAY_ID, WINDOW_STATUS_BAR, WINDOW_STATE_SHOWING)
|
||||
|
||||
assertThat(listener.state).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setWindowState_newState_listenersNotified() {
|
||||
val listener = TestListener()
|
||||
controller.addListener(listener)
|
||||
val newState = WINDOW_STATE_HIDDEN
|
||||
|
||||
callback.setWindowState(DISPLAY_ID, WINDOW_STATUS_BAR, newState)
|
||||
|
||||
assertThat(listener.state).isEqualTo(newState)
|
||||
}
|
||||
|
||||
private class TestListener : StatusBarWindowStateListener {
|
||||
@WindowVisibleState var state: Int? = null
|
||||
override fun onStatusBarWindowStateChanged(@WindowVisibleState state: Int) {
|
||||
this.state = state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val DISPLAY_ID = 10
|
||||
Reference in New Issue
Block a user