Use doze amount to ensure notification stability when going to sleep
Test: atest VisualStabilityCoordinatorTest
Fixes: 233396394
Change-Id: Ic6c6dfe428054bfdae8ed53ab6d6e9d599f238db
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index d7bd95c..b9d23b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -16,8 +16,9 @@
package com.android.systemui.statusbar.notification.collection.coordinator;
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -35,6 +36,7 @@
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
import com.android.systemui.statusbar.phone.NotifPanelEvents;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.Compile;
import com.android.systemui.util.concurrency.DelayableExecutor;
import java.io.PrintWriter;
@@ -54,6 +56,8 @@
@SysUISingleton
public class VisualStabilityCoordinator implements Coordinator, Dumpable,
NotifPanelEvents.Listener {
+ public static final String TAG = "VisualStability";
+ public static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
private final DelayableExecutor mDelayableExecutor;
private final HeadsUpManager mHeadsUpManager;
private final NotifPanelEvents mNotifPanelEvents;
@@ -61,7 +65,8 @@
private final VisualStabilityProvider mVisualStabilityProvider;
private final WakefulnessLifecycle mWakefulnessLifecycle;
- private boolean mScreenOn;
+ private boolean mSleepy = true;
+ private boolean mFullyDozed;
private boolean mPanelExpanded;
private boolean mPulsing;
private boolean mNotifPanelCollapsing;
@@ -104,8 +109,8 @@
@Override
public void attach(NotifPipeline pipeline) {
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
- mScreenOn = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
- || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING;
+ mSleepy = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP;
+ mFullyDozed = mStatusBarStateController.getDozeAmount() == 1f;
mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
mPulsing = mStatusBarStateController.isPulsing();
@@ -113,6 +118,7 @@
pipeline.setVisualStabilityManager(mNotifStabilityManager);
}
+
// TODO(b/203826051): Ensure stability manager can allow reordering off-screen
// HUNs to the top of the shade
private final NotifStabilityManager mNotifStabilityManager =
@@ -174,9 +180,18 @@
}
};
- private void updateAllowedStates() {
+ private void updateAllowedStates(String field, boolean value) {
+ boolean wasPipelineRunAllowed = mPipelineRunAllowed;
+ boolean wasReorderingAllowed = mReorderingAllowed;
mPipelineRunAllowed = !isPanelCollapsingOrLaunchingActivity();
mReorderingAllowed = isReorderingAllowed();
+ if (DEBUG && (wasPipelineRunAllowed != mPipelineRunAllowed
+ || wasReorderingAllowed != mReorderingAllowed)) {
+ Log.d(TAG, "Stability allowances changed:"
+ + " pipelineRunAllowed " + wasPipelineRunAllowed + "->" + mPipelineRunAllowed
+ + " reorderingAllowed " + wasReorderingAllowed + "->" + mReorderingAllowed
+ + " when setting " + field + "=" + value);
+ }
if ((mPipelineRunAllowed && mIsSuppressingPipelineRun)
|| (mReorderingAllowed && (mIsSuppressingGroupChange
|| isSuppressingSectionChange()
@@ -195,7 +210,7 @@
}
private boolean isReorderingAllowed() {
- return (!mScreenOn || !mPanelExpanded) && !mPulsing;
+ return ((mFullyDozed && mSleepy) || !mPanelExpanded) && !mPulsing;
}
/**
@@ -235,27 +250,37 @@
@Override
public void onPulsingChanged(boolean pulsing) {
mPulsing = pulsing;
- updateAllowedStates();
+ updateAllowedStates("pulsing", pulsing);
}
@Override
public void onExpandedChanged(boolean expanded) {
mPanelExpanded = expanded;
- updateAllowedStates();
+ updateAllowedStates("panelExpanded", expanded);
+ }
+
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ final boolean fullyDozed = linear == 1f;
+ mFullyDozed = fullyDozed;
+ updateAllowedStates("fullyDozed", fullyDozed);
}
};
final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedGoingToSleep() {
- mScreenOn = false;
- updateAllowedStates();
+ // NOTE: this method is called much earlier than what we consider "finished" going to
+ // sleep (the animation isn't done), so we also need to check the doze amount is not 1
+ // and use the combo to determine that the locked shade is not visible.
+ mSleepy = true;
+ updateAllowedStates("sleepy", true);
}
@Override
public void onStartedWakingUp() {
- mScreenOn = true;
- updateAllowedStates();
+ mSleepy = false;
+ updateAllowedStates("sleepy", false);
}
};
@@ -265,7 +290,8 @@
pw.println(" notifPanelCollapsing: " + mNotifPanelCollapsing);
pw.println(" launchingNotifActivity: " + mNotifPanelLaunchingActivity);
pw.println("reorderingAllowed: " + mReorderingAllowed);
- pw.println(" screenOn: " + mScreenOn);
+ pw.println(" sleepy: " + mSleepy);
+ pw.println(" fullyDozed: " + mFullyDozed);
pw.println(" panelExpanded: " + mPanelExpanded);
pw.println(" pulsing: " + mPulsing);
pw.println("isSuppressingPipelineRun: " + mIsSuppressingPipelineRun);
@@ -285,12 +311,12 @@
@Override
public void onPanelCollapsingChanged(boolean isCollapsing) {
mNotifPanelCollapsing = isCollapsing;
- updateAllowedStates();
+ updateAllowedStates("notifPanelCollapsing", isCollapsing);
}
@Override
public void onLaunchingActivityChanged(boolean isLaunchingActivity) {
mNotifPanelLaunchingActivity = isLaunchingActivity;
- updateAllowedStates();
+ updateAllowedStates("notifPanelLaunchingActivity", isLaunchingActivity);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index f3aa20b..2f37f89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -136,7 +136,8 @@
@Test
public void testScreenOff_groupAndSectionChangesAllowed() {
// GIVEN screen is off, panel isn't expanded and device isn't pulsing
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPanelExpanded(false);
setPulsing(false);
@@ -149,9 +150,42 @@
}
@Test
+ public void testScreenTurningOff_groupAndSectionChangesNotAllowed() {
+ // GIVEN the screen is turning off (sleepy but partially dozed)
+ setFullyDozed(false);
+ setSleepy(true);
+ setPanelExpanded(true);
+ setPulsing(false);
+
+ // THEN group changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+ assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry));
+
+ // THEN section changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testScreenTurningOn_groupAndSectionChangesNotAllowed() {
+ // GIVEN the screen is turning on (still fully dozed, not sleepy)
+ setFullyDozed(true);
+ setSleepy(false);
+ setPanelExpanded(true);
+ setPulsing(false);
+
+ // THEN group changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+ assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry));
+
+ // THEN section changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
public void testPanelNotExpanded_groupAndSectionChangesAllowed() {
// GIVEN screen is on but the panel isn't expanded and device isn't pulsing
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(false);
setPulsing(false);
@@ -166,7 +200,8 @@
@Test
public void testPanelExpanded_groupAndSectionChangesNotAllowed() {
// GIVEN the panel true expanded and device isn't pulsing
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
setPulsing(false);
@@ -181,7 +216,8 @@
@Test
public void testPulsing_screenOff_groupAndSectionChangesNotAllowed() {
// GIVEN the device is pulsing and screen is off
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPulsing(true);
// THEN group changes are NOT allowed
@@ -195,7 +231,8 @@
@Test
public void testPulsing_panelNotExpanded_groupAndSectionChangesNotAllowed() {
// GIVEN the device is pulsing and screen is off with the panel not expanded
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPanelExpanded(false);
setPulsing(true);
@@ -211,7 +248,8 @@
public void testOverrideReorderingSuppression_onlySectionChangesAllowed() {
// GIVEN section changes typically wouldn't be allowed because the panel is expanded and
// we're not pulsing
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
setPulsing(true);
@@ -233,7 +271,8 @@
@Test
public void testTemporarilyAllowSectionChanges_callsInvalidate() {
// GIVEN section changes typically wouldn't be allowed because the panel is expanded
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
setPulsing(false);
@@ -247,7 +286,8 @@
@Test
public void testTemporarilyAllowSectionChanges_noInvalidationCalled() {
// GIVEN section changes typically WOULD be allowed
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPanelExpanded(false);
setPulsing(false);
@@ -261,7 +301,8 @@
@Test
public void testTemporarilyAllowSectionChangesTimeout() {
// GIVEN section changes typically WOULD be allowed
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPanelExpanded(false);
setPulsing(false);
assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
@@ -292,7 +333,8 @@
@Test
public void testTemporarilyAllowSectionChanges_isPulsingChangeBeforeTimeout() {
// GIVEN section changes typically wouldn't be allowed because the device is pulsing
- setScreenOn(false);
+ setFullyDozed(true);
+ setSleepy(true);
setPanelExpanded(false);
setPulsing(true);
@@ -315,8 +357,11 @@
// WHEN device isn't pulsing anymore
setPulsing(false);
- // WHEN screen isn't on
- setScreenOn(false);
+ // WHEN fully dozed
+ setFullyDozed(true);
+
+ // WHEN sleepy
+ setSleepy(true);
// WHEN panel isn't expanded
setPanelExpanded(false);
@@ -330,7 +375,8 @@
public void testNotSuppressingGroupChangesAnymore_invalidationCalled() {
// GIVEN visual stability is being maintained b/c panel is expanded
setPulsing(false);
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
@@ -399,7 +445,8 @@
public void testNotSuppressingEntryReorderingAnymoreWillInvalidate() {
// GIVEN visual stability is being maintained b/c panel is expanded
setPulsing(false);
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
@@ -417,7 +464,8 @@
public void testQueryingEntryReorderingButNotReportingReorderSuppressedDoesNotInvalidate() {
// GIVEN visual stability is being maintained b/c panel is expanded
setPulsing(false);
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
@@ -432,7 +480,8 @@
@Test
public void testHeadsUp_allowedToChangeGroupAndSection() {
// GIVEN group + section changes disallowed
- setScreenOn(true);
+ setFullyDozed(false);
+ setSleepy(false);
setPanelExpanded(true);
setPulsing(true);
assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
@@ -462,11 +511,16 @@
mStatusBarStateListener.onPulsingChanged(pulsing);
}
- private void setScreenOn(boolean screenOn) {
- if (screenOn) {
- mWakefulnessObserver.onStartedWakingUp();
- } else {
+ private void setFullyDozed(boolean fullyDozed) {
+ float dozeAmount = fullyDozed ? 1 : 0;
+ mStatusBarStateListener.onDozeAmountChanged(dozeAmount, dozeAmount);
+ }
+
+ private void setSleepy(boolean sleepy) {
+ if (sleepy) {
mWakefulnessObserver.onFinishedGoingToSleep();
+ } else {
+ mWakefulnessObserver.onStartedWakingUp();
}
}