Introduced the visual stability manager
Notifications used to roam around and reorder whenever
they wished. Those little beasts must be tamed, hence
a new visual stability manager is introduced that
dictates the terms of their interplay.
Test: manual: add heads-up and see if they correctly appear
Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java
Bug: 32442500
Change-Id: I8d7596fa7c14e0df68459a77d445f618d517ad51
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 2c8339a..f25e599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -23,6 +23,7 @@
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -35,7 +36,7 @@
/**
* A class to handle notifications and their corresponding groups.
*/
-public class NotificationGroupManager implements HeadsUpManager.OnHeadsUpChangedListener {
+public class NotificationGroupManager implements OnHeadsUpChangedListener {
private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
private OnGroupChangeListener mListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index a239cb6..7f6322a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -63,6 +63,7 @@
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -72,7 +73,7 @@
ExpandableView.OnHeightChangedListener,
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
- HeadsUpManager.OnHeadsUpChangedListener, QS.HeightListener {
+ OnHeadsUpChangedListener, QS.HeightListener {
private static final boolean DEBUG = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f82642d..1722c7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -151,7 +151,6 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
import com.android.systemui.recents.events.activity.UndockingTaskEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
@@ -172,6 +171,7 @@
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -189,8 +189,8 @@
import com.android.systemui.statusbar.policy.LocationControllerImpl;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
-import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
import com.android.systemui.statusbar.policy.SecurityControllerImpl;
@@ -201,7 +201,6 @@
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout
.OnChildLocationsChangedListener;
import com.android.systemui.statusbar.stack.StackStateAnimator;
-import com.android.systemui.statusbar.stack.ExpandableViewState;
import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
@@ -216,7 +215,7 @@
public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
- HeadsUpManager.OnHeadsUpChangedListener {
+ OnHeadsUpChangedListener, VisualStabilityManager.Callback {
static final String TAG = "PhoneStatusBar";
public static final boolean DEBUG = BaseStatusBar.DEBUG;
public static final boolean SPEW = false;
@@ -573,9 +572,6 @@
*/
protected boolean mStartedGoingToSleep;
- private static final int VISIBLE_LOCATIONS = ExpandableViewState.LOCATION_FIRST_HUN
- | ExpandableViewState.LOCATION_MAIN_AREA;
-
private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
new OnChildLocationsChangedListener() {
@Override
@@ -624,8 +620,7 @@
for (int i = 0; i < N; i++) {
Entry entry = activeNotifications.get(i);
String key = entry.notification.getKey();
- boolean isVisible =
- (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
+ boolean isVisible = mStackScroller.isInVisibleLocation(entry.row);
NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
if (isVisible) {
@@ -782,9 +777,11 @@
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mHeadsUpManager.addListener(mGroupManager);
+ mHeadsUpManager.addListener(mVisualStabilityManager);
mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
mNotificationData.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
+ mHeadsUpManager.setVisualStabilityManager(mVisualStabilityManager);
if (MULTIUSER_DEBUG) {
mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
@@ -814,6 +811,7 @@
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setOnGroupChangeListener(mStackScroller);
+ mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
inflateShelf();
inflateEmptyShadeView();
@@ -1781,6 +1779,11 @@
final int N = activeNotifications.size();
for (int i=0; i<N; i++) {
Entry ent = activeNotifications.get(i);
+ if (ent.row.isDismissed() || ent.row.isRemoved()) {
+ // we don't want to update removed notifications because they could
+ // temporarily become children if they were isolated before.
+ continue;
+ }
int vis = ent.notification.getNotification().visibility;
int userId = ent.notification.getUserId();
@@ -1847,6 +1850,7 @@
for (int i=0; i<toShow.size(); i++) {
View v = toShow.get(i);
if (v.getParent() == null) {
+ mVisualStabilityManager.notifyViewAddition(v);
mStackScroller.addView(v);
}
}
@@ -1868,12 +1872,17 @@
if (child != targetChild) {
// Oops, wrong notification at this position. Put the right one
// here and advance both lists.
- mStackScroller.changeViewPosition(targetChild, i);
+ if (mVisualStabilityManager.canReorderNotification(targetChild)) {
+ mStackScroller.changeViewPosition(targetChild, i);
+ } else {
+ mVisualStabilityManager.addReorderingAllowedCallback(this);
+ }
}
j++;
}
+ mVisualStabilityManager.onReorderingFinished();
// clear the map again for the next usage
mTmpChildOrderMap.clear();
@@ -1920,13 +1929,14 @@
childIndex++) {
ExpandableNotificationRow childView = orderedChildren.get(childIndex);
if (children == null || !children.contains(childView)) {
+ mVisualStabilityManager.notifyViewAddition(childView);
parent.addChildNotification(childView, childIndex);
mStackScroller.notifyGroupChildAdded(childView);
}
}
// Finally after removing and adding has been beformed we can apply the order.
- orderChanged |= parent.applyChildOrder(orderedChildren);
+ orderChanged |= parent.applyChildOrder(orderedChildren, mVisualStabilityManager, this);
}
if (orderChanged) {
mStackScroller.generateChildOrderChangedEvent();
@@ -2003,7 +2013,7 @@
}
private void updateSpeedBumpIndex() {
- int speedBumpIndex = -1;
+ int speedBumpIndex = 0;
int currentIndex = 0;
final int N = mStackScroller.getChildCount();
for (int i = 0; i < N; i++) {
@@ -2012,17 +2022,12 @@
continue;
}
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- if (mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
- speedBumpIndex = currentIndex;
- break;
- }
currentIndex++;
+ if (!mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
+ speedBumpIndex = currentIndex;
+ }
}
- boolean noAmbient = false;
- if (speedBumpIndex == -1) {
- speedBumpIndex = currentIndex;
- noAmbient = true;
- }
+ boolean noAmbient = speedBumpIndex == N;
mStackScroller.updateSpeedBumpIndex(speedBumpIndex, noAmbient);
}
@@ -2690,7 +2695,7 @@
public void setPanelExpanded(boolean isExpanded) {
mStatusBarWindowManager.setPanelExpanded(isExpanded);
-
+ mVisualStabilityManager.setPanelExpanded(isExpanded);
if (isExpanded && getBarState() != StatusBarState.KEYGUARD) {
if (DEBUG) {
Log.v(TAG, "clearing notification effects from setPanelExpanded");
@@ -2728,6 +2733,11 @@
return mDozeScrimController.isPulsing();
}
+ @Override
+ public void onReorderingAllowed() {
+ updateNotifications();
+ }
+
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
@@ -2952,7 +2962,6 @@
mNotificationPanel.closeQs();
mExpandedVisible = false;
-
visibilityChanged(false);
// Shrink the window to the size of the status bar only
@@ -4907,6 +4916,7 @@
mWakeUpComingFromTouch = false;
mWakeUpTouchLocation = null;
mStackScroller.setAnimationsEnabled(false);
+ mVisualStabilityManager.setScreenOn(false);
updateVisibleToUser();
if (mLaunchCameraOnFinishedGoingToSleep) {
mLaunchCameraOnFinishedGoingToSleep = false;
@@ -4925,6 +4935,7 @@
public void onStartedWakingUp() {
mDeviceInteractive = true;
mStackScroller.setAnimationsEnabled(true);
+ mVisualStabilityManager.setScreenOn(true);
mNotificationPanel.setTouchDisabled(false);
updateVisibleToUser();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 944495e..517551d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -35,7 +35,7 @@
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.ViewState;
/**
@@ -43,7 +43,7 @@
* security method gets shown).
*/
public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
- HeadsUpManager.OnHeadsUpChangedListener {
+ OnHeadsUpChangedListener {
public static final long ANIMATION_DURATION = 220;
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
= new PathInterpolator(0f, 0, 0.7f, 1f);