From 2e4f5782b665851def14bb87efac8ae80c0fef2b Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 1 Oct 2021 03:25:39 +0000 Subject: [PATCH 1/6] [Status Bar Refactor] Move PanelBar#collapsePanel into NotificationPanelViewController. PanelBar#collapsePanel mostly just called through to PanelViewController, so the function might as well belong in PVC. Test: Manually verified that the same functions are called in the correct order in various scenarios (open shade, close shade, open QS tile into new activity, close QS via home button while in app) Test: atest SystemUITests Bug: 200063118 Change-Id: I3c5d41db7daf8085baea73db806c6e350a7115bf --- .../NotificationPanelViewController.java | 43 +++++++++++++++++++ .../systemui/statusbar/phone/PanelBar.java | 32 ++++---------- .../statusbar/phone/PanelViewController.java | 4 ++ .../statusbar/phone/PhoneStatusBarView.java | 21 --------- .../statusbar/phone/ShadeControllerImpl.java | 3 +- .../systemui/statusbar/phone/StatusBar.java | 8 ++-- .../phone/StatusBarCommandQueueCallbacks.java | 2 +- .../NotificationPanelViewControllerTest.java | 1 + 8 files changed, 64 insertions(+), 50 deletions(-) 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 9dea5bc09e10c..71a07866a6eec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -1526,6 +1526,24 @@ public class NotificationPanelViewController extends PanelViewController { mNotificationStackScrollLayoutController.resetScrollPosition(); } + /** Collapses the panel. */ + public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) { + boolean waiting = false; + if (animate && !isFullyCollapsed()) { + collapse(delayed, speedUpFactor); + waiting = true; + } else { + resetViews(false /* animate */); + setExpandedFraction(0); // just in case + } + if (!waiting) { + // it's possible that nothing animated, so we replicate the termination + // conditions of panelExpansionChanged here + // TODO(b/200063118): This can likely go away in a future refactor CL. + mBar.updateState(STATE_CLOSED); + } + } + @Override public void collapse(boolean delayed, float speedUpFactor) { if (!canPanelBeCollapsed()) { @@ -3052,6 +3070,7 @@ public class NotificationPanelViewController extends PanelViewController { mAffordanceHelper.animateHideLeftRightIcon(); } mNotificationStackScrollLayoutController.onPanelTrackingStarted(); + cancelPendingPanelCollapse(); } @Override @@ -3671,13 +3690,27 @@ public class NotificationPanelViewController extends PanelViewController { mNotificationStackScrollLayoutController.setScrollingEnabled(b); } + private Runnable mHideExpandedRunnable; + private final Runnable mMaybeHideExpandedRunnable = new Runnable() { + @Override + public void run() { + if (getExpansionFraction() == 0.0f) { + mView.post(mHideExpandedRunnable); + } + } + }; + /** * Initialize objects instead of injecting to avoid circular dependencies. + * + * @param hideExpandedRunnable a runnable to run when we need to hide the expanded panel. */ public void initDependencies( StatusBar statusBar, + Runnable hideExpandedRunnable, NotificationShelfController notificationShelfController) { setStatusBar(statusBar); + mHideExpandedRunnable = hideExpandedRunnable; mNotificationStackScrollLayoutController.setShelfController(notificationShelfController); mNotificationShelfController = notificationShelfController; mLockscreenShadeTransitionController.bindController(notificationShelfController); @@ -4568,6 +4601,11 @@ public class NotificationPanelViewController extends PanelViewController { } } + /** Removes any pending runnables that would collapse the panel. */ + public void cancelPendingPanelCollapse() { + mView.removeCallbacks(mMaybeHideExpandedRunnable); + } + private final PanelBar.PanelStateChangeListener mPanelStateChangeListener = new PanelBar.PanelStateChangeListener() { @@ -4582,6 +4620,11 @@ public class NotificationPanelViewController extends PanelViewController { if (state == STATE_OPEN && mCurrentState != state) { mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } + if (state == STATE_CLOSED) { + // Close the status bar in the next frame so we can show the end of the + // animation. + mView.post(mMaybeHideExpandedRunnable); + } mCurrentState = state; } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 310fe73df1eac..f76665285e13a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -58,6 +58,14 @@ public abstract class PanelBar extends FrameLayout { private int mState = STATE_CLOSED; private boolean mTracking; + /** Updates the panel state if necessary. */ + public void updateState(@PanelState int state) { + if (DEBUG) LOG("update state: %d -> %d", mState, state); + if (mState != state) { + go(state); + } + } + private void go(@PanelState int state) { if (DEBUG) LOG("go state: %d -> %d", mState, state); mState = state; @@ -171,32 +179,12 @@ public abstract class PanelBar extends FrameLayout { go(STATE_OPEN); } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) { go(STATE_CLOSED); - onPanelCollapsed(); } if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState, fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":""); } - public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) { - boolean waiting = false; - PanelViewController pv = mPanel; - if (animate && !pv.isFullyCollapsed()) { - pv.collapse(delayed, speedUpFactor); - waiting = true; - } else { - pv.resetViews(false /* animate */); - pv.setExpandedFraction(0); // just in case - } - if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting); - if (!waiting && mState != STATE_CLOSED) { - // it's possible that nothing animated, so we replicate the termination - // conditions of panelExpansionChanged here - go(STATE_CLOSED); - onPanelCollapsed(); - } - } - public void onPanelPeeked() { if (DEBUG) LOG("onPanelPeeked"); } @@ -205,10 +193,6 @@ public abstract class PanelBar extends FrameLayout { return mState == STATE_CLOSED; } - public void onPanelCollapsed() { - if (DEBUG) LOG("onPanelCollapsed"); - } - public void onTrackingStarted() { mTracking = true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index c23577c523e36..6718306863586 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -1435,4 +1435,8 @@ public abstract class PanelViewController { private void cancelJankMonitoring(int cuj) { InteractionJankMonitor.getInstance().cancel(cuj); } + + protected float getExpansionFraction() { + return mExpandedFraction; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 150d9c8fcce66..610b0a758b499 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -55,14 +55,6 @@ public class PhoneStatusBarView extends PanelBar { StatusBar mBar; private ScrimController mScrimController; - private Runnable mHideExpandedRunnable = new Runnable() { - @Override - public void run() { - if (mPanelFraction == 0.0f) { - mBar.makeExpandedInvisible(); - } - } - }; private DarkReceiver mBattery; private DarkReceiver mClock; private int mRotationOrientation = -1; @@ -84,7 +76,6 @@ public class PhoneStatusBarView extends PanelBar { * Draw this many pixels into the left/right side of the cutout to optimally use the space */ private int mCutoutSideNudge = 0; - private boolean mHeadsUpVisible; public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -207,17 +198,6 @@ public class PhoneStatusBarView extends PanelBar { mBar.makeExpandedVisible(false); } - @Override - public void onPanelCollapsed() { - super.onPanelCollapsed(); - // Close the status bar in the next frame so we can show the end of the animation. - post(mHideExpandedRunnable); - } - - public void removePendingHideExpandedRunnables() { - removeCallbacks(mHideExpandedRunnable); - } - @Override public boolean onTouchEvent(MotionEvent event) { boolean barConsumedEvent = mBar.interceptTouchEvent(event); @@ -238,7 +218,6 @@ public class PhoneStatusBarView extends PanelBar { super.onTrackingStarted(); mBar.onTrackingStarted(); mScrimController.onTrackingStarted(); - removePendingHideExpandedRunnables(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java index 768222d348624..a54251a469018 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java @@ -128,7 +128,8 @@ public class ShadeControllerImpl implements ShadeController { mNotificationShadeWindowController.setNotificationShadeFocusable(false); getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper(); - getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor); + getNotificationPanelViewController() + .collapsePanel(true /* animate */, delayed, speedUpFactor); } else if (mBubblesOptional.isPresent()) { mBubblesOptional.get().collapseStack(); } 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 2ebe3c5eec144..b10972a31eb24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1316,6 +1316,7 @@ public class StatusBar extends SystemUI implements mNotificationPanelViewController.initDependencies( this, + this::makeExpandedInvisible, mNotificationShelfController); BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop); @@ -2157,7 +2158,8 @@ public class StatusBar extends SystemUI implements public void animateCollapseQuickSettings() { if (mState == StatusBarState.SHADE) { - mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */); + mNotificationPanelViewController.collapsePanel( + true, false /* delayed */, 1.0f /* speedUpFactor */); } } @@ -2170,7 +2172,7 @@ public class StatusBar extends SystemUI implements } // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868) - mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/, + mNotificationPanelViewController.collapsePanel(/*animate=*/ false, false /* delayed*/, 1.0f /* speedUpFactor */); mNotificationPanelViewController.closeQs(); @@ -4464,7 +4466,7 @@ public class StatusBar extends SystemUI implements mNavigationBarController.touchAutoDim(mDisplayId); Trace.beginSection("StatusBar#updateKeyguardState"); if (mState == StatusBarState.KEYGUARD && mStatusBarView != null) { - mStatusBarView.removePendingHideExpandedRunnables(); + mNotificationPanelViewController.cancelPendingPanelCollapse(); } updateDozingState(); checkBarModes(); 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 5301b25715340..bb1daa252cdf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java @@ -536,7 +536,7 @@ public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks { } if (mStatusBar.getStatusBarView() != null) { if (!showing && mStatusBarStateController.getState() == StatusBarState.SHADE) { - mStatusBar.getStatusBarView().collapsePanel( + mNotificationPanelViewController.collapsePanel( false /* animate */, false /* delayed */, 1.0f /* speedUpFactor */); } 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 265e418a279c7..23c76c6161695 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 @@ -450,6 +450,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mControlsComponent); mNotificationPanelViewController.initDependencies( mStatusBar, + () -> {}, mNotificationShelfController); mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager); mNotificationPanelViewController.setBar(mPanelBar); From 79dd2c6afbbb4fe3967738e06fc0282829d409b1 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 8 Oct 2021 15:14:45 +0000 Subject: [PATCH 2/6] [Status Bar Refactor] Remove unnecessary return value from StatusBar#interceptTouchEvent. That method always returned false. Test: Manual Bug: 199733640 Change-Id: Ie3b4c57191e72d9ca73914fd774ee3506d89a726 --- .../systemui/statusbar/phone/PhoneStatusBarView.java | 10 +++++----- .../android/systemui/statusbar/phone/StatusBar.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 610b0a758b499..800c2864d492f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -200,17 +200,16 @@ public class PhoneStatusBarView extends PanelBar { @Override public boolean onTouchEvent(MotionEvent event) { - boolean barConsumedEvent = mBar.interceptTouchEvent(event); + mBar.onTouchEvent(event); if (DEBUG_GESTURES) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH, - event.getActionMasked(), (int) event.getX(), (int) event.getY(), - barConsumedEvent ? 1 : 0); + event.getActionMasked(), (int) event.getX(), (int) event.getY()); } } - return barConsumedEvent || super.onTouchEvent(event); + return super.onTouchEvent(event); } @Override @@ -240,7 +239,8 @@ public class PhoneStatusBarView extends PanelBar { @Override public boolean onInterceptTouchEvent(MotionEvent event) { - return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event); + mBar.onTouchEvent(event); + return super.onInterceptTouchEvent(event); } @Override 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 b10972a31eb24..90394d3da4bfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2206,7 +2206,8 @@ public class StatusBar extends SystemUI implements } } - public boolean interceptTouchEvent(MotionEvent event) { + /** Called when a touch event occurred on {@link PhoneStatusBarView}. */ + public void onTouchEvent(MotionEvent event) { if (DEBUG_GESTURES) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH, @@ -2238,7 +2239,6 @@ public class StatusBar extends SystemUI implements event.getAction() == MotionEvent.ACTION_CANCEL; setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible); } - return false; } boolean isSameStatusBarState(int state) { From 8add0cb7fff07d4a169903f1309bd29f8dce1340 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Mon, 11 Oct 2021 21:04:43 +0000 Subject: [PATCH 3/6] [Status Bar Refactor] Move PanelBar's touch handling into NotificationPanelViewController. All the code should be exactly the same, it's just happening in a different place. Bug: 202981994 Bug: 200063118 Test: Manual: Can still interact with status bar and notification shade in all the typical ways Test: atest NotificationPanelViewControllerTest, PhoneStatusBarViewControllerTest, PhoneStatusBarViewTest, StatusBarTest Change-Id: Id882cff69d4670dd1ac89264c689e63d15240287 --- .../NotificationPanelViewController.java | 47 ++++++++++++- .../systemui/statusbar/phone/PanelBar.java | 45 ------------ .../statusbar/phone/PanelViewController.java | 30 +++++--- .../statusbar/phone/PhoneStatusBarView.java | 60 ++++++++-------- .../phone/PhoneStatusBarViewController.kt | 6 +- .../systemui/statusbar/phone/StatusBar.java | 10 ++- .../NotificationPanelViewControllerTest.java | 45 ++++++++++++ .../phone/PhoneStatusBarViewControllerTest.kt | 34 +++++---- .../statusbar/phone/PhoneStatusBarViewTest.kt | 70 +++++++++++++------ 9 files changed, 218 insertions(+), 129 deletions(-) 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 71a07866a6eec..46365de4b8a47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -3766,6 +3766,45 @@ public class NotificationPanelViewController extends PanelViewController { private long mLastTouchDownTime = -1L; + @Override + public boolean onTouchForwardedFromStatusBar(MotionEvent event) { + // TODO(b/202981994): Move the touch debugging in this method to a central location. + // (Right now, it's split between StatusBar and here.) + + // If panels aren't enabled, ignore the gesture and don't pass it down to the + // panel view. + if (!mCommandQueue.panelsEnabled()) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + Log.v( + TAG, + String.format( + "onTouchForwardedFromStatusBar: " + + "panel disabled, ignoring touch at (%d,%d)", + (int) event.getX(), + (int) event.getY() + ) + ); + } + return false; + } + + // If the view that would receive the touch is disabled, just have status bar eat + // the gesture. + if (event.getAction() == MotionEvent.ACTION_DOWN && !mView.isEnabled()) { + Log.v(TAG, + String.format( + "onTouchForwardedFromStatusBar: " + + "panel view disabled, eating touch at (%d,%d)", + (int) event.getX(), + (int) event.getY() + ) + ); + return true; + } + + return mView.dispatchTouchEvent(event); + } + @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (mBlockTouches || mQs.disallowPanelTouches()) { @@ -3777,7 +3816,7 @@ public class NotificationPanelViewController extends PanelViewController { if (mStatusBar.isBouncerShowing()) { return true; } - if (mBar.panelEnabled() + if (mCommandQueue.panelsEnabled() && !mNotificationStackScrollLayoutController.isLongPressInProgress() && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) { mMetricsLogger.count(COUNTER_PANEL_OPEN, 1); @@ -4632,4 +4671,10 @@ public class NotificationPanelViewController extends PanelViewController { public PanelBar.PanelStateChangeListener getPanelStateChangeListener() { return mPanelStateChangeListener; } + + + /** Returns the handler that the status bar should forward touches to. */ + public PhoneStatusBarView.TouchEventHandler getStatusBarTouchEventHandler() { + return getTouchHandler()::onTouchForwardedFromStatusBar; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index f76665285e13a..ba48ba65257a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -25,7 +25,6 @@ import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; -import android.view.MotionEvent; import android.widget.FrameLayout; import androidx.annotation.Nullable; @@ -53,7 +52,6 @@ public abstract class PanelBar extends FrameLayout { public static final int STATE_OPENING = 1; public static final int STATE_OPEN = 2; - private PanelViewController mPanel; @Nullable private PanelStateChangeListener mPanelStateChangeListener; private int mState = STATE_CLOSED; private boolean mTracking; @@ -105,54 +103,11 @@ public abstract class PanelBar extends FrameLayout { super.onFinishInflate(); } - /** Set the PanelViewController */ - public void setPanel(PanelViewController pv) { - mPanel = pv; - pv.setBar(this); - } - /** Sets the listener that will be notified of panel state changes. */ public void setPanelStateChangeListener(PanelStateChangeListener listener) { mPanelStateChangeListener = listener; } - public boolean panelEnabled() { - return true; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // Allow subclasses to implement enable/disable semantics - if (!panelEnabled()) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)", - (int) event.getX(), (int) event.getY())); - } - return false; - } - - if (event.getAction() == MotionEvent.ACTION_DOWN) { - final PanelViewController panel = mPanel; - if (panel == null) { - // panel is not there, so we'll eat the gesture - Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)", - (int) event.getX(), (int) event.getY())); - return true; - } - boolean enabled = panel.isEnabled(); - if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel, - (enabled ? "" : " (disabled)")); - if (!enabled) { - // panel is disabled, so we'll eat the gesture - Log.v(TAG, String.format( - "onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)", - panel, (int) event.getX(), (int) event.getY())); - return true; - } - } - return mPanel == null || mPanel.getView().dispatchTouchEvent(event); - } - /** * @param frac the fraction from the expansion in [0, 1] * @param expanded whether the panel is currently expanded; this is independent from the diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 6718306863586..393e85816a325 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -185,6 +185,8 @@ public abstract class PanelViewController { protected final SysuiStatusBarStateController mStatusBarStateController; protected final AmbientState mAmbientState; protected final LockscreenGestureLogger mLockscreenGestureLogger; + private final TouchHandler mTouchHandler; + protected void onExpandingFinished() { mBar.onExpandingFinished(); @@ -226,6 +228,7 @@ public abstract class PanelViewController { mView = view; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mLockscreenGestureLogger = lockscreenGestureLogger; + mTouchHandler = createTouchHandler(); mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { @@ -238,7 +241,7 @@ public abstract class PanelViewController { }); mView.addOnLayoutChangeListener(createLayoutChangeListener()); - mView.setOnTouchListener(createTouchHandler()); + mView.setOnTouchListener(mTouchHandler); mView.setOnConfigurationChangedListener(createOnConfigurationChangedListener()); mResources = mView.getResources(); @@ -289,6 +292,10 @@ public abstract class PanelViewController { : mTouchSlop; } + protected TouchHandler getTouchHandler() { + return mTouchHandler; + } + private void addMovement(MotionEvent event) { // Add movement to velocity tracker using raw screen X and Y coordinates instead // of window coordinates because the window frame may be moving at the same time. @@ -1153,23 +1160,28 @@ public abstract class PanelViewController { return mView; } - public boolean isEnabled() { - return mView.isEnabled(); - } - public OnLayoutChangeListener createLayoutChangeListener() { return new OnLayoutChangeListener(); } - protected TouchHandler createTouchHandler() { - return new TouchHandler(); - } + protected abstract TouchHandler createTouchHandler(); protected OnConfigurationChangedListener createOnConfigurationChangedListener() { return new OnConfigurationChangedListener(); } - public class TouchHandler implements View.OnTouchListener { + public abstract class TouchHandler implements View.OnTouchListener { + /** + * Method called when a touch has occurred on {@link PhoneStatusBarView}. + * + * Touches that occur on the status bar view may have ramifications for the notification + * panel (e.g. a touch that pulls down the shade could start on the status bar), so we need + * to notify the panel controller when these touches occur. + * + * Returns true if the event was handled and false otherwise. + */ + public abstract boolean onTouchForwardedFromStatusBar(MotionEvent event); + public boolean onInterceptTouchEvent(MotionEvent event) { if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 800c2864d492f..7bc460de9b47f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -24,7 +24,6 @@ import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.EventLog; import android.util.Log; import android.util.Pair; import android.view.DisplayCutout; @@ -37,7 +36,6 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.LinearLayout; import com.android.systemui.Dependency; -import com.android.systemui.EventLogTags; import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; @@ -69,8 +67,8 @@ public class PhoneStatusBarView extends PanelBar { private List mExpansionChangedListeners; @Nullable private PanelExpansionStateChangedListener mPanelExpansionStateChangedListener; - - private PanelEnabledProvider mPanelEnabledProvider; + @Nullable + private TouchEventHandler mTouchEventHandler; /** * Draw this many pixels into the left/right side of the cutout to optimally use the space @@ -95,6 +93,10 @@ public class PhoneStatusBarView extends PanelBar { mPanelExpansionStateChangedListener = listener; } + void setTouchEventHandler(TouchEventHandler handler) { + mTouchEventHandler = handler; + } + public void setScrimController(ScrimController scrimController) { mScrimController = scrimController; } @@ -168,15 +170,6 @@ public class PhoneStatusBarView extends PanelBar { return changed; } - @Override - public boolean panelEnabled() { - if (mPanelEnabledProvider == null) { - Log.e(TAG, "panelEnabledProvider is null; defaulting to super class."); - return super.panelEnabled(); - } - return mPanelEnabledProvider.panelEnabled(); - } - @Override public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) { if (super.onRequestSendAccessibilityEventInternal(child, event)) { @@ -201,15 +194,18 @@ public class PhoneStatusBarView extends PanelBar { @Override public boolean onTouchEvent(MotionEvent event) { mBar.onTouchEvent(event); - - if (DEBUG_GESTURES) { - if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { - EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH, - event.getActionMasked(), (int) event.getX(), (int) event.getY()); - } + if (mTouchEventHandler == null) { + Log.w( + TAG, + String.format( + "onTouch: No touch handler provided; eating gesture at (%d,%d)", + (int) event.getX(), + (int) event.getY() + ) + ); + return true; } - - return super.onTouchEvent(event); + return mTouchEventHandler.handleTouchEvent(event); } @Override @@ -261,11 +257,6 @@ public class PhoneStatusBarView extends PanelBar { } } - /** Set the {@link PanelEnabledProvider} to use. */ - public void setPanelEnabledProvider(PanelEnabledProvider panelEnabledProvider) { - mPanelEnabledProvider = panelEnabledProvider; - } - public void updateResources() { mCutoutSideNudge = getResources().getDimensionPixelSize( R.dimen.display_cutout_margin_consumption); @@ -345,15 +336,20 @@ public class PhoneStatusBarView extends PanelBar { getPaddingBottom()); } - /** An interface that will provide whether panel is enabled. */ - interface PanelEnabledProvider { - /** Returns true if the panel is enabled and false otherwise. */ - boolean panelEnabled(); - } - /** A listener that will be notified when a panel's expansion state may have changed. */ public interface PanelExpansionStateChangedListener { /** Called when a panel's expansion state may have changed. */ void onPanelExpansionStateChanged(); } + + /** + * A handler repsonsible for all touch event handling on the status bar. + * + * The handler will be notified each time {@link this#onTouchEvent} is called, and the return + * value from the handler will be returned from {@link this#onTouchEvent}. + **/ + public interface TouchEventHandler { + /** Called each time {@link this#onTouchEvent} is called. */ + boolean handleTouchEvent(MotionEvent event); + } } 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 4c0332a75df10..f4b10f045eeb7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -26,18 +26,16 @@ import com.android.systemui.util.ViewController /** Controller for [PhoneStatusBarView]. */ class PhoneStatusBarViewController( view: PhoneStatusBarView, - commandQueue: CommandQueue, statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?, panelExpansionStateChangedListener: PhoneStatusBarView.PanelExpansionStateChangedListener, + touchEventHandler: PhoneStatusBarView.TouchEventHandler, ) : ViewController(view) { override fun onViewAttached() {} override fun onViewDetached() {} init { - mView.setPanelEnabledProvider { - commandQueue.panelsEnabled() - } + mView.setTouchEventHandler(touchEventHandler) mView.setPanelExpansionStateChangedListener(panelExpansionStateChangedListener) statusBarMoveFromCenterAnimationController?.let { animationController -> 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 90394d3da4bfa..6fd0d06b31c2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1167,7 +1167,6 @@ public class StatusBar extends SystemUI implements PhoneStatusBarView oldStatusBarView = mStatusBarView; mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView(); mStatusBarView.setBar(this); - mStatusBarView.setPanel(mNotificationPanelViewController); mStatusBarView.setPanelStateChangeListener( mNotificationPanelViewController.getPanelStateChangeListener()); mStatusBarView.setScrimController(mScrimController); @@ -1176,6 +1175,8 @@ public class StatusBar extends SystemUI implements sendInitialExpansionAmount(listener); } + mNotificationPanelViewController.setBar(mStatusBarView); + StatusBarMoveFromCenterAnimationController moveFromCenterAnimation = null; if (mUnfoldTransitionConfig.isEnabled()) { moveFromCenterAnimation = mMoveFromCenterAnimation.get(); @@ -1183,9 +1184,10 @@ public class StatusBar extends SystemUI implements mPhoneStatusBarViewController = new PhoneStatusBarViewController( mStatusBarView, - mCommandQueue, moveFromCenterAnimation, - this::onPanelExpansionStateChanged); + this::onPanelExpansionStateChanged, + mNotificationPanelViewController.getStatusBarTouchEventHandler() + ); mPhoneStatusBarViewController.init(); mBatteryMeterViewController = new BatteryMeterViewController( @@ -2208,6 +2210,8 @@ public class StatusBar extends SystemUI implements /** Called when a touch event occurred on {@link PhoneStatusBarView}. */ public void onTouchEvent(MotionEvent event) { + // TODO(b/202981994): Move this touch debugging to a central location. (Right now, it's + // split between NotificationPanelViewController and here.) if (DEBUG_GESTURES) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH, 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 23c76c6161695..2369d8e1b50b4 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 @@ -518,6 +518,51 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse(); } + @Test + public void onTouchForwardedFromStatusBar_panelsNotEnabled_returnsFalseAndNoViewEvent() { + when(mCommandQueue.panelsEnabled()).thenReturn(false); + + boolean returnVal = mTouchHandler.onTouchForwardedFromStatusBar( + MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)); + + assertThat(returnVal).isFalse(); + verify(mView, never()).dispatchTouchEvent(any()); + } + + @Test + public void onTouchForwardedFromStatusBar_viewNotEnabled_returnsTrueAndNoViewEvent() { + when(mCommandQueue.panelsEnabled()).thenReturn(true); + when(mView.isEnabled()).thenReturn(false); + + boolean returnVal = mTouchHandler.onTouchForwardedFromStatusBar( + MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)); + + assertThat(returnVal).isTrue(); + verify(mView, never()).dispatchTouchEvent(any()); + } + + @Test + public void onTouchForwardedFromStatusBar_viewNotEnabledButIsMoveEvent_viewReceivesEvent() { + when(mCommandQueue.panelsEnabled()).thenReturn(true); + when(mView.isEnabled()).thenReturn(false); + MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0); + + mTouchHandler.onTouchForwardedFromStatusBar(event); + + verify(mView).dispatchTouchEvent(event); + } + + @Test + public void onTouchForwardedFromStatusBar_panelAndViewEnabled_viewReceivesEvent() { + when(mCommandQueue.panelsEnabled()).thenReturn(true); + when(mView.isEnabled()).thenReturn(true); + MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0); + + mTouchHandler.onTouchForwardedFromStatusBar(event); + + verify(mView).dispatchTouchEvent(event); + } + @Test public void testA11y_initializeNode() { AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo(); 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 52a5e064f984e..b53db88c01e75 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 @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone import android.view.LayoutInflater +import android.view.MotionEvent import android.view.ViewGroup import android.widget.FrameLayout import androidx.test.filters.SmallTest @@ -31,12 +32,14 @@ import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.verify +import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @SmallTest class PhoneStatusBarViewControllerTest : SysuiTestCase() { private val stateChangeListener = TestStateChangedListener() + private val touchEventHandler = TestTouchEventHandler() @Mock private lateinit var commandQueue: CommandQueue @@ -63,37 +66,31 @@ 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.setPanel(panelViewController) view.setScrimController(scrimController) + view.setBar(mock(StatusBar::class.java)) } controller = PhoneStatusBarViewController( view, - commandQueue, null, - stateChangeListener + stateChangeListener, + touchEventHandler, ) } @Test - fun constructor_setsPanelEnabledProviderOnView() { - var providerUsed = false - `when`(commandQueue.panelsEnabled()).then { - providerUsed = true - true - } + fun constructor_setsTouchHandlerOnView() { + val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) - // If the constructor correctly set a [PanelEnabledProvider], then it should be used - // when [PhoneStatusBarView.panelEnabled] is called. - view.panelEnabled() + view.onTouchEvent(event) - assertThat(providerUsed).isTrue() + assertThat(touchEventHandler.lastEvent).isEqualTo(event) } @Test fun constructor_moveFromCenterAnimationIsNotNull_moveFromCenterAnimationInitialized() { controller = PhoneStatusBarViewController( - view, commandQueue, moveFromCenterAnimation, stateChangeListener + view, moveFromCenterAnimation, stateChangeListener, touchEventHandler ) verify(moveFromCenterAnimation).init(any(), any()) @@ -117,4 +114,13 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { stateChangeCalled = true } } + + private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler { + var lastEvent: MotionEvent? = null + override fun handleTouchEvent(event: MotionEvent?): Boolean { + lastEvent = event + return false + } + + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt index ec7e07f905c63..5f72ff82c3441 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone +import android.view.MotionEvent import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -48,31 +49,10 @@ class PhoneStatusBarViewTest : SysuiTestCase() { `when`(panelViewController.view).thenReturn(panelView) view = PhoneStatusBarView(mContext, null) - view.setPanel(panelViewController) view.setScrimController(scrimController) view.setBar(statusBar) } - @Test - fun panelEnabled_providerReturnsTrue_returnsTrue() { - view.setPanelEnabledProvider { true } - - assertThat(view.panelEnabled()).isTrue() - } - - @Test - fun panelEnabled_providerReturnsFalse_returnsFalse() { - view.setPanelEnabledProvider { false } - - assertThat(view.panelEnabled()).isFalse() - } - - @Test - fun panelEnabled_noProvider_noCrash() { - view.panelEnabled() - // No assert needed, just testing no crash - } - @Test fun panelExpansionChanged_fracZero_stateChangeListenerNotified() { val listener = TestExpansionStateChangedListener() @@ -149,6 +129,45 @@ class PhoneStatusBarViewTest : SysuiTestCase() { // No assert needed, just testing no crash } + @Test + fun onTouchEvent_listenerNotified() { + val handler = TestTouchEventHandler() + view.setTouchEventHandler(handler) + + val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) + view.onTouchEvent(event) + + assertThat(handler.lastEvent).isEqualTo(event) + } + + @Test + fun onTouchEvent_listenerReturnsTrue_viewReturnsTrue() { + val handler = TestTouchEventHandler() + view.setTouchEventHandler(handler) + val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) + + handler.returnValue = true + + assertThat(view.onTouchEvent(event)).isTrue() + } + + @Test + fun onTouchEvent_listenerReturnsFalse_viewReturnsFalse() { + val handler = TestTouchEventHandler() + view.setTouchEventHandler(handler) + val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) + + handler.returnValue = false + + assertThat(view.onTouchEvent(event)).isFalse() + } + + @Test + fun onTouchEvent_noListener_noCrash() { + view.onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)) + // No assert needed, just testing no crash + } + private class TestExpansionStateChangedListener : PhoneStatusBarView.PanelExpansionStateChangedListener { var stateChangeCalled: Boolean = false @@ -164,4 +183,13 @@ class PhoneStatusBarViewTest : SysuiTestCase() { this.state = state } } + + private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler { + var lastEvent: MotionEvent? = null + var returnValue: Boolean = false + override fun handleTouchEvent(event: MotionEvent?): Boolean { + lastEvent = event + return returnValue + } + } } From e2132cdaedfab3be85d2c695bd960fd5b2ab512f Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Thu, 14 Oct 2021 19:51:11 +0000 Subject: [PATCH 4/6] [Status Bar Refactor] Move a bunch of callbacks out of PanelBar and into (N)PVC. No need for the callbacks to flow through PanelBar when (Notification)PanelViewController can just notify them directly. Test: Manual (verify callbacks still trigger at the correct times) Test: atest NotificationPanelViewControllerTest Bug: 200063118 Change-Id: I374dc97a5fec8ce9c08b167dfb1112262b475f2a --- .../NotificationPanelViewController.java | 5 ++-- .../systemui/statusbar/phone/PanelBar.java | 8 ------ .../statusbar/phone/PanelViewController.java | 12 +++------ .../statusbar/phone/PhoneStatusBarView.java | 25 ------------------- 4 files changed, 7 insertions(+), 43 deletions(-) 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 46365de4b8a47..b531d27ea14b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -2985,7 +2985,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override protected void onExpandingFinished() { - super.onExpandingFinished(); + mScrimController.onExpandingFinished(); mNotificationStackScrollLayoutController.onExpansionStopped(); mHeadsUpManager.onExpandingFinished(); mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); @@ -3060,6 +3060,7 @@ public class NotificationPanelViewController extends PanelViewController { protected void onTrackingStarted() { mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen()); super.onTrackingStarted(); + mScrimController.onTrackingStarted(); if (mQsFullyExpanded) { mQsExpandImmediate = true; if (!mShouldUseSplitNotificationShade) { @@ -3260,7 +3261,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override protected void onClosingFinished() { - super.onClosingFinished(); + mStatusBar.onClosingFinished(); setClosingWithAlphaFadeout(false); mMediaHierarchyManager.closeGuts(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index ba48ba65257a6..7e029f24e76f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -156,14 +156,6 @@ public abstract class PanelBar extends FrameLayout { mTracking = false; } - public void onExpandingFinished() { - if (DEBUG) LOG("onExpandingFinished"); - } - - public void onClosingFinished() { - - } - /** An interface that will be notified of panel state changes. */ public interface PanelStateChangeListener { /** Called when the state changes. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 393e85816a325..ac8ebd9badc27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -187,10 +187,7 @@ public abstract class PanelViewController { protected final LockscreenGestureLogger mLockscreenGestureLogger; private final TouchHandler mTouchHandler; - - protected void onExpandingFinished() { - mBar.onExpandingFinished(); - } + protected abstract void onExpandingFinished(); protected void onExpandingStarted() { } @@ -455,6 +452,7 @@ public abstract class PanelViewController { protected void onTrackingStopped(boolean expand) { mTracking = false; mBar.onTrackingStopped(expand); + mStatusBar.onTrackingStopped(expand); updatePanelExpansionAndVisibility(); } @@ -462,6 +460,7 @@ public abstract class PanelViewController { endClosing(); mTracking = true; mBar.onTrackingStarted(); + mStatusBar.onTrackingStarted(); notifyExpandingStarted(); updatePanelExpansionAndVisibility(); } @@ -934,10 +933,7 @@ public abstract class PanelViewController { mView.removeCallbacks(mFlingCollapseRunnable); } - protected void onClosingFinished() { - mBar.onClosingFinished(); - } - + protected abstract void onClosingFinished(); protected void startUnlockHintAnimation() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 7bc460de9b47f..98d0f7cf88341 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -208,31 +208,6 @@ public class PhoneStatusBarView extends PanelBar { return mTouchEventHandler.handleTouchEvent(event); } - @Override - public void onTrackingStarted() { - super.onTrackingStarted(); - mBar.onTrackingStarted(); - mScrimController.onTrackingStarted(); - } - - @Override - public void onClosingFinished() { - super.onClosingFinished(); - mBar.onClosingFinished(); - } - - @Override - public void onTrackingStopped(boolean expand) { - super.onTrackingStopped(expand); - mBar.onTrackingStopped(expand); - } - - @Override - public void onExpandingFinished() { - super.onExpandingFinished(); - mScrimController.onExpandingFinished(); - } - @Override public boolean onInterceptTouchEvent(MotionEvent event) { mBar.onTouchEvent(event); From 3483f6e8aa0396bc82ed7922e840a7a0bf7726a3 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 15 Oct 2021 20:14:32 +0000 Subject: [PATCH 5/6] [Status Bar Refactor] Remove PanelBar#onPanelPeeked and put its code in a callback instead. Test: manual (verified callback triggered correctly) Bug: 200063118 Change-Id: I59fe4951729da09ec8100ded4a1dfefffb6fd160 --- .../statusbar/phone/NotificationPanelViewController.java | 3 +++ .../src/com/android/systemui/statusbar/phone/PanelBar.java | 5 ----- .../systemui/statusbar/phone/PhoneStatusBarView.java | 6 ------ 3 files changed, 3 insertions(+), 11 deletions(-) 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 b531d27ea14b1..f1bc64b63afc4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -4660,6 +4660,9 @@ public class NotificationPanelViewController extends PanelViewController { if (state == STATE_OPEN && mCurrentState != state) { mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } + if (state == STATE_OPENING) { + mStatusBar.makeExpandedVisible(false); + } if (state == STATE_CLOSED) { // Close the status bar in the next frame so we can show the end of the // animation. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 7e029f24e76f0..e90258db85718 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -125,7 +125,6 @@ public abstract class PanelBar extends FrameLayout { if (expanded) { if (mState == STATE_CLOSED) { go(STATE_OPENING); - onPanelPeeked(); } fullyClosed = false; fullyOpened = frac >= 1f; @@ -140,10 +139,6 @@ public abstract class PanelBar extends FrameLayout { fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":""); } - public void onPanelPeeked() { - if (DEBUG) LOG("onPanelPeeked"); - } - public boolean isClosed() { return mState == STATE_CLOSED; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 98d0f7cf88341..cfd845f8c24bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -185,12 +185,6 @@ public class PhoneStatusBarView extends PanelBar { return false; } - @Override - public void onPanelPeeked() { - super.onPanelPeeked(); - mBar.makeExpandedVisible(false); - } - @Override public boolean onTouchEvent(MotionEvent event) { mBar.onTouchEvent(event); From 7bad7f99d82146ac035f52b1105d0e230cd91dd3 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Mon, 18 Oct 2021 18:42:28 +0000 Subject: [PATCH 6/6] [Status Bar Refactor] Combine PanelExpansionChange and PanelExpansionStateChange into one listener class. Test: manual (verified callbacks still trigger) Bug: 200063118 Change-Id: Iac617598fd41885a71b21728f1984838c44a2422 --- .../statusbar/phone/PhoneStatusBarView.java | 20 ------- .../phone/PhoneStatusBarViewController.kt | 2 - .../systemui/statusbar/phone/StatusBar.java | 16 +++--- .../phone/PhoneStatusBarViewControllerTest.kt | 26 +-------- .../statusbar/phone/PhoneStatusBarViewTest.kt | 53 ++++++------------- 5 files changed, 26 insertions(+), 91 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index cfd845f8c24bc..06a31c94896a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -66,8 +66,6 @@ public class PhoneStatusBarView extends PanelBar { @Nullable private List mExpansionChangedListeners; @Nullable - private PanelExpansionStateChangedListener mPanelExpansionStateChangedListener; - @Nullable private TouchEventHandler mTouchEventHandler; /** @@ -89,10 +87,6 @@ public class PhoneStatusBarView extends PanelBar { mExpansionChangedListeners = listeners; } - void setPanelExpansionStateChangedListener(PanelExpansionStateChangedListener listener) { - mPanelExpansionStateChangedListener = listener; - } - void setTouchEventHandler(TouchEventHandler handler) { mTouchEventHandler = handler; } @@ -211,14 +205,6 @@ public class PhoneStatusBarView extends PanelBar { @Override public void panelExpansionChanged(float frac, boolean expanded) { super.panelExpansionChanged(frac, expanded); - if ((frac == 0 || frac == 1)) { - if (mPanelExpansionStateChangedListener != null) { - mPanelExpansionStateChangedListener.onPanelExpansionStateChanged(); - } else { - Log.w(TAG, "No PanelExpansionStateChangedListener provided."); - } - } - if (mExpansionChangedListeners != null) { for (StatusBar.ExpansionChangedListener listener : mExpansionChangedListeners) { listener.onExpansionChanged(frac, expanded); @@ -305,12 +291,6 @@ public class PhoneStatusBarView extends PanelBar { getPaddingBottom()); } - /** A listener that will be notified when a panel's expansion state may have changed. */ - public interface PanelExpansionStateChangedListener { - /** Called when a panel's expansion state may have changed. */ - void onPanelExpansionStateChanged(); - } - /** * A handler repsonsible for all touch event handling on the status bar. * 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 f4b10f045eeb7..e27f4585e3206 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -27,7 +27,6 @@ import com.android.systemui.util.ViewController class PhoneStatusBarViewController( view: PhoneStatusBarView, statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?, - panelExpansionStateChangedListener: PhoneStatusBarView.PanelExpansionStateChangedListener, touchEventHandler: PhoneStatusBarView.TouchEventHandler, ) : ViewController(view) { @@ -36,7 +35,6 @@ class PhoneStatusBarViewController( init { mView.setTouchEventHandler(touchEventHandler) - mView.setPanelExpansionStateChangedListener(panelExpansionStateChangedListener) statusBarMoveFromCenterAnimationController?.let { animationController -> val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_left_side) 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 6fd0d06b31c2c..caa0dbe1a2c9a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -902,6 +902,7 @@ public class StatusBar extends SystemUI implements mExpansionChangedListeners = new ArrayList<>(); addExpansionChangedListener( (expansion, expanded) -> mScrimController.setRawPanelExpansionFraction(expansion)); + addExpansionChangedListener(this::onPanelExpansionChanged); mBubbleExpandListener = (isExpanding, key) -> mContext.getMainExecutor().execute(() -> { @@ -1185,7 +1186,6 @@ public class StatusBar extends SystemUI implements new PhoneStatusBarViewController( mStatusBarView, moveFromCenterAnimation, - this::onPanelExpansionStateChanged, mNotificationPanelViewController.getStatusBarTouchEventHandler() ); mPhoneStatusBarViewController.init(); @@ -1456,12 +1456,14 @@ public class StatusBar extends SystemUI implements } } - private void onPanelExpansionStateChanged() { - if (getNavigationBarView() != null) { - getNavigationBarView().onStatusBarPanelStateChanged(); - } - if (getNotificationPanelViewController() != null) { - getNotificationPanelViewController().updateSystemUiStateFlags(); + private void onPanelExpansionChanged(float frac, boolean expanded) { + if (frac == 0 || frac == 1) { + if (getNavigationBarView() != null) { + getNavigationBarView().onStatusBarPanelStateChanged(); + } + if (getNotificationPanelViewController() != null) { + getNotificationPanelViewController().updateSystemUiStateFlags(); + } } } 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 b53db88c01e75..033f689945c86 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 @@ -24,7 +24,6 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.systemui.R import com.android.systemui.SysuiTestCase -import com.android.systemui.statusbar.CommandQueue import com.android.systemui.util.mockito.any import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -38,11 +37,8 @@ import org.mockito.MockitoAnnotations @SmallTest class PhoneStatusBarViewControllerTest : SysuiTestCase() { - private val stateChangeListener = TestStateChangedListener() private val touchEventHandler = TestTouchEventHandler() - @Mock - private lateinit var commandQueue: CommandQueue @Mock private lateinit var panelViewController: PanelViewController @Mock @@ -73,7 +69,6 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { controller = PhoneStatusBarViewController( view, null, - stateChangeListener, touchEventHandler, ) } @@ -90,31 +85,12 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { @Test fun constructor_moveFromCenterAnimationIsNotNull_moveFromCenterAnimationInitialized() { controller = PhoneStatusBarViewController( - view, moveFromCenterAnimation, stateChangeListener, touchEventHandler + view, moveFromCenterAnimation, touchEventHandler ) verify(moveFromCenterAnimation).init(any(), any()) } - @Test - fun constructor_setsExpansionStateChangedListenerOnView() { - assertThat(stateChangeListener.stateChangeCalled).isFalse() - - // If the constructor correctly set the listener, then it should be used when - // [PhoneStatusBarView.panelExpansionChanged] is called. - view.panelExpansionChanged(0f, false) - - assertThat(stateChangeListener.stateChangeCalled).isTrue() - } - - private class TestStateChangedListener : PhoneStatusBarView.PanelExpansionStateChangedListener { - var stateChangeCalled: Boolean = false - - override fun onPanelExpansionStateChanged() { - stateChangeCalled = true - } - } - private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler { var lastEvent: MotionEvent? = null override fun handleTouchEvent(event: MotionEvent?): Boolean { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt index 5f72ff82c3441..fe3490399e81e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt @@ -54,37 +54,20 @@ class PhoneStatusBarViewTest : SysuiTestCase() { } @Test - fun panelExpansionChanged_fracZero_stateChangeListenerNotified() { - val listener = TestExpansionStateChangedListener() - view.setPanelExpansionStateChangedListener(listener) + fun panelExpansionChanged_expansionChangeListenerNotified() { + val listener = TestExpansionChangedListener() + view.setExpansionChangedListeners(listOf(listener)) + val fraction = 0.4f + val isExpanded = true - view.panelExpansionChanged(0f, false) + view.panelExpansionChanged(fraction, isExpanded) - assertThat(listener.stateChangeCalled).isTrue() + assertThat(listener.fraction).isEqualTo(fraction) + assertThat(listener.isExpanded).isEqualTo(isExpanded) } @Test - fun panelExpansionChanged_fracOne_stateChangeListenerNotified() { - val listener = TestExpansionStateChangedListener() - view.setPanelExpansionStateChangedListener(listener) - - view.panelExpansionChanged(1f, false) - - assertThat(listener.stateChangeCalled).isTrue() - } - - @Test - fun panelExpansionChanged_fracHalf_stateChangeListenerNotNotified() { - val listener = TestExpansionStateChangedListener() - view.setPanelExpansionStateChangedListener(listener) - - view.panelExpansionChanged(0.5f, false) - - assertThat(listener.stateChangeCalled).isFalse() - } - - @Test - fun panelExpansionChanged_noStateChangeListener_noCrash() { + fun panelExpansionChanged_noListeners_noCrash() { view.panelExpansionChanged(1f, false) // No assert needed, just testing no crash } @@ -123,12 +106,6 @@ class PhoneStatusBarViewTest : SysuiTestCase() { assertThat(listener.state).isEqualTo(PanelBar.STATE_CLOSED) } - @Test - fun panelStateChanged_noListener_noCrash() { - view.panelExpansionChanged(1f, true) - // No assert needed, just testing no crash - } - @Test fun onTouchEvent_listenerNotified() { val handler = TestTouchEventHandler() @@ -168,12 +145,14 @@ class PhoneStatusBarViewTest : SysuiTestCase() { // No assert needed, just testing no crash } - private class TestExpansionStateChangedListener - : PhoneStatusBarView.PanelExpansionStateChangedListener { - var stateChangeCalled: Boolean = false + private class TestExpansionChangedListener + : StatusBar.ExpansionChangedListener { + var fraction: Float = 0f + var isExpanded: Boolean = false - override fun onPanelExpansionStateChanged() { - stateChangeCalled = true + override fun onExpansionChanged(expansion: Float, expanded: Boolean) { + this.fraction = expansion + this.isExpanded = expanded } }