From 11e72d9f218813cd63d7654fc0d290de748c0fbd Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 17 Sep 2021 21:17:40 +0000 Subject: [PATCH 1/3] [Status Bar Refactor] Add a PanelStateChangeListener interface and use it in PanelBar#go. Bug: 200063118 Test: manual Test: atest PhoneStatusBarViewTest Change-Id: I41e1854ec919ba3619e3abdecd0974e1c1e0d06f --- .../NotificationPanelViewController.java | 17 +++--- .../systemui/statusbar/phone/PanelBar.java | 32 +++++++--- .../statusbar/phone/PanelViewController.java | 5 -- .../systemui/statusbar/phone/StatusBar.java | 2 + .../statusbar/phone/PhoneStatusBarViewTest.kt | 59 +++++++++++++++++-- 5 files changed, 92 insertions(+), 23 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 4862d16178371..138989c04f0ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -57,7 +57,6 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Region; import android.graphics.drawable.Drawable; -import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.SensorLocationInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Bundle; @@ -2228,12 +2227,6 @@ public class NotificationPanelViewController extends PanelViewController { updateQSExpansionEnabledAmbient(); } - @Override - public void setIsShadeOpening(boolean opening) { - mAmbientState.setIsShadeOpening(opening); - updateQSExpansionEnabledAmbient(); - } - private void updateQSExpansionEnabledAmbient() { final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsOffsetHeight; mQsExpansionEnabledAmbient = mShouldUseSplitNotificationShade @@ -4629,4 +4622,14 @@ public class NotificationPanelViewController extends PanelViewController { return insets; } } + + private final PanelBar.PanelStateChangeListener mPanelStateChangeListener = + state -> { + mAmbientState.setIsShadeOpening(state == PanelBar.STATE_OPENING); + updateQSExpansionEnabledAmbient(); + }; + + public PanelBar.PanelStateChangeListener getPanelStateChangeListener() { + return mPanelStateChangeListener; + } } 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 247ede91eeb31..4b9d5ec140561 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -17,8 +17,10 @@ package com.android.systemui.statusbar.phone; import static java.lang.Float.isNaN; +import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.CallSuper; +import android.annotation.IntDef; import android.content.Context; import android.os.Bundle; import android.os.Parcelable; @@ -27,6 +29,10 @@ import android.util.Log; import android.view.MotionEvent; import android.widget.FrameLayout; +import androidx.annotation.Nullable; + +import java.lang.annotation.Retention; + public abstract class PanelBar extends FrameLayout { public static final boolean DEBUG = false; public static final String TAG = PanelBar.class.getSimpleName(); @@ -40,26 +46,27 @@ public abstract class PanelBar extends FrameLayout { Log.v(TAG, String.format(fmt, args)); } + /** Enum for the current state of the panel. */ + @Retention(SOURCE) + @IntDef({STATE_CLOSED, STATE_OPENING, STATE_OPEN}) + @interface PanelState {} public static final int STATE_CLOSED = 0; public static final int STATE_OPENING = 1; public static final int STATE_OPEN = 2; PanelViewController mPanel; + @Nullable private PanelStateChangeListener mPanelStateChangeListener; private int mState = STATE_CLOSED; private boolean mTracking; - public void go(int state) { + private void go(@PanelState int state) { if (DEBUG) LOG("go state: %d -> %d", mState, state); mState = state; - if (mPanel != null) { - mPanel.setIsShadeOpening(state == STATE_OPENING); + if (mPanelStateChangeListener != null) { + mPanelStateChangeListener.onStateChanged(state); } } - protected boolean isShadeOpening() { - return mState == STATE_OPENING; - } - @Override protected Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); @@ -97,6 +104,11 @@ public abstract class PanelBar extends FrameLayout { 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; } @@ -226,4 +238,10 @@ public abstract class PanelBar extends FrameLayout { public void onClosingFinished() { } + + /** An interface that will be notified of panel state changes. */ + public interface PanelStateChangeListener { + /** Called when the state changes. */ + void onStateChanged(@PanelState int state); + } } 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 b2155154d6523..54adac098a334 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -1171,11 +1171,6 @@ public abstract class PanelViewController { return new OnConfigurationChangedListener(); } - /** - * Set that the panel is currently opening and not fully opened or closed. - */ - public abstract void setIsShadeOpening(boolean opening); - public class TouchHandler implements View.OnTouchListener { public boolean onInterceptTouchEvent(MotionEvent event) { if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled || (mMotionAborted 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 2130e028e8637..67b2ee5ba2106 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1161,6 +1161,8 @@ public class StatusBar extends SystemUI implements mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView(); mStatusBarView.setBar(this); mStatusBarView.setPanel(mNotificationPanelViewController); + mStatusBarView.setPanelStateChangeListener( + mNotificationPanelViewController.getPanelStateChangeListener()); mStatusBarView.setScrimController(mScrimController); mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners); for (ExpansionChangedListener listener : mExpansionChangedListeners) { 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 aee9f12c3844a..ec7e07f905c63 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 @@ -35,6 +35,8 @@ class PhoneStatusBarViewTest : SysuiTestCase() { private lateinit var panelView: ViewGroup @Mock private lateinit var scrimController: ScrimController + @Mock + private lateinit var statusBar: StatusBar private lateinit var view: PhoneStatusBarView @@ -48,6 +50,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { view = PhoneStatusBarView(mContext, null) view.setPanel(panelViewController) view.setScrimController(scrimController) + view.setBar(statusBar) } @Test @@ -72,7 +75,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { @Test fun panelExpansionChanged_fracZero_stateChangeListenerNotified() { - val listener = TestStateChangedListener() + val listener = TestExpansionStateChangedListener() view.setPanelExpansionStateChangedListener(listener) view.panelExpansionChanged(0f, false) @@ -82,7 +85,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { @Test fun panelExpansionChanged_fracOne_stateChangeListenerNotified() { - val listener = TestStateChangedListener() + val listener = TestExpansionStateChangedListener() view.setPanelExpansionStateChangedListener(listener) view.panelExpansionChanged(1f, false) @@ -92,7 +95,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { @Test fun panelExpansionChanged_fracHalf_stateChangeListenerNotNotified() { - val listener = TestStateChangedListener() + val listener = TestExpansionStateChangedListener() view.setPanelExpansionStateChangedListener(listener) view.panelExpansionChanged(0.5f, false) @@ -106,11 +109,59 @@ class PhoneStatusBarViewTest : SysuiTestCase() { // No assert needed, just testing no crash } - private class TestStateChangedListener : PhoneStatusBarView.PanelExpansionStateChangedListener { + @Test + fun panelStateChanged_toStateOpening_listenerNotified() { + val listener = TestStateChangedListener() + view.setPanelStateChangeListener(listener) + + view.panelExpansionChanged(0.5f, true) + + assertThat(listener.state).isEqualTo(PanelBar.STATE_OPENING) + } + + @Test + fun panelStateChanged_toStateOpen_listenerNotified() { + val listener = TestStateChangedListener() + view.setPanelStateChangeListener(listener) + + view.panelExpansionChanged(1f, true) + + assertThat(listener.state).isEqualTo(PanelBar.STATE_OPEN) + } + + @Test + fun panelStateChanged_toStateClosed_listenerNotified() { + val listener = TestStateChangedListener() + view.setPanelStateChangeListener(listener) + + // First, open the panel + view.panelExpansionChanged(1f, true) + + // Then, close it again + view.panelExpansionChanged(0f, false) + + assertThat(listener.state).isEqualTo(PanelBar.STATE_CLOSED) + } + + @Test + fun panelStateChanged_noListener_noCrash() { + view.panelExpansionChanged(1f, true) + // No assert needed, just testing no crash + } + + private class TestExpansionStateChangedListener + : PhoneStatusBarView.PanelExpansionStateChangedListener { var stateChangeCalled: Boolean = false override fun onPanelExpansionStateChanged() { stateChangeCalled = true } } + + private class TestStateChangedListener : PanelBar.PanelStateChangeListener { + var state: Int = 0 + override fun onStateChanged(state: Int) { + this.state = state + } + } } From 23fc3d6b6ea755b2429557d2ee2451498df76918 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 1 Oct 2021 01:40:37 +0000 Subject: [PATCH 2/3] [Status Bar Refactor] Remove PanelBar#onPanelFullyOpened and instead handle that logic in the listener callback. Test: manual Bug: 200063118 Change-Id: I3e327a8372d052098e732bd9d51f118028b9731a --- .../NotificationPanelViewController.java | 22 ++++++++++++++++--- .../systemui/statusbar/phone/PanelBar.java | 7 +----- .../statusbar/phone/PhoneStatusBarView.java | 11 ---------- 3 files changed, 20 insertions(+), 20 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 138989c04f0ee..d36fae199072f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -34,6 +34,9 @@ import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL; +import static com.android.systemui.statusbar.phone.PanelBar.STATE_CLOSED; +import static com.android.systemui.statusbar.phone.PanelBar.STATE_OPEN; +import static com.android.systemui.statusbar.phone.PanelBar.STATE_OPENING; import static java.lang.Float.isNaN; @@ -79,6 +82,7 @@ import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.ViewTreeObserver; import android.view.WindowInsets; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; @@ -4624,9 +4628,21 @@ public class NotificationPanelViewController extends PanelViewController { } private final PanelBar.PanelStateChangeListener mPanelStateChangeListener = - state -> { - mAmbientState.setIsShadeOpening(state == PanelBar.STATE_OPENING); - updateQSExpansionEnabledAmbient(); + new PanelBar.PanelStateChangeListener() { + + @PanelBar.PanelState + private int mCurrentState = STATE_CLOSED; + + @Override + public void onStateChanged(@PanelBar.PanelState int state) { + mAmbientState.setIsShadeOpening(state == STATE_OPENING); + updateQSExpansionEnabledAmbient(); + + if (state == STATE_OPEN && mCurrentState != state) { + mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + } + mCurrentState = state; + } }; public PanelBar.PanelStateChangeListener getPanelStateChangeListener() { 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 4b9d5ec140561..430edfdd9d19d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -54,7 +54,7 @@ public abstract class PanelBar extends FrameLayout { public static final int STATE_OPENING = 1; public static final int STATE_OPEN = 2; - PanelViewController mPanel; + private PanelViewController mPanel; @Nullable private PanelStateChangeListener mPanelStateChangeListener; private int mState = STATE_CLOSED; private boolean mTracking; @@ -178,7 +178,6 @@ public abstract class PanelBar extends FrameLayout { } if (fullyOpened && !mTracking) { go(STATE_OPEN); - onPanelFullyOpened(); } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) { go(STATE_CLOSED); onPanelCollapsed(); @@ -219,10 +218,6 @@ public abstract class PanelBar extends FrameLayout { if (DEBUG) LOG("onPanelCollapsed"); } - public void onPanelFullyOpened() { - if (DEBUG) LOG("onPanelFullyOpened"); - } - public void onTrackingStarted() { mTracking = true; } 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 9ab6cdd3053bc..815f6fe850225 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -56,7 +56,6 @@ public class PhoneStatusBarView extends PanelBar { StatusBar mBar; - boolean mIsFullyOpenedPanel = false; private ScrimController mScrimController; private float mMinFraction; private Runnable mHideExpandedRunnable = new Runnable() { @@ -216,22 +215,12 @@ public class PhoneStatusBarView extends PanelBar { super.onPanelCollapsed(); // Close the status bar in the next frame so we can show the end of the animation. post(mHideExpandedRunnable); - mIsFullyOpenedPanel = false; } public void removePendingHideExpandedRunnables() { removeCallbacks(mHideExpandedRunnable); } - @Override - public void onPanelFullyOpened() { - super.onPanelFullyOpened(); - if (!mIsFullyOpenedPanel) { - mPanel.getView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - } - mIsFullyOpenedPanel = true; - } - @Override public boolean onTouchEvent(MotionEvent event) { boolean barConsumedEvent = mBar.interceptTouchEvent(event); From 4cbf1b636c270657e8cc8175b503a09b517ea50c Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Fri, 1 Oct 2021 02:55:17 +0000 Subject: [PATCH 3/3] [Status Bar Refactor] Remove some indirection about minFraction between NotificationPanelViewController and PanelBar. The current code flow is NPVC#setPanelScrimMinFraction => PanelBar#onPanelMinFractionChanged => NPVC#setMinFraction. The minFraction doesn't need to flow through PanelBar if it's going to go right back to NPVC. Test: Test steps from ag/15759151 Bug: 200063118 Change-Id: If31a0d78cf4ac4a4d4bc6fcc7423a8006ab309fa --- .../phone/NotificationPanelViewController.java | 15 ++++++--------- .../systemui/statusbar/phone/PanelBar.java | 6 +----- .../statusbar/phone/PanelViewController.java | 7 ------- .../statusbar/phone/PhoneStatusBarView.java | 1 - .../NotificationPanelViewControllerTest.java | 4 ++-- 5 files changed, 9 insertions(+), 24 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 d36fae199072f..c88303a09d1da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -1801,15 +1801,6 @@ public class NotificationPanelViewController extends PanelViewController { return !mQsTouchAboveFalsingThreshold; } - /** - * Percentage of panel expansion offset, caused by pulling down on a heads-up. - */ - @Override - public void setMinFraction(float minFraction) { - mMinFraction = minFraction; - mDepthController.setPanelPullDownMinFraction(mMinFraction); - } - private float computeQsExpansionFraction() { if (mQSAnimatingHiddenFromCollapsed) { // When hiding QS from collapsed state, the expansion can sometimes temporarily @@ -3337,8 +3328,14 @@ public class NotificationPanelViewController extends PanelViewController { return mBarState == KEYGUARD; } + /** + * Sets the minimum fraction for the panel expansion offset. This may be non-zero in certain + * cases, such as if there's a heads-up notification. + */ public void setPanelScrimMinFraction(float minFraction) { mBar.onPanelMinFractionChanged(minFraction); + mMinFraction = minFraction; + mDepthController.setPanelPullDownMinFraction(mMinFraction); } public void clearNotificationEffects() { 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 430edfdd9d19d..1f1090d7168b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone; import static java.lang.Float.isNaN; import static java.lang.annotation.RetentionPolicy.SOURCE; -import android.annotation.CallSuper; import android.annotation.IntDef; import android.content.Context; import android.os.Bundle; @@ -149,10 +148,7 @@ public abstract class PanelBar extends FrameLayout { /** * Percentage of panel expansion offset, caused by pulling down on a heads-up. */ - @CallSuper - public void onPanelMinFractionChanged(float minFraction) { - mPanel.setMinFraction(minFraction); - } + abstract void onPanelMinFractionChanged(float minFraction); /** * @param frac the fraction from the expansion in [0, 1] 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 54adac098a334..768567b8b4741 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -342,13 +342,6 @@ public abstract class PanelViewController { protected abstract float getOpeningHeight(); - /** - * Minimum fraction from where expansion should start. This is set when pulling down on a - * heads-up notification. - * @param minFraction Fraction from 0 to 1. - */ - public abstract void setMinFraction(float minFraction); - /** * @return whether the swiping direction is upwards and above a 45 degree angle compared to the * horizontal direction 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 815f6fe850225..1cca4777da0a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -272,7 +272,6 @@ public class PhoneStatusBarView extends PanelBar { if (isNaN(minFraction)) { throw new IllegalArgumentException("minFraction cannot be NaN"); } - super.onPanelMinFractionChanged(minFraction); if (mMinFraction != minFraction) { mMinFraction = minFraction; updateScrimFraction(); 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 f7423bb7951df..e286ea986fded 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 @@ -469,8 +469,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } @Test - public void testSetMinFraction() { - mNotificationPanelViewController.setMinFraction(0.5f); + public void testSetPanelScrimMinFraction() { + mNotificationPanelViewController.setPanelScrimMinFraction(0.5f); verify(mNotificationShadeDepthController).setPanelPullDownMinFraction(eq(0.5f)); }