Merge changes from topic "ccassidy-sbwsc"
* changes:
[Status Bar Refactor] Have SBHideIconsForBouncerManager listen to window state directly instead of getting it from StatusBar.java
[Status Bar Refactor] Have NotificationShadeWindowViewController query the window state directly instead of going through StatusBar.java.
[Status Bar Refactor] Move status bar window state tracking into a centralized class and add some listeners for it.
[Status Bar Refactor] Pass status bar view's controller to NotificationShadeWindowViewController instead of the view itself.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 9ca904b..03b1627 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -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.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 @@
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 @@
mQs.animateHeaderSlidingOut();
}
});
+ statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
mThemeResId = mView.getContext().getThemeResId();
mKeyguardBypassController = bypassController;
mUpdateMonitor = keyguardUpdateMonitor;
@@ -5009,4 +5014,14 @@
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 */);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index a6980a4..4e2eb6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -16,10 +16,7 @@
package com.android.systemui.statusbar.phone;
-import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
-
import android.app.StatusBarManager;
-import android.graphics.RectF;
import android.hardware.display.AmbientDisplayConfiguration;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
@@ -47,6 +44,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
+import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
@@ -68,6 +66,7 @@
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private final LockIconViewController mLockIconViewController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final StatusBarWindowStateController mStatusBarWindowStateController;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -75,7 +74,7 @@
private boolean mTouchCancelled;
private boolean mExpandAnimationRunning;
private NotificationStackScrollLayout mStackScrollLayout;
- private PhoneStatusBarView mStatusBarView;
+ private PhoneStatusBarViewController mStatusBarViewController;
private StatusBar mService;
private NotificationShadeWindowController mNotificationShadeWindowController;
private DragDownHelper mDragDownHelper;
@@ -86,8 +85,6 @@
private final NotificationPanelViewController mNotificationPanelViewController;
private final PanelExpansionStateManager mPanelExpansionStateManager;
- // Used for determining view / touch intersection
- private final RectF mTempRect = new RectF();
private boolean mIsTrackingBarGesture = false;
@Inject
@@ -103,6 +100,7 @@
PanelExpansionStateManager panelExpansionStateManager,
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ StatusBarWindowStateController statusBarWindowStateController,
LockIconViewController lockIconViewController) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
@@ -115,6 +113,7 @@
mDepthController = depthController;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ mStatusBarWindowStateController = statusBarWindowStateController;
mLockIconViewController = lockIconViewController;
// This view is not part of the newly inflated expanded status bar.
@@ -175,7 +174,7 @@
mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
@Override
public Boolean handleDispatchTouchEvent(MotionEvent ev) {
- if (mStatusBarView == null) {
+ if (mStatusBarViewController == null) { // Fix for b/192490822
Log.w(TAG, "Ignoring touch while statusBarView not yet set.");
return false;
}
@@ -243,27 +242,27 @@
expandingBelowNotch = true;
}
if (expandingBelowNotch) {
- return mStatusBarView.dispatchTouchEvent(ev);
+ return mStatusBarViewController.sendTouchToView(ev);
}
if (!mIsTrackingBarGesture && isDown
&& mNotificationPanelViewController.isFullyCollapsed()) {
float x = ev.getRawX();
float y = ev.getRawY();
- if (isIntersecting(mStatusBarView, x, y)) {
- if (mService.isSameStatusBarState(WINDOW_STATE_SHOWING)) {
+ if (mStatusBarViewController.touchIsWithinView(x, y)) {
+ if (mStatusBarWindowStateController.windowIsShowing()) {
mIsTrackingBarGesture = true;
- return mStatusBarView.dispatchTouchEvent(ev);
+ return mStatusBarViewController.sendTouchToView(ev);
} else { // it's hidden or hiding, don't send to notification shade.
return true;
}
}
} else if (mIsTrackingBarGesture) {
- final boolean sendToNotification = mStatusBarView.dispatchTouchEvent(ev);
+ final boolean sendToStatusBar = mStatusBarViewController.sendTouchToView(ev);
if (isUp || isCancel) {
mIsTrackingBarGesture = false;
}
- return sendToNotification;
+ return sendToStatusBar;
}
return null;
@@ -442,8 +441,8 @@
}
}
- public void setStatusBarView(PhoneStatusBarView statusBarView) {
- mStatusBarView = statusBarView;
+ public void setStatusBarViewController(PhoneStatusBarViewController statusBarViewController) {
+ mStatusBarViewController = statusBarViewController;
}
public void setService(StatusBar statusBar, NotificationShadeWindowController controller) {
@@ -455,11 +454,4 @@
void setDragDownHelper(DragDownHelper dragDownHelper) {
mDragDownHelper = dragDownHelper;
}
-
- private boolean isIntersecting(View view, float x, float y) {
- int[] mTempLocation = view.getLocationOnScreen();
- mTempRect.set(mTempLocation[0], mTempLocation[1], mTempLocation[0] + view.getWidth(),
- mTempLocation[1] + view.getHeight());
- return mTempRect.contains(x, y);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index b9386bd..1cb19ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -17,6 +17,7 @@
import android.content.res.Configuration
import android.graphics.Point
+import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
@@ -92,6 +93,30 @@
mView.importantForAccessibility = mode
}
+ /**
+ * Sends a touch event to the status bar view.
+ *
+ * This is required in certain cases because the status bar view is in a separate window from
+ * the rest of SystemUI, and other windows may decide that their touch should instead be treated
+ * as a status bar window touch.
+ */
+ fun sendTouchToView(ev: MotionEvent): Boolean {
+ return mView.dispatchTouchEvent(ev)
+ }
+
+ /**
+ * Returns true if the given (x, y) point (in screen coordinates) is within the status bar
+ * view's range and false otherwise.
+ */
+ fun touchIsWithinView(x: Float, y: Float): Boolean {
+ val left = mView.locationOnScreen[0]
+ val top = mView.locationOnScreen[1]
+ return left <= x &&
+ x <= left + mView.width &&
+ top <= y &&
+ y <= top + mView.height
+ }
+
class StatusBarViewsCenterProvider : UnfoldMoveFromCenterAnimator.ViewCenterProvider {
override fun getViewCenter(view: View, outPoint: Point) =
when (view.id) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 6f8a334..3671bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -233,6 +233,7 @@
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;
@@ -338,15 +339,9 @@
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private StatusBarCommandQueueCallbacks mCommandQueueCallbacks;
- void setWindowState(int state) {
- mStatusBarWindowState = state;
- mStatusBarWindowHidden = state == WINDOW_STATE_HIDDEN;
- mStatusBarHideIconsForBouncerManager.setStatusBarWindowHidden(mStatusBarWindowHidden);
- if (mStatusBarView != 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 onStatusBarWindowStateChanged(@WindowVisibleState int state) {
+ updateBubblesVisibility();
+ mStatusBarWindowState = state;
}
void acquireGestureWakeLock(long time) {
@@ -465,7 +460,7 @@
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;
@@ -695,6 +690,7 @@
LightBarController lightBarController,
AutoHideController autoHideController,
StatusBarWindowController statusBarWindowController,
+ StatusBarWindowStateController statusBarWindowStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarSignalPolicy statusBarSignalPolicy,
PulseExpansionHandler pulseExpansionHandler,
@@ -877,6 +873,7 @@
mStartingSurfaceOptional = startingSurfaceOptional;
mNotifPipelineFlags = notifPipelineFlags;
lockscreenShadeTransitionController.setStatusbar(this);
+ statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
mScreenOffAnimationController = screenOffAnimationController;
@@ -1138,7 +1135,8 @@
mStatusBarView = statusBarView;
mPhoneStatusBarViewController = statusBarViewController;
mStatusBarTransitions = statusBarTransitions;
- mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
+ mNotificationShadeWindowViewController
+ .setStatusBarViewController(mPhoneStatusBarViewController);
// Ensure we re-propagate panel expansion values to the panel controller and
// any listeners it may have, such as PanelBar. This will also ensure we
// re-display the notification panel if necessary (for example, if
@@ -2111,10 +2109,6 @@
}
}
- boolean isSameStatusBarState(int state) {
- return mStatusBarWindowState == state;
- }
-
public GestureRecorder getGestureRecorder() {
return mGestureRec;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java
index b391de3..51f2e67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java
@@ -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.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;
@@ -515,30 +512,6 @@
}
@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();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
index d2181d0..17516e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
@@ -1,10 +1,12 @@
package com.android.systemui.statusbar.phone
+import android.app.StatusBarManager
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.statusbar.window.StatusBarWindowStateController
import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.FileDescriptor
import java.io.PrintWriter
@@ -25,6 +27,7 @@
class StatusBarHideIconsForBouncerManager @Inject constructor(
private val commandQueue: CommandQueue,
@Main private val mainExecutor: DelayableExecutor,
+ statusBarWindowStateController: StatusBarWindowStateController,
dumpManager: DumpManager
) : Dumpable {
// State variables set by external classes.
@@ -42,6 +45,9 @@
init {
dumpManager.registerDumpable(this)
+ statusBarWindowStateController.addListener {
+ state -> setStatusBarStateAndTriggerUpdate(state)
+ }
}
/** Returns true if the status bar icons should be hidden in the bouncer. */
@@ -49,8 +55,9 @@
return hideIconsForBouncer || wereIconsJustHidden
}
- fun setStatusBarWindowHidden(statusBarWindowHidden: Boolean) {
- this.statusBarWindowHidden = statusBarWindowHidden
+ private fun setStatusBarStateAndTriggerUpdate(@StatusBarManager.WindowVisibleState state: Int) {
+ statusBarWindowHidden = state == StatusBarManager.WINDOW_STATE_HIDDEN
+ updateHideIconsForBouncer(animate = false)
}
fun setDisplayId(displayId: Int) {
@@ -87,7 +94,7 @@
* 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) {
+ private fun updateHideIconsForBouncer(animate: Boolean) {
val hideBecauseApp =
topAppHidesStatusBar &&
isOccluded &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index c6ef4b5..50176fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -106,6 +106,7 @@
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;
@@ -141,6 +142,7 @@
LightBarController lightBarController,
AutoHideController autoHideController,
StatusBarWindowController statusBarWindowController,
+ StatusBarWindowStateController statusBarWindowStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarSignalPolicy statusBarSignalPolicy,
PulseExpansionHandler pulseExpansionHandler,
@@ -237,6 +239,7 @@
lightBarController,
autoHideController,
statusBarWindowController,
+ statusBarWindowStateController,
keyguardUpdateMonitor,
statusBarSignalPolicy,
pulseExpansionHandler,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
new file mode 100644
index 0000000..3a14914
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
@@ -0,0 +1,88 @@
+/*
+ * 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)
+ }
+
+ /** Returns true if the window is currently showing. */
+ fun windowIsShowing() = windowState == WINDOW_STATE_SHOWING
+
+ 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) }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateListener.kt
new file mode 100644
index 0000000..f3bab04
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateListener.kt
@@ -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. */
+fun interface StatusBarWindowStateListener {
+ fun onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState state: Int)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 3b72f00..5ada6d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -141,6 +141,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.window.StatusBarWindowStateController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
@@ -359,6 +360,8 @@
private NotificationsQSContainerController mNotificationsQSContainerController;
@Mock
private QsFrameTranslateController mQsFrameTranslateController;
+ @Mock
+ private StatusBarWindowStateController mStatusBarWindowStateController;
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -495,7 +498,9 @@
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,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
new file mode 100644
index 0000000..12e71af
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
@@ -0,0 +1,241 @@
+/*
+ * 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.phone
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.keyguard.LockIconViewController
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollectorFake
+import com.android.systemui.dock.DockManager
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
+import com.android.systemui.statusbar.NotificationShadeDepthController
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView.InteractionEventHandler
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
+import com.android.systemui.statusbar.window.StatusBarWindowStateController
+import com.android.systemui.tuner.TunerService
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
+ private lateinit var mController: NotificationShadeWindowViewController
+
+ @Mock
+ private lateinit var mView: NotificationShadeWindowView
+ @Mock
+ private lateinit var mTunerService: TunerService
+ @Mock
+ private lateinit var mStatusBarStateController: SysuiStatusBarStateController
+ @Mock
+ private lateinit var mStatusBar: StatusBar
+ @Mock
+ private lateinit var mDockManager: DockManager
+ @Mock
+ private lateinit var mNotificationPanelViewController: NotificationPanelViewController
+ @Mock
+ private lateinit var mNotificationShadeDepthController: NotificationShadeDepthController
+ @Mock
+ private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
+ @Mock
+ private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
+ @Mock
+ private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ @Mock
+ private lateinit var mStatusBarWindowStateController: StatusBarWindowStateController
+ @Mock
+ private lateinit var mLockscreenShadeTransitionController: LockscreenShadeTransitionController
+ @Mock
+ private lateinit var mLockIconViewController: LockIconViewController
+ @Mock
+ private lateinit var mPhoneStatusBarViewController: PhoneStatusBarViewController
+
+ private lateinit var mInteractionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
+ private lateinit var mInteractionEventHandler: InteractionEventHandler
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(mView.bottom).thenReturn(VIEW_BOTTOM)
+
+ mController = NotificationShadeWindowViewController(
+ mLockscreenShadeTransitionController,
+ FalsingCollectorFake(),
+ mTunerService,
+ mStatusBarStateController,
+ mDockManager,
+ mNotificationShadeDepthController,
+ mView,
+ mNotificationPanelViewController,
+ PanelExpansionStateManager(),
+ stackScrollLayoutController,
+ mStatusBarKeyguardViewManager,
+ mStatusBarWindowStateController,
+ mLockIconViewController
+ )
+ mController.setupExpandedStatusBar()
+ mController.setService(mStatusBar, mNotificationShadeWindowController)
+
+ mInteractionEventHandlerCaptor =
+ ArgumentCaptor.forClass(InteractionEventHandler::class.java)
+ verify(mView).setInteractionEventHandler(mInteractionEventHandlerCaptor.capture())
+ mInteractionEventHandler = mInteractionEventHandlerCaptor.value
+ }
+
+ // Note: So far, these tests only cover interactions with the status bar view controller. More
+ // tests need to be added to test the rest of handleDispatchTouchEvent.
+
+ @Test
+ fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
+ mController.setStatusBarViewController(null)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ assertThat(returnVal).isFalse()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
+ whenever(mPhoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(ev)
+
+ verify(mPhoneStatusBarViewController).sendTouchToView(ev)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ val downEvBelow = MotionEvent.obtain(
+ 0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
+ )
+ mInteractionEventHandler.handleDispatchTouchEvent(downEvBelow)
+
+ val nextEvent = MotionEvent.obtain(
+ 0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
+ )
+ whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+
+ verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ whenever(mPhoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ verify(mPhoneStatusBarViewController).sendTouchToView(downEv)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ // Item we're testing
+ whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(false)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ assertThat(returnVal).isNull()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ // Item we're testing
+ whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(false)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ assertThat(returnVal).isNull()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ // Item we're testing
+ whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(false)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
+ mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+
+ // Down event first
+ mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+
+ // Then another event
+ val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+
+ val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+
+ verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+ assertThat(returnVal).isTrue()
+ }
+}
+
+private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index aaf051c..d885da8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -45,6 +45,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
+import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.tuner.TunerService;
import org.junit.Before;
@@ -75,6 +76,7 @@
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private LockIconViewController mLockIconViewController;
@@ -107,6 +109,7 @@
new PanelExpansionStateManager(),
mNotificationStackScrollLayoutController,
mStatusBarKeyguardViewManager,
+ mStatusBarWindowStateController,
mLockIconViewController);
mController.setupExpandedStatusBar();
mController.setService(mStatusBar, mNotificationShadeWindowController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 235de1e..c65a6b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -77,9 +77,10 @@
val parent = FrameLayout(mContext) // add parent to keep layout params
view = LayoutInflater.from(mContext)
.inflate(R.layout.status_bar, parent, false) as PhoneStatusBarView
+ view.setLeftTopRightBottom(VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM)
}
- controller = createController(view)
+ controller = createAndInitController(view)
}
@Test
@@ -99,8 +100,7 @@
val view = createViewMock()
val argumentCaptor = ArgumentCaptor.forClass(OnPreDrawListener::class.java)
unfoldConfig.isEnabled = true
- controller = createController(view)
- controller.init()
+ controller = createAndInitController(view)
verify(view.viewTreeObserver).addOnPreDrawListener(argumentCaptor.capture())
argumentCaptor.value.onPreDraw()
@@ -108,6 +108,64 @@
verify(moveFromCenterAnimation).onViewsReady(any())
}
+ @Test
+ fun touchIsWithinView_inBounds_returnsTrue() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP + 1f)).isTrue()
+ }
+
+ @Test
+ fun touchIsWithinView_onTopLeftCorner_returnsTrue() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_LEFT.toFloat(), VIEW_TOP.toFloat())).isTrue()
+ }
+
+ @Test
+ fun touchIsWithinView_onBottomRightCorner_returnsTrue() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(
+ VIEW_RIGHT.toFloat(), VIEW_BOTTOM.toFloat())
+ ).isTrue()
+ }
+
+ @Test
+ fun touchIsWithinView_xTooSmall_returnsFalse() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_LEFT - 1f, VIEW_TOP + 1f)).isFalse()
+ }
+
+ @Test
+ fun touchIsWithinView_xTooLarge_returnsFalse() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_RIGHT + 1f, VIEW_TOP + 1f)).isFalse()
+ }
+
+ @Test
+ fun touchIsWithinView_yTooSmall_returnsFalse() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP - 1f)).isFalse()
+ }
+
+ @Test
+ fun touchIsWithinView_yTooLarge_returnsFalse() {
+ val view = createViewMockWithScreenLocation()
+ controller = createAndInitController(view)
+
+ assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_BOTTOM + 1f)).isFalse()
+ }
+
private fun createViewMock(): PhoneStatusBarView {
val view = spy(view)
val viewTreeObserver = mock(ViewTreeObserver::class.java)
@@ -116,12 +174,23 @@
return view
}
- private fun createController(view: PhoneStatusBarView): PhoneStatusBarViewController {
+ private fun createViewMockWithScreenLocation(): PhoneStatusBarView {
+ val view = spy(view)
+ val location = IntArray(2)
+ location[0] = VIEW_LEFT
+ location[1] = VIEW_TOP
+ `when`(view.locationOnScreen).thenReturn(location)
+ return view
+ }
+
+ private fun createAndInitController(view: PhoneStatusBarView): PhoneStatusBarViewController {
return PhoneStatusBarViewController.Factory(
Optional.of(sysuiUnfoldComponent),
Optional.of(progressProvider),
configurationController
- ).create(view, touchEventHandler)
+ ).create(view, touchEventHandler).also {
+ it.init()
+ }
}
private class UnfoldConfig : UnfoldTransitionConfig {
@@ -142,3 +211,8 @@
}
}
}
+
+private const val VIEW_LEFT = 30
+private const val VIEW_RIGHT = 100
+private const val VIEW_TOP = 40
+private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java
index 0131293..aabf923 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java
@@ -36,7 +36,6 @@
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;
@@ -46,8 +45,6 @@
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;
@@ -84,6 +81,7 @@
@Mock private VibratorHelper mVibratorHelper;
@Mock private Vibrator mVibrator;
@Mock private LightBarController mLightBarController;
+ @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
StatusBarCommandQueueCallbacks mSbcqCallbacks;
@@ -112,8 +110,7 @@
mStatusBarStateController,
mNotificationShadeWindowView,
mNotificationStackScrollLayoutController,
- new StatusBarHideIconsForBouncerManager(
- mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
+ mStatusBarHideIconsForBouncerManager,
mPowerManager,
mVibratorHelper,
Optional.of(mVibrator),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 554e1d9..69f2bd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -148,6 +148,7 @@
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;
@@ -229,6 +230,7 @@
@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;
@@ -264,6 +266,7 @@
@Mock private BrightnessSliderController.Factory mBrightnessSliderFactory;
@Mock private WallpaperController mWallpaperController;
@Mock private OngoingCallController mOngoingCallController;
+ @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
@Mock private LockscreenShadeTransitionController mLockscreenTransitionController;
@Mock private FeatureFlags mFeatureFlags;
@Mock private NotificationVisibilityProvider mVisibilityProvider;
@@ -376,6 +379,7 @@
mLightBarController,
mAutoHideController,
mStatusBarWindowController,
+ mStatusBarWindowStateController,
mKeyguardUpdateMonitor,
mStatusBarSignalPolicy,
mPulseExpansionHandler,
@@ -451,7 +455,7 @@
mScreenOffAnimationController,
mWallpaperController,
mOngoingCallController,
- new StatusBarHideIconsForBouncerManager(mCommandQueue, mMainExecutor, mDumpManager),
+ mStatusBarHideIconsForBouncerManager,
mLockscreenTransitionController,
mFeatureFlags,
mKeyguardUnlockAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index b97f053..a630840 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -37,7 +37,6 @@
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;
@@ -57,8 +56,6 @@
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.Test;
@@ -96,6 +93,8 @@
private HeadsUpAppearanceController mHeadsUpAppearanceController;
@Mock
private NotificationPanelViewController mNotificationPanelViewController;
+ @Mock
+ private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class);
@@ -325,8 +324,7 @@
new PanelExpansionStateManager(),
mock(FeatureFlags.class),
mStatusBarIconController,
- new StatusBarHideIconsForBouncerManager(
- mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
+ mStatusBarHideIconsForBouncerManager,
mKeyguardStateController,
mNotificationPanelViewController,
mNetworkController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
new file mode 100644
index 0000000..8576d4f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
@@ -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