Fix heads up views freeing too early.
In the previous CL, heads up views were freed while they were still
animating away. As a result, there could be a sudden shift in the view
the notification uses (most easily reproducible if you tap on a HUN with
actions as the actions disappear). This CL introduces an API to set a
a listener for when the content view becomes inactive and remove it then.
Bug: 111809944
Test: runtest systemui, manual (HUN with full screen intent, tap, see
that it goes away without visual jank)
Change-Id: Ib27bcf993f6be41aa4fde50b39817004610f5fd4
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
index 2c384d0..21a33b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
+
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
@@ -85,6 +87,7 @@
for (OnAmbientChangedListener listener : mListeners) {
listener.onAmbientStateChanged(entry, false);
}
+ entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 4a50a17..28d339a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -19,9 +19,9 @@
import static com.android.systemui.statusbar.NotificationRemoteInputManager
.FORCE_REMOTE_INPUT_HISTORY;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_AMBIENT_VIEW;
+ .FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_HEADS_UP_VIEW;
+ .FLAG_CONTENT_VIEW_HEADS_UP;
import android.annotation.Nullable;
import android.app.Notification;
@@ -458,7 +458,7 @@
*/
private void showAlertingView(NotificationData.Entry entry,
@InflationFlag int inflatedFlags) {
- if ((inflatedFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+ if ((inflatedFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
// Possible for shouldHeadsUp to change between the inflation starting and ending.
// If it does and we no longer need to heads up, we should free the view.
if (shouldHeadsUp(entry)) {
@@ -466,14 +466,14 @@
// Mark as seen immediately
setNotificationShown(entry.notification);
} else {
- entry.row.updateInflationFlag(FLAG_REINFLATE_HEADS_UP_VIEW, false);
+ entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
}
}
- if ((inflatedFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+ if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
if (shouldPulse(entry)) {
mAmbientPulseManager.showNotification(entry);
} else {
- entry.row.updateInflationFlag(FLAG_REINFLATE_AMBIENT_VIEW, false);
+ entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
}
}
}
@@ -666,8 +666,8 @@
row.setSmartActions(entry.smartActions);
row.setEntry(entry);
- row.updateInflationFlag(FLAG_REINFLATE_HEADS_UP_VIEW, shouldHeadsUp(entry));
- row.updateInflationFlag(FLAG_REINFLATE_AMBIENT_VIEW, shouldPulse(entry));
+ row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, shouldHeadsUp(entry));
+ row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, shouldPulse(entry));
row.inflateViews();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 51da868..23492aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -17,10 +17,12 @@
package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
+import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
+import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_AMBIENT_VIEW;
+ .FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_HEADS_UP_VIEW;
+ .FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater.InflationCallback;
import android.animation.Animator;
@@ -454,6 +456,33 @@
}
/**
+ * Marks a content view as freeable, setting it so that future inflations do not reinflate
+ * and ensuring that the view is freed when it is safe to remove.
+ *
+ * @param inflationFlag flag corresponding to the content view to be freed
+ */
+ public void freeContentViewWhenSafe(@InflationFlag int inflationFlag) {
+ // View should not be reinflated in the future
+ updateInflationFlag(inflationFlag, false);
+ Runnable freeViewRunnable = () ->
+ mNotificationInflater.freeNotificationView(inflationFlag);
+ switch (inflationFlag) {
+ case FLAG_CONTENT_VIEW_HEADS_UP:
+ getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_HEADSUP,
+ freeViewRunnable);
+ break;
+ case FLAG_CONTENT_VIEW_AMBIENT:
+ getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
+ freeViewRunnable);
+ getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
+ freeViewRunnable);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
* Update whether or not a content view should be inflated.
*
* @param flag the flag corresponding to the content view
@@ -607,7 +636,7 @@
headsUpHeight = mMaxHeadsUpHeight;
}
NotificationViewWrapper headsUpWrapper = layout.getVisibleWrapper(
- NotificationContentView.VISIBLE_TYPE_HEADSUP);
+ VISIBLE_TYPE_HEADSUP);
if (headsUpWrapper != null) {
headsUpHeight = Math.max(headsUpHeight, headsUpWrapper.getMinLayoutHeight());
}
@@ -642,12 +671,8 @@
if (isHeadsUp) {
mMustStayOnScreen = true;
setAboveShelf(true);
- } else {
- if (isAboveShelf() != wasAboveShelf) {
- mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
- }
- updateInflationFlag(FLAG_REINFLATE_HEADS_UP_VIEW, false);
- mNotificationInflater.freeNotificationView(FLAG_REINFLATE_HEADS_UP_VIEW);
+ } else if (isAboveShelf() != wasAboveShelf) {
+ mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
}
}
@@ -657,10 +682,6 @@
public void setAmbientPulsing(boolean isAmbientPulsing) {
mIsAmbientPulsing = isAmbientPulsing;
- if (!isAmbientPulsing) {
- updateInflationFlag(FLAG_REINFLATE_AMBIENT_VIEW, false);
- mNotificationInflater.freeNotificationView(FLAG_REINFLATE_AMBIENT_VIEW);
- }
}
public void setGroupManager(NotificationGroupManager groupManager) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 700dfa1..7856451 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -23,6 +23,7 @@
import android.graphics.Rect;
import android.os.Build;
import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
@@ -108,6 +109,10 @@
private NotificationGroupManager mGroupManager;
private RemoteInputController mRemoteInputController;
private Runnable mExpandedVisibleListener;
+ /**
+ * List of listeners for when content views become inactive (i.e. not the showing view).
+ */
+ private final ArrayMap<View, Runnable> mOnContentViewInactiveListeners = new ArrayMap<>();
private final ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
= new ViewTreeObserver.OnPreDrawListener() {
@@ -1171,6 +1176,7 @@
public void onNotificationUpdated(NotificationData.Entry entry) {
mStatusBarNotification = entry.notification;
+ mOnContentViewInactiveListeners.clear();
mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
updateAllSingleLineViews();
if (mContractedChild != null) {
@@ -1628,6 +1634,58 @@
fireExpandedVisibleListenerIfVisible();
}
+ /**
+ * Set a one-shot listener to run when a given content view becomes inactive.
+ *
+ * @param visibleType visible type corresponding to the content view to listen
+ * @param listener runnable to run once when the content view becomes inactive
+ */
+ public void performWhenContentInactive(int visibleType, Runnable listener) {
+ View view = getViewForVisibleType(visibleType);
+ // View is already inactive
+ if (view == null || isContentViewInactive(visibleType)) {
+ listener.run();
+ return;
+ }
+ mOnContentViewInactiveListeners.put(view, listener);
+ }
+
+ /**
+ * Whether or not the content view is inactive. This means it should not be visible
+ * or the showing content as removing it would cause visual jank.
+ *
+ * @param visibleType visible type corresponding to the content view to be removed
+ * @return true if the content view is inactive, false otherwise
+ */
+ public boolean isContentViewInactive(int visibleType) {
+ View view = getViewForVisibleType(visibleType);
+ return isContentViewInactive(view);
+ }
+
+ /**
+ * Whether or not the content view is inactive.
+ *
+ * @param view view to see if its inactive
+ * @return true if the view is inactive, false o/w
+ */
+ private boolean isContentViewInactive(View view) {
+ if (view == null) {
+ return true;
+ }
+ return view.getVisibility() != VISIBLE && getViewForVisibleType(mVisibleType) != view;
+ }
+
+ @Override
+ protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
+ super.onChildVisibilityChanged(child, oldVisibility, newVisibility);
+ if (isContentViewInactive(child)) {
+ Runnable listener = mOnContentViewInactiveListeners.remove(child);
+ if (listener != null) {
+ listener.run();
+ }
+ }
+ }
+
public void setIsLowPriority(boolean isLowPriority) {
mIsLowPriority = isLowPriority;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
index 7ded594..ea1892b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.notification.row;
+import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
+import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.Notification;
@@ -59,54 +62,54 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true,
- prefix = {"FLAG_REINFLATE_"},
+ prefix = {"FLAG_CONTENT_VIEW_"},
value = {
- FLAG_REINFLATE_CONTENT_VIEW,
- FLAG_REINFLATE_EXPANDED_VIEW,
- FLAG_REINFLATE_HEADS_UP_VIEW,
- FLAG_REINFLATE_AMBIENT_VIEW,
- FLAG_REINFLATE_PUBLIC_VIEW,
- FLAG_REINFLATE_ALL})
+ FLAG_CONTENT_VIEW_CONTRACTED,
+ FLAG_CONTENT_VIEW_EXPANDED,
+ FLAG_CONTENT_VIEW_HEADS_UP,
+ FLAG_CONTENT_VIEW_AMBIENT,
+ FLAG_CONTENT_VIEW_PUBLIC,
+ FLAG_CONTENT_VIEW_ALL})
public @interface InflationFlag {}
/**
* The default, contracted view. Seen when the shade is pulled down and in the lock screen
* if there is no worry about content sensitivity.
*/
- public static final int FLAG_REINFLATE_CONTENT_VIEW = 1;
+ public static final int FLAG_CONTENT_VIEW_CONTRACTED = 1;
/**
* The expanded view. Seen when the user expands a notification.
*/
- public static final int FLAG_REINFLATE_EXPANDED_VIEW = 1 << 1;
+ public static final int FLAG_CONTENT_VIEW_EXPANDED = 1 << 1;
/**
* The heads up view. Seen when a high priority notification peeks in from the top.
*/
- public static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1 << 2;
+ public static final int FLAG_CONTENT_VIEW_HEADS_UP = 1 << 2;
/**
* The ambient view. Seen when a high priority notification is received and the phone
* is dozing.
*/
- public static final int FLAG_REINFLATE_AMBIENT_VIEW = 1 << 3;
+ public static final int FLAG_CONTENT_VIEW_AMBIENT = 1 << 3;
/**
* The public view. This is a version of the contracted view that hides sensitive
* information and is used on the lock screen if we determine that the notification's
* content should be hidden.
*/
- public static final int FLAG_REINFLATE_PUBLIC_VIEW = 1 << 4;
+ public static final int FLAG_CONTENT_VIEW_PUBLIC = 1 << 4;
- public static final int FLAG_REINFLATE_ALL = ~0;
+ public static final int FLAG_CONTENT_VIEW_ALL = ~0;
/**
* Content views that must be inflated at all times.
*/
@InflationFlag
private static final int REQUIRED_INFLATION_FLAGS =
- FLAG_REINFLATE_CONTENT_VIEW
- | FLAG_REINFLATE_EXPANDED_VIEW
- | FLAG_REINFLATE_PUBLIC_VIEW;
+ FLAG_CONTENT_VIEW_CONTRACTED
+ | FLAG_CONTENT_VIEW_EXPANDED
+ | FLAG_CONTENT_VIEW_PUBLIC;
/**
* The set of content views to inflate.
@@ -144,7 +147,7 @@
if (childInGroup != mIsChildInGroup) {
mIsChildInGroup = childInGroup;
if (mIsLowPriority) {
- int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
+ int flags = FLAG_CONTENT_VIEW_CONTRACTED | FLAG_CONTENT_VIEW_EXPANDED;
inflateNotificationViews(flags);
}
}
@@ -172,7 +175,7 @@
if (mRow.getEntry() == null) {
return;
}
- inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
+ inflateNotificationViews(FLAG_CONTENT_VIEW_AMBIENT);
}
}
@@ -252,23 +255,41 @@
}
/**
- * Frees the content view associated with the inflation flag.
+ * Frees the content view associated with the inflation flag. Will only succeed if the
+ * view is safe to remove.
*
* @param inflateFlag the flag corresponding to the content view which should be freed
*/
public void freeNotificationView(@InflationFlag int inflateFlag) {
+ if ((mInflationFlags & inflateFlag) != 0) {
+ // The view should still be inflated.
+ return;
+ }
switch (inflateFlag) {
- case FLAG_REINFLATE_HEADS_UP_VIEW:
- mRow.getPrivateLayout().setHeadsUpChild(null);
- mCachedContentViews.remove(FLAG_REINFLATE_HEADS_UP_VIEW);
+ case FLAG_CONTENT_VIEW_HEADS_UP:
+ if (mRow.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_HEADSUP)) {
+ mRow.getPrivateLayout().setHeadsUpChild(null);
+ mCachedContentViews.remove(FLAG_CONTENT_VIEW_HEADS_UP);
+ }
break;
- case FLAG_REINFLATE_AMBIENT_VIEW:
- mRow.getShowingLayout().setAmbientChild(null);
- mCachedContentViews.remove(FLAG_REINFLATE_AMBIENT_VIEW);
+ case FLAG_CONTENT_VIEW_AMBIENT:
+ boolean privateSafeToRemove = mRow.getPrivateLayout().isContentViewInactive(
+ VISIBLE_TYPE_AMBIENT);
+ boolean publicSafeToRemove = mRow.getPublicLayout().isContentViewInactive(
+ VISIBLE_TYPE_AMBIENT);
+ if (privateSafeToRemove) {
+ mRow.getPrivateLayout().setAmbientChild(null);
+ }
+ if (publicSafeToRemove) {
+ mRow.getPublicLayout().setAmbientChild(null);
+ }
+ if (privateSafeToRemove && publicSafeToRemove) {
+ mCachedContentViews.remove(FLAG_CONTENT_VIEW_AMBIENT);
+ }
break;
- case FLAG_REINFLATE_CONTENT_VIEW:
- case FLAG_REINFLATE_EXPANDED_VIEW:
- case FLAG_REINFLATE_PUBLIC_VIEW:
+ case FLAG_CONTENT_VIEW_CONTRACTED:
+ case FLAG_CONTENT_VIEW_EXPANDED:
+ case FLAG_CONTENT_VIEW_PUBLIC:
default:
break;
}
@@ -280,23 +301,23 @@
Context packageContext) {
InflationProgress result = new InflationProgress();
isLowPriority = isLowPriority && !isChildInGroup;
- if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
result.newContentView = createContentView(builder, isLowPriority, usesIncreasedHeight);
}
- if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) {
result.newExpandedView = createExpandedView(builder, isLowPriority);
}
- if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
result.newHeadsUpView = builder.createHeadsUpContentView(usesIncreasedHeadsUpHeight);
}
- if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
result.newPublicView = builder.makePublicContentView();
}
- if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
result.newAmbientView = redactAmbient ? builder.makePublicAmbientNotification()
: builder.makeAmbientNotification();
}
@@ -316,11 +337,11 @@
NotificationContentView publicLayout = row.getPublicLayout();
final HashMap<Integer, CancellationSignal> runningInflations = new HashMap<>();
- int flag = FLAG_REINFLATE_CONTENT_VIEW;
+ int flag = FLAG_CONTENT_VIEW_CONTRACTED;
if ((reInflateFlags & flag) != 0) {
boolean isNewView =
!canReapplyRemoteView(result.newContentView,
- cachedContentViews.get(FLAG_REINFLATE_CONTENT_VIEW));
+ cachedContentViews.get(FLAG_CONTENT_VIEW_CONTRACTED));
ApplyCallback applyCallback = new ApplyCallback() {
@Override
public void setResultView(View v) {
@@ -339,12 +360,12 @@
runningInflations, applyCallback);
}
- flag = FLAG_REINFLATE_EXPANDED_VIEW;
+ flag = FLAG_CONTENT_VIEW_EXPANDED;
if ((reInflateFlags & flag) != 0) {
if (result.newExpandedView != null) {
boolean isNewView =
!canReapplyRemoteView(result.newExpandedView,
- cachedContentViews.get(FLAG_REINFLATE_EXPANDED_VIEW));
+ cachedContentViews.get(FLAG_CONTENT_VIEW_EXPANDED));
ApplyCallback applyCallback = new ApplyCallback() {
@Override
public void setResultView(View v) {
@@ -365,12 +386,12 @@
}
}
- flag = FLAG_REINFLATE_HEADS_UP_VIEW;
+ flag = FLAG_CONTENT_VIEW_HEADS_UP;
if ((reInflateFlags & flag) != 0) {
if (result.newHeadsUpView != null) {
boolean isNewView =
!canReapplyRemoteView(result.newHeadsUpView,
- cachedContentViews.get(FLAG_REINFLATE_HEADS_UP_VIEW));
+ cachedContentViews.get(FLAG_CONTENT_VIEW_HEADS_UP));
ApplyCallback applyCallback = new ApplyCallback() {
@Override
public void setResultView(View v) {
@@ -386,16 +407,16 @@
redactAmbient, isNewView, remoteViewClickHandler, callback,
privateLayout, privateLayout.getHeadsUpChild(),
privateLayout.getVisibleWrapper(
- NotificationContentView.VISIBLE_TYPE_HEADSUP), runningInflations,
+ VISIBLE_TYPE_HEADSUP), runningInflations,
applyCallback);
}
}
- flag = FLAG_REINFLATE_PUBLIC_VIEW;
+ flag = FLAG_CONTENT_VIEW_PUBLIC;
if ((reInflateFlags & flag) != 0) {
boolean isNewView =
!canReapplyRemoteView(result.newPublicView,
- cachedContentViews.get(FLAG_REINFLATE_PUBLIC_VIEW));
+ cachedContentViews.get(FLAG_CONTENT_VIEW_PUBLIC));
ApplyCallback applyCallback = new ApplyCallback() {
@Override
public void setResultView(View v) {
@@ -414,12 +435,12 @@
runningInflations, applyCallback);
}
- flag = FLAG_REINFLATE_AMBIENT_VIEW;
+ flag = FLAG_CONTENT_VIEW_AMBIENT;
if ((reInflateFlags & flag) != 0) {
NotificationContentView newParent = redactAmbient ? publicLayout : privateLayout;
boolean isNewView = (!canReapplyAmbient(row, redactAmbient)
|| !canReapplyRemoteView(result.newAmbientView,
- cachedContentViews.get(FLAG_REINFLATE_AMBIENT_VIEW)));
+ cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT)));
ApplyCallback applyCallback = new ApplyCallback() {
@Override
public void setResultView(View v) {
@@ -570,40 +591,40 @@
NotificationContentView privateLayout = row.getPrivateLayout();
NotificationContentView publicLayout = row.getPublicLayout();
if (runningInflations.isEmpty()) {
- if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
if (result.inflatedContentView != null) {
privateLayout.setContractedChild(result.inflatedContentView);
}
- cachedContentViews.put(FLAG_REINFLATE_CONTENT_VIEW, result.newContentView);
+ cachedContentViews.put(FLAG_CONTENT_VIEW_CONTRACTED, result.newContentView);
}
- if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) {
if (result.inflatedExpandedView != null) {
privateLayout.setExpandedChild(result.inflatedExpandedView);
} else if (result.newExpandedView == null) {
privateLayout.setExpandedChild(null);
}
- cachedContentViews.put(FLAG_REINFLATE_EXPANDED_VIEW, result.newExpandedView);
+ cachedContentViews.put(FLAG_CONTENT_VIEW_EXPANDED, result.newExpandedView);
row.setExpandable(result.newExpandedView != null);
}
- if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
if (result.inflatedHeadsUpView != null) {
privateLayout.setHeadsUpChild(result.inflatedHeadsUpView);
} else if (result.newHeadsUpView == null) {
privateLayout.setHeadsUpChild(null);
}
- cachedContentViews.put(FLAG_REINFLATE_HEADS_UP_VIEW, result.newHeadsUpView);
+ cachedContentViews.put(FLAG_CONTENT_VIEW_HEADS_UP, result.newHeadsUpView);
}
- if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
if (result.inflatedPublicView != null) {
publicLayout.setContractedChild(result.inflatedPublicView);
}
- cachedContentViews.put(FLAG_REINFLATE_PUBLIC_VIEW, result.newPublicView);
+ cachedContentViews.put(FLAG_CONTENT_VIEW_PUBLIC, result.newPublicView);
}
- if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+ if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
if (result.inflatedAmbientView != null) {
NotificationContentView newParent = redactAmbient
? publicLayout : privateLayout;
@@ -612,7 +633,7 @@
newParent.setAmbientChild(result.inflatedAmbientView);
otherParent.setAmbientChild(null);
}
- cachedContentViews.put(FLAG_REINFLATE_AMBIENT_VIEW, result.newAmbientView);
+ cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
}
entry.headsUpStatusBarText = result.headsUpStatusBarText;
entry.headsUpStatusBarTextPublic = result.headsUpStatusBarTextPublic;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index d477587..b4d24d16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -151,6 +153,7 @@
for (OnHeadsUpChangedListener listener : mListeners) {
listener.onHeadsUpStateChanged(entry, false);
}
+ entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
}
protected void updatePinnedMode() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 50147d5..aca1f90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -18,9 +18,6 @@
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_ALL;
-
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Instrumentation;
@@ -190,7 +187,8 @@
.setSmallIcon(R.drawable.ic_person)
.setContentTitle("Title")
.setContentText("Text")
- .setPublicVersion(publicVersion);
+ .setPublicVersion(publicVersion)
+ .setStyle(new Notification.BigTextStyle().bigText("Big Text"));
if (isGroupSummary) {
notificationBuilder.setGroupSummary(true);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 16ba3d0..cfc7526 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -18,13 +18,12 @@
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_ALL;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_HEADS_UP_VIEW;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -41,6 +40,7 @@
import android.app.NotificationChannel;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
import android.view.NotificationHeaderView;
@@ -140,26 +140,15 @@
}
@Test
- public void testHeadsUpViewShouldBeFreedWhenNotHeadsUp() throws Exception {
- ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_REINFLATE_ALL);
- row.setHeadsUp(true);
+ public void testFreeContentViewWhenSafe() throws Exception {
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
- row.setHeadsUp(false);
+ row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
assertNull(row.getPrivateLayout().getHeadsUpChild());
}
@Test
- public void testAmbientViewShouldBeFreedWhenNotPulsing() throws Exception {
- ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_REINFLATE_ALL);
- row.setAmbientPulsing(true);
-
- row.setAmbientPulsing(false);
-
- assertNull(row.getShowingLayout().getAmbientChild());
- }
-
- @Test
public void testAboveShelfChangedListenerCalled() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow();
AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
index 803f2a8..150d933 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
@@ -16,12 +16,9 @@
package com.android.systemui.statusbar.notification.row;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_ALL;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_EXPANDED_VIEW;
-import static com.android.systemui.statusbar.notification.row.NotificationInflater
- .FLAG_REINFLATE_HEADS_UP_VIEW;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_EXPANDED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -99,7 +96,7 @@
public void testIncreasedHeadsUpBeingUsed() {
mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
Notification.Builder builder = spy(mBuilder);
- mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+ mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext);
verify(builder).createHeadsUpContentView(true);
}
@@ -107,7 +104,7 @@
public void testIncreasedHeightBeingUsed() {
mNotificationInflater.setUsesIncreasedHeight(true);
Notification.Builder builder = spy(mBuilder);
- mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+ mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext);
verify(builder).createContentView(true);
}
@@ -120,7 +117,7 @@
@Test
public void testInflationOnlyInflatesSetFlags() throws Exception {
- mNotificationInflater.updateInflationFlag(FLAG_REINFLATE_HEADS_UP_VIEW,
+ mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP,
true /* shouldInflate */);
runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
mNotificationInflater);
@@ -163,7 +160,7 @@
new NotificationInflater.InflationProgress();
result.packageContext = mContext;
CountDownLatch countDownLatch = new CountDownLatch(1);
- NotificationInflater.applyRemoteView(result, FLAG_REINFLATE_EXPANDED_VIEW, 0,
+ NotificationInflater.applyRemoteView(result, FLAG_CONTENT_VIEW_EXPANDED, 0,
new ArrayMap() /* cachedContentViews */, mRow, false /* redactAmbient */,
true /* isNewView */, new RemoteViews.OnClickHandler(),
new NotificationInflater.InflationCallback() {
@@ -197,7 +194,7 @@
/* Cancelling requires us to be on the UI thread otherwise we might have a race */
@Test
public void testSupersedesExistingTask() {
- mNotificationInflater.addInflationFlags(FLAG_REINFLATE_ALL);
+ mNotificationInflater.addInflationFlags(FLAG_CONTENT_VIEW_ALL);
mNotificationInflater.inflateNotificationViews();
// Trigger inflation of content and expanded only.
@@ -208,7 +205,7 @@
NotificationInflater.AsyncInflationTask asyncInflationTask =
(NotificationInflater.AsyncInflationTask) runningTask;
assertEquals("Successive inflations don't inherit the previous flags!",
- asyncInflationTask.getReInflateFlags(), FLAG_REINFLATE_ALL);
+ asyncInflationTask.getReInflateFlags(), FLAG_CONTENT_VIEW_ALL);
runningTask.abort();
}