diff options
| author | 2017-01-18 19:34:34 +0000 | |
|---|---|---|
| committer | 2017-01-18 19:34:38 +0000 | |
| commit | 64f13a56a404748bfea590a002663f991192da71 (patch) | |
| tree | 8afef1bd7a7ac9e42166e7814b74749ba606ca66 | |
| parent | b7a77d24a68accc30c45890d47c5da7f00cc2d00 (diff) | |
| parent | 4b820e4e5e0404adbf9f9678b79fa7e988e3e597 (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
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(); + } } |