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.
This commit is contained in:
committed by
Android (Google) Code Review
commit
fc1416c396
@@ -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;
|
||||
@@ -5009,4 +5014,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 */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.SysuiStatusBarStateController;
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
PanelExpansionStateManager panelExpansionStateManager,
|
||||
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
|
||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
LockIconViewController lockIconViewController) {
|
||||
mLockscreenShadeTransitionController = transitionController;
|
||||
mFalsingCollector = falsingCollector;
|
||||
@@ -115,6 +113,7 @@ public class NotificationShadeWindowViewController {
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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 class NotificationShadeWindowViewController {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class NotificationShadeWindowViewController {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone
|
||||
|
||||
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 @@ class PhoneStatusBarViewController private constructor(
|
||||
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) {
|
||||
|
||||
@@ -233,6 +233,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;
|
||||
@@ -338,15 +339,9 @@ public class StatusBar extends CoreStartable implements
|
||||
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 @@ 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;
|
||||
@@ -695,6 +690,7 @@ public class StatusBar extends CoreStartable implements
|
||||
LightBarController lightBarController,
|
||||
AutoHideController autoHideController,
|
||||
StatusBarWindowController statusBarWindowController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
StatusBarSignalPolicy statusBarSignalPolicy,
|
||||
PulseExpansionHandler pulseExpansionHandler,
|
||||
@@ -877,6 +873,7 @@ public class StatusBar extends CoreStartable implements
|
||||
mStartingSurfaceOptional = startingSurfaceOptional;
|
||||
mNotifPipelineFlags = notifPipelineFlags;
|
||||
lockscreenShadeTransitionController.setStatusbar(this);
|
||||
statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
|
||||
|
||||
mScreenOffAnimationController = screenOffAnimationController;
|
||||
|
||||
@@ -1138,7 +1135,8 @@ public class StatusBar extends CoreStartable implements
|
||||
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 @@ public class StatusBar extends CoreStartable implements
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSameStatusBarState(int state) {
|
||||
return mStatusBarWindowState == state;
|
||||
}
|
||||
|
||||
public GestureRecorder getGestureRecorder() {
|
||||
return mGestureRec;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 @@ import javax.inject.Inject
|
||||
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 @@ class StatusBarHideIconsForBouncerManager @Inject constructor(
|
||||
|
||||
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 @@ class StatusBarHideIconsForBouncerManager @Inject constructor(
|
||||
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 @@ class StatusBarHideIconsForBouncerManager @Inject constructor(
|
||||
* 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 &&
|
||||
|
||||
@@ -106,6 +106,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;
|
||||
@@ -141,6 +142,7 @@ public interface StatusBarPhoneModule {
|
||||
LightBarController lightBarController,
|
||||
AutoHideController autoHideController,
|
||||
StatusBarWindowController statusBarWindowController,
|
||||
StatusBarWindowStateController statusBarWindowStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
StatusBarSignalPolicy statusBarSignalPolicy,
|
||||
PulseExpansionHandler pulseExpansionHandler,
|
||||
@@ -237,6 +239,7 @@ public interface StatusBarPhoneModule {
|
||||
lightBarController,
|
||||
autoHideController,
|
||||
statusBarWindowController,
|
||||
statusBarWindowStateController,
|
||||
keyguardUpdateMonitor,
|
||||
statusBarSignalPolicy,
|
||||
pulseExpansionHandler,
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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;
|
||||
@@ -359,6 +360,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;
|
||||
@@ -495,7 +498,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,
|
||||
|
||||
@@ -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
|
||||
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||
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 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
@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 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
new PanelExpansionStateManager(),
|
||||
mNotificationStackScrollLayoutController,
|
||||
mStatusBarKeyguardViewManager,
|
||||
mStatusBarWindowStateController,
|
||||
mLockIconViewController);
|
||||
mController.setupExpandedStatusBar();
|
||||
mController.setService(mStatusBar, mNotificationShadeWindowController);
|
||||
|
||||
@@ -77,9 +77,10 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
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 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
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 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
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 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
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 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val VIEW_LEFT = 30
|
||||
private const val VIEW_RIGHT = 100
|
||||
private const val VIEW_TOP = 40
|
||||
private const val VIEW_BOTTOM = 100
|
||||
|
||||
@@ -36,7 +36,6 @@ 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;
|
||||
@@ -46,8 +45,6 @@ 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;
|
||||
@@ -84,6 +81,7 @@ public class StatusBarCommandQueueCallbacksTest extends SysuiTestCase {
|
||||
@Mock private VibratorHelper mVibratorHelper;
|
||||
@Mock private Vibrator mVibrator;
|
||||
@Mock private LightBarController mLightBarController;
|
||||
@Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
||||
|
||||
StatusBarCommandQueueCallbacks mSbcqCallbacks;
|
||||
|
||||
@@ -112,8 +110,7 @@ public class StatusBarCommandQueueCallbacksTest extends SysuiTestCase {
|
||||
mStatusBarStateController,
|
||||
mNotificationShadeWindowView,
|
||||
mNotificationStackScrollLayoutController,
|
||||
new StatusBarHideIconsForBouncerManager(
|
||||
mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
|
||||
mStatusBarHideIconsForBouncerManager,
|
||||
mPowerManager,
|
||||
mVibratorHelper,
|
||||
Optional.of(mVibrator),
|
||||
|
||||
@@ -148,6 +148,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;
|
||||
@@ -229,6 +230,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;
|
||||
@@ -264,6 +266,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
@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 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
mLightBarController,
|
||||
mAutoHideController,
|
||||
mStatusBarWindowController,
|
||||
mStatusBarWindowStateController,
|
||||
mKeyguardUpdateMonitor,
|
||||
mStatusBarSignalPolicy,
|
||||
mPulseExpansionHandler,
|
||||
@@ -451,7 +455,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
mScreenOffAnimationController,
|
||||
mWallpaperController,
|
||||
mOngoingCallController,
|
||||
new StatusBarHideIconsForBouncerManager(mCommandQueue, mMainExecutor, mDumpManager),
|
||||
mStatusBarHideIconsForBouncerManager,
|
||||
mLockscreenTransitionController,
|
||||
mFeatureFlags,
|
||||
mKeyguardUnlockAnimationController,
|
||||
|
||||
@@ -37,7 +37,6 @@ 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;
|
||||
@@ -57,8 +56,6 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom
|
||||
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 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||
@Mock
|
||||
private NotificationPanelViewController mNotificationPanelViewController;
|
||||
@Mock
|
||||
private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
||||
|
||||
public CollapsedStatusBarFragmentTest() {
|
||||
super(CollapsedStatusBarFragment.class);
|
||||
@@ -325,8 +324,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
||||
new PanelExpansionStateManager(),
|
||||
mock(FeatureFlags.class),
|
||||
mStatusBarIconController,
|
||||
new StatusBarHideIconsForBouncerManager(
|
||||
mCommandQueue, new FakeExecutor(new FakeSystemClock()), new DumpManager()),
|
||||
mStatusBarHideIconsForBouncerManager,
|
||||
mKeyguardStateController,
|
||||
mNotificationPanelViewController,
|
||||
mNetworkController,
|
||||
|
||||
@@ -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