Merge "Heads-up notifications now reuse the views from the shade"

This commit is contained in:
Selim Cinek
2015-03-13 21:42:41 +00:00
committed by Android (Google) Code Review
7 changed files with 91 additions and 45 deletions

View File

@@ -416,8 +416,7 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
processForRemoteInput(sbn.getNotification());
addNotification(sbn, currentRanking);
addNotification(sbn, currentRanking, null /* oldEntry */);
}
}
});
@@ -456,7 +455,7 @@ public abstract class BaseStatusBar extends SystemUI implements
if (isUpdate) {
updateNotification(sbn, rankingMap);
} else {
addNotification(sbn, rankingMap);
addNotification(sbn, rankingMap, null /* oldEntry */);
}
}
});
@@ -1292,12 +1291,12 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void workAroundBadLayerDrawableOpacity(View v) {
}
private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
return inflateViews(entry, parent, false);
}
protected boolean inflateViewsForHeadsUp(NotificationData.Entry entry, ViewGroup parent) {
return inflateViews(entry, parent, true);
return inflateViews(entry, parent, true);
}
private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
@@ -1338,6 +1337,7 @@ public abstract class BaseStatusBar extends SystemUI implements
hasUserChangedExpansion = row.hasUserChangedExpansion();
userExpanded = row.isUserExpanded();
userLocked = row.isUserLocked();
entry.row.setHeadsUp(isHeadsUp);
entry.reset();
if (hasUserChangedExpansion) {
row.setUserExpanded(userExpanded);
@@ -1793,6 +1793,21 @@ public abstract class BaseStatusBar extends SystemUI implements
if (DEBUG) {
Log.d(TAG, "createNotificationViews(notification=" + sbn);
}
final StatusBarIconView iconView = createIcon(sbn);
if (iconView == null) {
return null;
}
// Construct the expanded view.
NotificationData.Entry entry = new NotificationData.Entry(sbn, iconView);
if (!inflateViews(entry, mStackScroller)) {
handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
return null;
}
return entry;
}
protected StatusBarIconView createIcon(StatusBarNotification sbn) {
// Construct the icon.
Notification n = sbn.getNotification();
final StatusBarIconView iconView = new StatusBarIconView(mContext,
@@ -1809,13 +1824,7 @@ public abstract class BaseStatusBar extends SystemUI implements
handleNotificationError(sbn, "Couldn't create icon: " + ic);
return null;
}
// Construct the expanded view.
NotificationData.Entry entry = new NotificationData.Entry(sbn, iconView);
if (!inflateViews(entry, mStackScroller)) {
handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
return null;
}
return entry;
return iconView;
}
protected void addNotificationViews(Entry entry, RankingMap ranking) {
@@ -1918,7 +1927,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected abstract boolean shouldDisableNavbarGestures();
public abstract void addNotification(StatusBarNotification notification,
RankingMap ranking);
RankingMap ranking, Entry oldEntry);
protected abstract void updateNotificationRanking(RankingMap ranking);
public abstract void removeNotification(String key, RankingMap ranking);
@@ -2034,8 +2043,10 @@ public abstract class BaseStatusBar extends SystemUI implements
}
} else {
if (shouldInterrupt && alertAgain) {
mStackScroller.setRemoveAnimationEnabled(false);
removeNotificationViews(key, ranking);
addNotification(notification, ranking); //this will pop the headsup
mStackScroller.setRemoveAnimationEnabled(true);
addNotification(notification, ranking, oldEntry); //this will pop the headsup
} else {
updateNotificationViews(oldEntry, notification);
}
@@ -2053,10 +2064,9 @@ public abstract class BaseStatusBar extends SystemUI implements
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
if (wasHeadsUp) {
if (DEBUG) Log.d(TAG, "rebuilding heads up for key: " + key);
Entry newEntry = new Entry(notification, null);
ViewGroup holder = mHeadsUpNotificationView.getHolder();
if (inflateViewsForHeadsUp(newEntry, holder)) {
mHeadsUpNotificationView.updateNotification(newEntry, alertAgain);
if (inflateViewsForHeadsUp(oldEntry, holder)) {
mHeadsUpNotificationView.updateNotification(oldEntry, alertAgain);
} else {
Log.w(TAG, "Couldn't create new updated headsup for package "
+ contentView.getPackage());
@@ -2070,8 +2080,10 @@ public abstract class BaseStatusBar extends SystemUI implements
} else {
if (shouldInterrupt && alertAgain) {
if (DEBUG) Log.d(TAG, "reposting to invoke heads up for key: " + key);
mStackScroller.setRemoveAnimationEnabled(false);
removeNotificationViews(key, ranking);
addNotification(notification, ranking); //this will pop the headsup
mStackScroller.setRemoveAnimationEnabled(true);
addNotification(notification, ranking, oldEntry); //this will pop the headsup
} else {
if (DEBUG) Log.d(TAG, "rebuilding update in place for key: " + key);
oldEntry.notification = notification;

View File

@@ -31,7 +31,6 @@ import com.android.systemui.R;
public class ExpandableNotificationRow extends ActivatableNotificationView {
private int mRowMinHeight;
private int mRowMaxHeight;
/** Does this row contain layouts that can adapt to row expansion */
private boolean mExpandable;
@@ -145,7 +144,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
super.reset();
mRowMinHeight = 0;
final boolean wasExpanded = isExpanded();
mRowMaxHeight = 0;
mMaxViewHeight = 0;
mExpandable = false;
mHasUserChangedExpansion = false;
mUserLocked = false;
@@ -217,7 +216,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
mRowMinHeight = rowMinHeight;
mRowMaxHeight = rowMaxHeight;
mMaxViewHeight = rowMaxHeight;
}
public boolean isExpandable() {

View File

@@ -33,9 +33,9 @@ import java.util.ArrayList;
*/
public abstract class ExpandableView extends FrameLayout {
private final int mMaxNotificationHeight;
private OnHeightChangedListener mOnHeightChangedListener;
protected int mMaxViewHeight;
private int mActualHeight;
protected int mClipTopAmount;
private boolean mActualHeightInitialized;
@@ -44,13 +44,13 @@ public abstract class ExpandableView extends FrameLayout {
public ExpandableView(Context context, AttributeSet attrs) {
super(context, attrs);
mMaxNotificationHeight = getResources().getDimensionPixelSize(
mMaxViewHeight = getResources().getDimensionPixelSize(
R.dimen.notification_max_height);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int ownMaxHeight = mMaxNotificationHeight;
int ownMaxHeight = mMaxViewHeight;
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
@@ -81,7 +81,8 @@ public abstract class ExpandableView extends FrameLayout {
mMatchParentViews.add(child);
}
}
int ownHeight = hasFixedHeight ? ownMaxHeight : maxChildHeight;
int ownHeight = hasFixedHeight ? ownMaxHeight :
isHeightLimited ? Math.min(ownMaxHeight, maxChildHeight) : maxChildHeight;
newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
for (View child : mMatchParentViews) {
child.measure(getChildMeasureSpec(

View File

@@ -136,6 +136,7 @@ import com.android.systemui.statusbar.NotificationOverflowContainer;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.SpeedBumpView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -1158,11 +1159,19 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
public void addNotification(StatusBarNotification notification, RankingMap ranking) {
public void addNotification(StatusBarNotification notification, RankingMap ranking,
Entry oldEntry) {
if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
if (mUseHeadsUp && shouldInterrupt(notification)) {
if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Entry interruptionCandidate = new Entry(notification, null);
Entry interruptionCandidate = oldEntry;
if (interruptionCandidate == null) {
final StatusBarIconView iconView = createIcon(notification);
if (iconView == null) {
return;
}
interruptionCandidate = new Entry(notification, iconView);
}
ViewGroup holder = mHeadsUpNotificationView.getHolder();
if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
// 1. Populate mHeadsUpNotificationView
@@ -1197,12 +1206,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
setAreThereNotifications();
}
public void displayNotificationFromHeadsUp(StatusBarNotification notification) {
NotificationData.Entry shadeEntry = createNotificationViews(notification);
if (shadeEntry == null) {
return;
}
public void displayNotificationFromHeadsUp(Entry shadeEntry) {
// The notification comes from the headsup, let's inflate the normal layout again
inflateViews(shadeEntry, mStackScroller);
shadeEntry.setInterruption();
shadeEntry.row.setHeadsUp(false);
addNotificationViews(shadeEntry, null);
// Recalculate the position of the sliding windows and the titles.

View File

@@ -168,6 +168,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
invalidate();
if (mHeadsUp == headsUp) {
resetViewForHeadsup();
// This is an in-place update. Noting more to do.
return;
}
@@ -180,12 +181,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
if (mHeadsUp != null) {
mMostRecentPackageName = mHeadsUp.notification.getPackageName();
if (mHeadsUp.row != null) { // only null in tests
mHeadsUp.row.setSystemExpanded(true);
mHeadsUp.row.setSensitive(false);
mHeadsUp.row.setHeadsUp(true);
mHeadsUp.row.setHideSensitive(
false, false /* animated */, 0 /* delay */, 0 /* duration */);
if (mHeadsUp.row != null) {
resetViewForHeadsup();
}
mStartTouchTime = SystemClock.elapsedRealtime() + mTouchSensitivityDelay;
@@ -206,6 +203,16 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
}
}
private void resetViewForHeadsup() {
mHeadsUp.row.setSystemExpanded(true);
mHeadsUp.row.setSensitive(false);
mHeadsUp.row.setHeadsUp(true);
mHeadsUp.row.setTranslationY(0);
mHeadsUp.row.setTranslationZ(0);
mHeadsUp.row.setHideSensitive(
false, false /* animated */, 0 /* delay */, 0 /* duration */);
}
/**
* Possibly enter the lingering state by delaying the closing of the window.
*
@@ -253,7 +260,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
public void releaseImmediately() {
if (DEBUG) Log.v(TAG, "releaseImmediately");
if (mHeadsUp != null) {
mBar.displayNotificationFromHeadsUp(mHeadsUp.notification);
mContentHolder.removeView(mHeadsUp.row);
mBar.displayNotificationFromHeadsUp(mHeadsUp);
}
mHeadsUp = null;
mBar.scheduleHeadsUpClose();

View File

@@ -213,6 +213,7 @@ public class NotificationStackScrollLayout extends ViewGroup
};
private PhoneStatusBar mPhoneStatusBar;
private int[] mTempInt2 = new int[2];
private boolean mRemoveAnimationEnabled;
public NotificationStackScrollLayout(Context context) {
this(context, null);
@@ -1551,11 +1552,16 @@ public class NotificationStackScrollLayout extends ViewGroup
((ExpandableView) child).setOnHeightChangedListener(null);
mCurrentStackScrollState.removeViewStateForView(child);
updateScrollStateForRemovedChild(child);
boolean animationGenerated = generateRemoveAnimation(child);
if (animationGenerated && !mSwipedOutViews.contains(child)) {
// Add this view to an overlay in order to ensure that it will still be temporary
// drawn when removed
getOverlay().add(child);
if (mRemoveAnimationEnabled) {
boolean animationGenerated = generateRemoveAnimation(child);
if (animationGenerated && !mSwipedOutViews.contains(child)) {
// Add this view to an overlay in order to ensure that it will still be temporary
// drawn when removed
getOverlay().add(child);
}
} else {
// TODO: handle this more cleanly when HEADS-up and the shade are merged
requestAnimateEverything();
}
updateAnimationState(false, child);
@@ -2392,8 +2398,13 @@ public class NotificationStackScrollLayout extends ViewGroup
}
public void onGoToKeyguard() {
requestAnimateEverything();
}
private void requestAnimateEverything() {
if (mIsExpanded && mAnimationsEnabled) {
mEverythingNeedsAnimation = true;
mNeedsAnimation = true;
requestChildrenUpdate();
}
}
@@ -2416,6 +2427,10 @@ public class NotificationStackScrollLayout extends ViewGroup
}
}
public void setRemoveAnimationEnabled(boolean enabled) {
mRemoveAnimationEnabled = enabled;
}
/**
* A listener that is notified when some child locations might have changed.
*/

View File

@@ -26,6 +26,7 @@ import android.view.WindowManager;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.NotificationData;
/*
* Status bar implementation for "large screen" products that mostly present no on-screen nav
@@ -47,7 +48,8 @@ public class TvStatusBar extends BaseStatusBar {
}
@Override
public void addNotification(StatusBarNotification notification, RankingMap ranking) {
public void addNotification(StatusBarNotification notification, RankingMap ranking,
NotificationData.Entry entry) {
}
@Override