summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adrian Roos <roosa@google.com> 2017-01-18 19:34:34 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-01-18 19:34:38 +0000
commit64f13a56a404748bfea590a002663f991192da71 (patch)
tree8afef1bd7a7ac9e42166e7814b74749ba606ca66
parentb7a77d24a68accc30c45890d47c5da7f00cc2d00 (diff)
parent4b820e4e5e0404adbf9f9678b79fa7e988e3e597 (diff)
Merge changes Ib6de3aa3,Idc46d1b2,I889e3864,I9a50ee57,I411f08ae, ...
* changes: AOD: Use heads-up state instead of buzzBeepBlinked AOD: Do not animate shelf icons when changing ambientness AOD: Show ambient versions of notifications AoD: Reposition shelf under clock AoD: Adjust shelf, only show top notification AoD: Adjust clock layout
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java19
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java133
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java24
18 files changed, 262 insertions, 82 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index e1657c7dacc2..f8f4f2a8b8fc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -29,6 +29,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.TextClock;
import android.widget.TextView;
@@ -48,6 +49,7 @@ public class KeyguardStatusView extends GridLayout {
private TextClock mDateView;
private TextClock mClockView;
private TextView mOwnerInfo;
+ private ViewGroup mClockContainer;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -105,6 +107,7 @@ public class KeyguardStatusView extends GridLayout {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ mClockContainer = (ViewGroup) findViewById(R.id.keyguard_clock_container);
mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
mDateView = (TextClock) findViewById(R.id.date_view);
mClockView = (TextClock) findViewById(R.id.clock_view);
@@ -167,6 +170,11 @@ public class KeyguardStatusView extends GridLayout {
}
}
+ public int getClockBottom() {
+ return mClockView.getBottom() +
+ ((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin;
+ }
+
public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
if (info == null) {
return "";
@@ -260,4 +268,15 @@ public class KeyguardStatusView extends GridLayout {
cacheKey = key;
}
}
+
+ public void setDark(boolean dark) {
+ final int N = mClockContainer.getChildCount();
+ for (int i = 0; i < N; i++) {
+ View child = mClockContainer.getChildAt(i);
+ if (child == mClockView) {
+ continue;
+ }
+ child.setAlpha(dark ? 0 : 1);
+ }
+ }
}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 78d211f33f37..6ffdbcb9380e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -75,6 +75,9 @@
<!-- Height of a large notification in the status bar -->
<dimen name="notification_max_height">284dp</dimen>
+ <!-- Height of an ambient notification on ambient display -->
+ <dimen name="notification_ambient_height">400dp</dimen>
+
<!-- Height of a heads up notification in the status bar for legacy custom views -->
<dimen name="notification_max_heads_up_height_legacy">128dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index e081b53ffda3..00d229887004 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -37,7 +37,7 @@ public interface DozeHost {
interface Callback {
default void onNewNotifications() {}
- default void onBuzzBeepBlinked() {}
+ default void onNotificationHeadsUp() {}
default void onNotificationLight(boolean on) {}
default void onPowerSaveChanged(boolean active) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 84b22ea93b81..db5a3921db9d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -309,7 +309,7 @@ public class DozeTriggers implements DozeMachine.Part {
private DozeHost.Callback mHostCallback = new DozeHost.Callback() {
@Override
- public void onBuzzBeepBlinked() {
+ public void onNotificationHeadsUp() {
onNotification();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index e39c64e9262a..faf143e098fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1524,6 +1524,7 @@ public abstract class BaseStatusBar extends SystemUI implements
final RemoteViews bigContentView = entry.cachedBigContentView;
final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
final RemoteViews publicContentView = entry.cachedPublicContentView;
+ final RemoteViews ambientContentView = entry.cachedAmbientContentView;
if (contentView == null) {
Log.v(TAG, "no contentView for: " + sbn.getNotification());
@@ -1604,6 +1605,7 @@ public abstract class BaseStatusBar extends SystemUI implements
View bigContentViewLocal = null;
View headsUpContentViewLocal = null;
View publicViewLocal = null;
+ View ambientViewLocal = null;
try {
contentViewLocal = contentView.apply(
sbn.getPackageContext(mContext),
@@ -1626,6 +1628,11 @@ public abstract class BaseStatusBar extends SystemUI implements
sbn.getPackageContext(mContext),
contentContainerPublic, mOnClickHandler);
}
+ if (ambientContentView != null) {
+ ambientViewLocal = ambientContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer, mOnClickHandler);
+ }
if (contentViewLocal != null) {
contentViewLocal.setIsRootNamespace(true);
@@ -1643,6 +1650,11 @@ public abstract class BaseStatusBar extends SystemUI implements
publicViewLocal.setIsRootNamespace(true);
contentContainerPublic.setContractedChild(publicViewLocal);
}
+
+ if (ambientViewLocal != null) {
+ ambientViewLocal.setIsRootNamespace(true);
+ contentContainer.setAmbientChild(ambientViewLocal);
+ }
}
catch (RuntimeException e) {
final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
@@ -2139,6 +2151,7 @@ public abstract class BaseStatusBar extends SystemUI implements
row.setOnKeyguard(false);
row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
}
+ entry.row.setShowAmbient(isDozing());
int userId = entry.notification.getUserId();
boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
entry.notification) && !entry.row.isRemoved();
@@ -2176,6 +2189,10 @@ public abstract class BaseStatusBar extends SystemUI implements
mStackScroller.changeViewPosition(mNotificationShelf, mStackScroller.getChildCount() - 3);
}
+ public boolean isDozing() {
+ return false;
+ }
+
public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
return mShowLockscreenNotifications && !mNotificationData.isAmbient(sbn.getKey());
}
@@ -2388,7 +2405,7 @@ public abstract class BaseStatusBar extends SystemUI implements
Log.d(TAG, "failed to query dream manager", e);
}
- if (!inUse) {
+ if (!inUse && !isDozing()) {
if (DEBUG) {
Log.d(TAG, "No peeking: not in use: " + sbn.getKey());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 173a110aaa47..93c48f86cec9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -74,6 +74,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
private int mMaxHeadsUpHeight;
private int mNotificationMinHeight;
private int mNotificationMaxHeight;
+ private int mNotificationAmbientHeight;
private int mIncreasedPaddingBetweenElements;
/** Does this row contain layouts that can adapt to row expansion */
@@ -197,6 +198,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
private float mContentTransformationAmount;
private boolean mIconsVisible = true;
private boolean mAboveShelf;
+ private boolean mShowAmbient;
private boolean mIsLastChild;
private Runnable mOnDismissRunnable;
@@ -326,7 +328,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
!= com.android.internal.R.id.status_bar_latest_event_content;
int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
: mMaxHeadsUpHeight;
- layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
+ layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight,
+ mNotificationAmbientHeight);
}
public StatusBarNotification getStatusBarNotification() {
@@ -954,6 +957,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
+ mNotificationAmbientHeight = getFontScaledHeight(R.dimen.notification_ambient_height);
mMaxHeadsUpHeightLegacy = getFontScaledHeight(
R.dimen.notification_max_heads_up_height_legacy);
mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
@@ -1353,6 +1357,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return mGuts.getHeight();
} else if ((isChildInGroup() && !isGroupExpanded())) {
return mPrivateLayout.getMinHeight();
+ } else if (mShowAmbient) {
+ return getAmbientHeight();
} else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
return getMinHeight();
} else if (mIsSummaryWithChildren && !mOnKeyguard) {
@@ -1683,6 +1689,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return showingLayout.getMinHeight();
}
+ private int getAmbientHeight() {
+ NotificationContentView showingLayout = getShowingLayout();
+ return showingLayout.getAmbientChild() != null
+ ? showingLayout.getAmbientChild().getHeight()
+ : getCollapsedHeight();
+ }
+
@Override
public int getCollapsedHeight() {
if (mIsSummaryWithChildren && !mShowingPublic) {
@@ -1879,6 +1892,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf);
}
+ public void setShowAmbient(boolean showAmbient) {
+ if (showAmbient != mShowAmbient) {
+ mShowAmbient = showAmbient;
+ notifyHeightChanged(false /* needsAnimation */);
+ }
+ }
+
public void setAboveShelf(boolean aboveShelf) {
mAboveShelf = aboveShelf;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 9ce211539ad9..077303a29105 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -52,6 +52,7 @@ public class NotificationContentView extends FrameLayout {
private static final int VISIBLE_TYPE_EXPANDED = 1;
private static final int VISIBLE_TYPE_HEADSUP = 2;
private static final int VISIBLE_TYPE_SINGLELINE = 3;
+ private static final int VISIBLE_TYPE_AMBIENT = 4;
public static final int UNDEFINED = -1;
private final Rect mClipBounds = new Rect();
@@ -62,6 +63,7 @@ public class NotificationContentView extends FrameLayout {
private View mExpandedChild;
private View mHeadsUpChild;
private HybridNotificationView mSingleLineView;
+ private View mAmbientChild;
private RemoteInputView mExpandedRemoteInput;
private RemoteInputView mHeadsUpRemoteInput;
@@ -69,6 +71,7 @@ public class NotificationContentView extends FrameLayout {
private NotificationViewWrapper mContractedWrapper;
private NotificationViewWrapper mExpandedWrapper;
private NotificationViewWrapper mHeadsUpWrapper;
+ private NotificationViewWrapper mAmbientWrapper;
private HybridGroupManager mHybridGroupManager;
private int mClipTopAmount;
private int mContentHeight;
@@ -81,6 +84,7 @@ public class NotificationContentView extends FrameLayout {
private int mSmallHeight;
private int mHeadsUpHeight;
private int mNotificationMaxHeight;
+ private int mNotificationAmbientHeight;
private StatusBarNotification mStatusBarNotification;
private NotificationGroupManager mGroupManager;
private RemoteInputController mRemoteInputController;
@@ -136,10 +140,12 @@ public class NotificationContentView extends FrameLayout {
reset();
}
- public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
+ public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight,
+ int ambientHeight) {
mSmallHeight = smallHeight;
mHeadsUpHeight = headsUpMaxHeight;
mNotificationMaxHeight = maxHeight;
+ mNotificationAmbientHeight = ambientHeight;
}
@Override
@@ -215,6 +221,17 @@ public class NotificationContentView extends FrameLayout {
MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight());
}
+ if (mAmbientChild != null) {
+ int size = Math.min(maxSize, mNotificationAmbientHeight);
+ ViewGroup.LayoutParams layoutParams = mAmbientChild.getLayoutParams();
+ if (layoutParams.height >= 0) {
+ // An actual height is set
+ size = Math.min(size, layoutParams.height);
+ }
+ mAmbientChild.measure(widthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
+ maxChildHeight = Math.max(maxChildHeight, mAmbientChild.getMeasuredHeight());
+ }
int ownHeight = Math.min(maxChildHeight, maxSize);
setMeasuredDimension(width, ownHeight);
}
@@ -339,6 +356,10 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpChild;
}
+ public View getAmbientChild() {
+ return mAmbientChild;
+ }
+
public void setContractedChild(View child) {
if (mContractedChild != null) {
mContractedChild.animate().cancel();
@@ -373,6 +394,17 @@ public class NotificationContentView extends FrameLayout {
mContainingNotification);
}
+ public void setAmbientChild(View child) {
+ if (mAmbientChild != null) {
+ mAmbientChild.animate().cancel();
+ removeView(mAmbientChild);
+ }
+ addView(child);
+ mAmbientChild = child;
+ mAmbientWrapper = NotificationViewWrapper.wrap(getContext(), child,
+ mContainingNotification);
+ }
+
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -447,6 +479,11 @@ public class NotificationContentView extends FrameLayout {
com.android.internal.R.dimen.notification_action_list_height);
}
+ if (isVisibleOrTransitioning(VISIBLE_TYPE_AMBIENT)) {
+ return mContractedChild.getHeight() + mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_action_list_height);
+ }
+
// Transition between heads-up & expanded, or pinned.
if (mHeadsUpChild != null && mExpandedChild != null) {
boolean transitioningBetweenHunAndExpanded =
@@ -651,39 +688,23 @@ public class NotificationContentView extends FrameLayout {
}
private void forceUpdateVisibilities() {
- boolean contractedVisible = mVisibleType == VISIBLE_TYPE_CONTRACTED
- || mTransformationStartVisibleType == VISIBLE_TYPE_CONTRACTED;
- boolean expandedVisible = mVisibleType == VISIBLE_TYPE_EXPANDED
- || mTransformationStartVisibleType == VISIBLE_TYPE_EXPANDED;
- boolean headsUpVisible = mVisibleType == VISIBLE_TYPE_HEADSUP
- || mTransformationStartVisibleType == VISIBLE_TYPE_HEADSUP;
- boolean singleLineVisible = mVisibleType == VISIBLE_TYPE_SINGLELINE
- || mTransformationStartVisibleType == VISIBLE_TYPE_SINGLELINE;
- if (!contractedVisible) {
- mContractedChild.setVisibility(View.INVISIBLE);
- } else {
- mContractedWrapper.setVisible(true);
- }
- if (mExpandedChild != null) {
- if (!expandedVisible) {
- mExpandedChild.setVisibility(View.INVISIBLE);
- } else {
- mExpandedWrapper.setVisible(true);
- }
- }
- if (mHeadsUpChild != null) {
- if (!headsUpVisible) {
- mHeadsUpChild.setVisibility(View.INVISIBLE);
- } else {
- mHeadsUpWrapper.setVisible(true);
- }
+ forceUpdateVisibility(VISIBLE_TYPE_CONTRACTED, mContractedChild, mContractedWrapper);
+ forceUpdateVisibility(VISIBLE_TYPE_EXPANDED, mExpandedChild, mExpandedWrapper);
+ forceUpdateVisibility(VISIBLE_TYPE_HEADSUP, mHeadsUpChild, mHeadsUpWrapper);
+ forceUpdateVisibility(VISIBLE_TYPE_SINGLELINE, mSingleLineView, mSingleLineView);
+ forceUpdateVisibility(VISIBLE_TYPE_AMBIENT, mAmbientChild, mAmbientWrapper);
+ }
+
+ private void forceUpdateVisibility(int type, View view, TransformableView wrapper) {
+ if (view == null) {
+ return;
}
- if (mSingleLineView != null) {
- if (!singleLineVisible) {
- mSingleLineView.setVisibility(View.INVISIBLE);
- } else {
- mSingleLineView.setVisible(true);
- }
+ boolean visible = mVisibleType == type
+ || mTransformationStartVisibleType == type;
+ if (!visible) {
+ view.setVisibility(INVISIBLE);
+ } else {
+ wrapper.setVisible(true);
}
}
@@ -717,19 +738,22 @@ public class NotificationContentView extends FrameLayout {
}
private void updateViewVisibilities(int visibleType) {
- boolean contractedVisible = visibleType == VISIBLE_TYPE_CONTRACTED;
- mContractedWrapper.setVisible(contractedVisible);
- if (mExpandedChild != null) {
- boolean expandedVisible = visibleType == VISIBLE_TYPE_EXPANDED;
- mExpandedWrapper.setVisible(expandedVisible);
- }
- if (mHeadsUpChild != null) {
- boolean headsUpVisible = visibleType == VISIBLE_TYPE_HEADSUP;
- mHeadsUpWrapper.setVisible(headsUpVisible);
- }
- if (mSingleLineView != null) {
- boolean singleLineVisible = visibleType == VISIBLE_TYPE_SINGLELINE;
- mSingleLineView.setVisible(singleLineVisible);
+ updateViewVisibility(visibleType, VISIBLE_TYPE_CONTRACTED,
+ mContractedChild, mContractedWrapper);
+ updateViewVisibility(visibleType, VISIBLE_TYPE_EXPANDED,
+ mExpandedChild, mExpandedWrapper);
+ updateViewVisibility(visibleType, VISIBLE_TYPE_HEADSUP,
+ mHeadsUpChild, mHeadsUpWrapper);
+ updateViewVisibility(visibleType, VISIBLE_TYPE_SINGLELINE,
+ mSingleLineView, mSingleLineView);
+ updateViewVisibility(visibleType, VISIBLE_TYPE_AMBIENT,
+ mAmbientChild, mAmbientWrapper);
+ }
+
+ private void updateViewVisibility(int visibleType, int type, View view,
+ TransformableView wrapper) {
+ if (view != null) {
+ wrapper.setVisible(visibleType == type);
}
}
@@ -779,6 +803,8 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpWrapper;
case VISIBLE_TYPE_SINGLELINE:
return mSingleLineView;
+ case VISIBLE_TYPE_AMBIENT:
+ return mAmbientWrapper;
default:
return mContractedWrapper;
}
@@ -796,6 +822,8 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpChild;
case VISIBLE_TYPE_SINGLELINE:
return mSingleLineView;
+ case VISIBLE_TYPE_AMBIENT:
+ return mAmbientChild;
default:
return mContractedChild;
}
@@ -809,6 +837,8 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpWrapper;
case VISIBLE_TYPE_CONTRACTED:
return mContractedWrapper;
+ case VISIBLE_TYPE_AMBIENT:
+ return mAmbientWrapper;
default:
return null;
}
@@ -818,6 +848,10 @@ public class NotificationContentView extends FrameLayout {
* @return one of the static enum types in this view, calculated form the current state
*/
public int calculateVisibleType() {
+ if (mDark && !mIsChildInGroup) {
+ // TODO: Handle notification groups
+ return VISIBLE_TYPE_AMBIENT;
+ }
if (mUserExpanding) {
int height = !mIsChildInGroup || isGroupExpanded()
|| mContainingNotification.isExpanded(true /* allowOnKeyguard */)
@@ -890,6 +924,7 @@ public class NotificationContentView extends FrameLayout {
if (mSingleLineView != null && (mVisibleType == VISIBLE_TYPE_SINGLELINE || !dark)) {
mSingleLineView.setDark(dark, fade, delay);
}
+ selectLayout(!dark && fade /* animate */, false /* force */);
}
public void setHeadsUp(boolean headsUp) {
@@ -942,6 +977,9 @@ public class NotificationContentView extends FrameLayout {
if (mHeadsUpChild != null) {
mHeadsUpWrapper.notifyContentUpdated(entry.notification);
}
+ if (mAmbientChild != null) {
+ mAmbientWrapper.notifyContentUpdated(entry.notification);
+ }
updateShowingLegacyBackground();
mForceSelectNextLayout = true;
setDark(mDark, false /* animate */, 0 /* delay */);
@@ -1128,6 +1166,9 @@ public class NotificationContentView extends FrameLayout {
if (header == null && mHeadsUpChild != null) {
header = mHeadsUpWrapper.getNotificationHeader();
}
+ if (header == null && mAmbientChild != null) {
+ header = mAmbientWrapper.getNotificationHeader();
+ }
return header;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c06e6394e197..458daf162b24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -67,6 +67,7 @@ public class NotificationData {
public RemoteViews cachedBigContentView;
public RemoteViews cachedHeadsUpContentView;
public RemoteViews cachedPublicContentView;
+ public RemoteViews cachedAmbientContentView;
public CharSequence remoteInputText;
private int mCachedContrastColor = COLOR_INVALID;
private int mCachedContrastColorIsFor = COLOR_INVALID;
@@ -126,6 +127,8 @@ public class NotificationData {
updatedNotificationBuilder.createHeadsUpContentView();
final RemoteViews newPublicNotification
= updatedNotificationBuilder.makePublicContentView();
+ final RemoteViews newAmbientNotification
+ = updatedNotificationBuilder.makeAmbientNotification();
boolean sameCustomView = Objects.equals(
notification.getNotification().extras.getBoolean(
@@ -136,11 +139,13 @@ public class NotificationData {
&& compareRemoteViews(cachedBigContentView, newBigContentView)
&& compareRemoteViews(cachedHeadsUpContentView, newHeadsUpContentView)
&& compareRemoteViews(cachedPublicContentView, newPublicNotification)
+ && compareRemoteViews(cachedAmbientContentView, newAmbientNotification)
&& sameCustomView;
cachedPublicContentView = newPublicNotification;
cachedHeadsUpContentView = newHeadsUpContentView;
cachedBigContentView = newBigContentView;
cachedContentView = newContentView;
+ cachedAmbientContentView = newAmbientNotification;
} else {
final Notification.Builder builder
= Notification.Builder.recoverBuilder(ctx, notification.getNotification());
@@ -149,6 +154,7 @@ public class NotificationData {
cachedBigContentView = builder.createBigContentView();
cachedHeadsUpContentView = builder.createHeadsUpContentView();
cachedPublicContentView = builder.makePublicContentView();
+ cachedAmbientContentView = builder.makeAmbientNotification();
applyInPlace = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 64c49496ee9c..e8e9d4ebec6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -129,6 +129,7 @@ public class NotificationShelf extends ActivatableNotificationView {
} else {
mViewInvertHelper.update(dark);
}
+ mShelfIcons.setAmbient(dark);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 7ca2df99d76e..b984c0ba8e3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -116,8 +116,10 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
private void resolveTemplateViews(StatusBarNotification notification) {
mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon);
- mPicture.setTag(ImageTransformState.ICON_TAG,
- notification.getNotification().getLargeIcon());
+ if (mPicture != null) {
+ mPicture.setTag(ImageTransformState.ICON_TAG,
+ notification.getNotification().getLargeIcon());
+ }
mTitle = (TextView) mView.findViewById(com.android.internal.R.id.title);
mText = (TextView) mView.findViewById(com.android.internal.R.id.text);
final View progress = mView.findViewById(com.android.internal.R.id.progress);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 5047041745d8..a4e591625a95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -39,6 +39,7 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener {
private VisibilityLocationProvider mVisibilityLocationProvider;
private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
private ArraySet<View> mAddedChildren = new ArraySet<>();
+ private boolean mPulsing;
/**
* Add a callback to invoke when reordering is allowed again.
@@ -67,8 +68,16 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener {
updateReorderingAllowed();
}
+ /**
+ * @param pulsing whether we are currently pulsing for ambient display.
+ */
+ public void setPulsing(boolean pulsing) {
+ mPulsing = pulsing;
+ updateReorderingAllowed();
+ }
+
private void updateReorderingAllowed() {
- boolean reorderingAllowed = !mScreenOn || !mPanelExpanded;
+ boolean reorderingAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
boolean changed = reorderingAllowed && !mReorderingAllowed;
mReorderingAllowed = reorderingAllowed;
if (changed) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 01ffe01d0d64..b78f7482b9f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -26,6 +26,7 @@ import android.util.Log;
import android.view.View;
import android.view.animation.Interpolator;
+import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.Interpolators;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
@@ -41,7 +42,9 @@ public class DozeScrimController {
private final Handler mHandler = new Handler();
private final ScrimController mScrimController;
+ private final Context mContext;
private final View mStackScroller;
+ private final NotificationPanelView mNotificationPanelView;
private boolean mDozing;
private DozeHost.PulseCallback mPulseCallback;
@@ -52,10 +55,12 @@ public class DozeScrimController {
private float mBehindTarget;
public DozeScrimController(ScrimController scrimController, Context context,
- View stackScroller) {
+ View stackScroller, NotificationPanelView notificationPanelView) {
+ mContext = context;
mStackScroller = stackScroller;
mScrimController = scrimController;
mDozeParameters = new DozeParameters(context);
+ mNotificationPanelView = notificationPanelView;
}
public void setDozing(boolean dozing, boolean animate) {
@@ -65,10 +70,7 @@ public class DozeScrimController {
abortAnimations();
mScrimController.setDozeBehindAlpha(1f);
mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
- if (mDozeParameters.getAlwaysOn()) {
- mStackScroller.setAlpha(0f);
- mHandler.postDelayed(() -> mStackScroller.setAlpha(0f), 30);
- }
+ mNotificationPanelView.setDark(true);
} else {
cancelPulsing();
if (animate) {
@@ -83,9 +85,8 @@ public class DozeScrimController {
mScrimController.setDozeBehindAlpha(0f);
mScrimController.setDozeInFrontAlpha(0f);
}
- if (mDozeParameters.getAlwaysOn()) {
- mStackScroller.setAlpha(1f);
- }
+ // TODO: animate
+ mNotificationPanelView.setDark(false);
}
}
@@ -123,9 +124,6 @@ public class DozeScrimController {
if (isPulsing()) {
final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
|| mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
- if (mDozeParameters.getAlwaysOn()) {
- mStackScroller.setAlpha(1f);
- }
startScrimAnimation(true /* inFront */, 0f,
mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
@@ -291,9 +289,6 @@ public class DozeScrimController {
@Override
public void run() {
if (DEBUG) Log.d(TAG, "Pulse out finished");
- if (mDozeParameters.getAlwaysOn()) {
- mStackScroller.setAlpha(0f);
- }
DozeLog.tracePulseFinish();
// Signal that the pulse is all finished so we can turn the screen off now.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 70beac8ea522..c78ec836fbc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -68,6 +68,8 @@ public class KeyguardClockPositionAlgorithm {
}
private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
+ private int mClockBottom;
+ private boolean mDark;
/**
* Refreshes the dimension values.
@@ -86,7 +88,8 @@ public class KeyguardClockPositionAlgorithm {
}
public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
- int notificationCount, int height, int keyguardStatusHeight, float emptyDragAmount) {
+ int notificationCount, int height, int keyguardStatusHeight, float emptyDragAmount,
+ int clockBottom, boolean dark) {
mMaxKeyguardNotifications = maxKeyguardNotifications;
mMaxPanelHeight = maxPanelHeight;
mExpandedHeight = expandedHeight;
@@ -94,6 +97,8 @@ public class KeyguardClockPositionAlgorithm {
mHeight = height;
mKeyguardStatusHeight = keyguardStatusHeight;
mEmptyDragAmount = emptyDragAmount;
+ mClockBottom = clockBottom;
+ mDark = dark;
}
public float getMinStackScrollerPadding(int height, int keyguardStatusHeight) {
@@ -115,6 +120,9 @@ public class KeyguardClockPositionAlgorithm {
result.clockY,
y + getClockNotificationsPadding() + mKeyguardStatusHeight);
result.clockAlpha = getClockAlpha(result.clockScale);
+ if (mDark) {
+ result.stackScrollerPadding = mClockBottom + y;
+ }
}
private float getClockScale(int notificationPadding, int clockY, int startPadding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 9fb59801f8f0..c25a45cc37e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -22,9 +22,7 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
-import android.util.Property;
import android.view.View;
-import android.view.animation.Interpolator;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -32,7 +30,6 @@ import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.stack.AnimationFilter;
import com.android.systemui.statusbar.stack.AnimationProperties;
-import com.android.systemui.statusbar.stack.HeadsUpAppearInterpolator;
import com.android.systemui.statusbar.stack.ViewState;
import java.util.HashMap;
@@ -98,6 +95,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private int mActualLayoutWidth = NO_VALUE;
private float mActualPaddingEnd = NO_VALUE;
private float mActualPaddingStart = NO_VALUE;
+ private boolean mCentered;
private boolean mChangingViewPositions;
private int mAddAnimationStartIndex = -1;
private int mCannedAnimationStartIndex = -1;
@@ -105,6 +103,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private int mIconSize;
private float mOpenedAmount = 0.0f;
private float mVisualOverflowAdaption;
+ private boolean mDisallowNextAnimation;
public NotificationIconContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -165,6 +164,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
mAddAnimationStartIndex = -1;
mCannedAnimationStartIndex = -1;
+ mDisallowNextAnimation = false;
}
@Override
@@ -310,6 +310,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
numDots++;
}
}
+ if (mCentered && translationX < getLayoutEnd()) {
+ float delta = (getLayoutEnd() - translationX) / 2;
+ for (int i = 0; i < childCount; i++) {
+ View view = getChildAt(i);
+ IconState iconState = mIconStates.get(view);
+ iconState.xTranslation += delta;
+ }
+ }
+
if (isLayoutRtl()) {
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
@@ -379,6 +388,11 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mChangingViewPositions = changingViewPositions;
}
+ public void setAmbient(boolean ambient) {
+ mCentered = ambient;
+ mDisallowNextAnimation = true;
+ }
+
public IconState getIconState(StatusBarIconView icon) {
return mIconStates.get(icon);
}
@@ -469,7 +483,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
animate = true;
}
icon.setVisibleState(visibleState);
- if (animate) {
+ if (animate && !mDisallowNextAnimation) {
animateTo(icon, animationProperties);
} else {
super.applyToView(view);
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 d48819a901ab..3bdd5e5c6db9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -211,6 +211,7 @@ public class NotificationPanelView extends PanelView implements
private boolean mOpening;
private int mIndicationBottomPadding;
private boolean mIsFullWidth;
+ private boolean mDark;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -391,7 +392,9 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.getNotGoneChildCount(),
getHeight(),
mKeyguardStatusView.getHeight(),
- mEmptyDragAmount);
+ mEmptyDragAmount,
+ mKeyguardStatusView.getClockBottom(),
+ mDark);
mClockPositionAlgorithm.run(mClockPositionResult);
if (animate || mClockAnimator != null) {
startClockAnimation(mClockPositionResult.clockY);
@@ -2453,4 +2456,10 @@ public class NotificationPanelView extends PanelView implements
}
}
};
+
+ public void setDark(boolean dark) {
+ mDark = dark;
+ mKeyguardStatusView.setDark(dark);
+ positionClockAndNotifications();
+ }
}
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 5998ed237628..9f12ca7fcd9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -74,7 +74,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
@@ -879,7 +878,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mHeadsUpManager.addListener(mScrimController);
mStackScroller.setScrimController(mScrimController);
mStatusBarView.setScrimController(mScrimController);
- mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller);
+ mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller,
+ mNotificationPanel);
// Other icons
mLocationController = new LocationControllerImpl(mContext,
@@ -2401,6 +2401,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return getBarState() == StatusBarState.KEYGUARD;
}
+ @Override
public boolean isDozing() {
return mDozing;
}
@@ -2487,6 +2488,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
} else {
updateNotificationRanking(null);
+ if (isHeadsUp) {
+ mDozeServiceHost.fireNotificationHeadsUp();
+ }
}
}
@@ -2886,9 +2890,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override // CommandQueue
public void buzzBeepBlinked() {
- if (mDozeServiceHost != null) {
- mDozeServiceHost.fireBuzzBeepBlinked();
- }
}
@Override
@@ -4234,6 +4235,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mDozeScrimController.setDozing(mDozing &&
mFingerprintUnlockController.getMode()
!= FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
+ updateRowStates();
Trace.endSection();
}
@@ -4904,9 +4906,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
- public void fireBuzzBeepBlinked() {
+ public void fireNotificationHeadsUp() {
for (Callback callback : mCallbacks) {
- callback.onBuzzBeepBlinked();
+ callback.onNotificationHeadsUp();
}
}
@@ -4950,12 +4952,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void onPulseStarted() {
callback.onPulseStarted();
mStackScroller.setPulsing(true);
+ mVisualStabilityManager.setPulsing(true);
}
@Override
public void onPulseFinished() {
callback.onPulseFinished();
mStackScroller.setPulsing(false);
+ mVisualStabilityManager.setPulsing(false);
}
}, reason);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 9545fd867786..395e8f2a1d56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1883,12 +1883,16 @@ public class NotificationStackScrollLayout extends ViewGroup
float previousIncreasedAmount = 0.0f;
int numShownItems = 0;
boolean finish = false;
+ int maxDisplayedNotifications = mAmbientState.isDark()
+ ? (mPulsing ? 1 : 0)
+ : mMaxDisplayedNotifications;
+
for (int i = 0; i < getChildCount(); i++) {
ExpandableView expandableView = (ExpandableView) getChildAt(i);
if (expandableView.getVisibility() != View.GONE
&& !expandableView.hasNoContentHeight()) {
- if (mMaxDisplayedNotifications != -1
- && numShownItems >= mMaxDisplayedNotifications) {
+ if (maxDisplayedNotifications != -1
+ && numShownItems >= maxDisplayedNotifications) {
expandableView = mShelf;
finish = true;
}
@@ -3486,6 +3490,8 @@ public class NotificationStackScrollLayout extends ViewGroup
updateBackground();
setWillNotDraw(false);
}
+ updateContentHeight();
+ notifyHeightChangeListener(mShelf);
}
private void setBackgroundFadeAmount(float fadeAmount) {
@@ -3921,6 +3927,8 @@ public class NotificationStackScrollLayout extends ViewGroup
public void setPulsing(boolean pulsing) {
mPulsing = pulsing;
updateNotificationAnimationStates();
+ updateContentHeight();
+ notifyHeightChangeListener(mShelf);
}
public void setFadingOut(boolean fadingOut) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java
index be6290bd41e0..76bb6c01f219 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/notification/VisualStabilityManagerTest.java
@@ -150,4 +150,28 @@ public class VisualStabilityManagerTest {
mVisualStabilityManager.onReorderingFinished();
assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
}
+
+ @Test
+ public void testPulsing() {
+ mVisualStabilityManager.setPulsing(true);
+ assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+ mVisualStabilityManager.setPulsing(false);
+ assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+ }
+
+ @Test
+ public void testReorderingAllowedChanges_Pulsing() {
+ mVisualStabilityManager.setPulsing(true);
+ assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+ mVisualStabilityManager.setPulsing(false);
+ assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+ }
+
+ @Test
+ public void testCallBackCalled_Pulsing() {
+ mVisualStabilityManager.setPulsing(true);
+ mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+ mVisualStabilityManager.setPulsing(false);
+ verify(mCallback).onReorderingAllowed();
+ }
}