diff --git a/packages/SystemUI/res/layout/hybrid_notification.xml b/packages/SystemUI/res/layout/hybrid_notification.xml new file mode 100644 index 0000000000000..9e64d2cc6eb60 --- /dev/null +++ b/packages/SystemUI/res/layout/hybrid_notification.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 9fd82eda03a84..c41352460c9e3 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -36,6 +36,18 @@ 14sp + + 16dp + + + 150sp + + + 8dp + + + 32sp + 64dp diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 844bab3d85be8..d5f9557ea56a1 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1026,6 +1026,9 @@ Touch to restore the original. + + , + You\'re using your work profile diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index ec22b9f1ec7e8..1e038c860be26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1929,27 +1929,29 @@ public abstract class BaseStatusBar extends SystemUI implements for (int i = 0; i < N; i++) { NotificationData.Entry entry = activeNotifications.get(i); if (onKeyguard) { - entry.row.setExpansionDisabled(true); + entry.row.setOnKeyguard(true); } else { - entry.row.setExpansionDisabled(false); - if (!entry.row.isUserLocked()) { - boolean top = (i == 0); - entry.row.setSystemExpanded(top); - } + entry.row.setOnKeyguard(false); + boolean top = (i == 0); + entry.row.setSystemExpanded(top); } - boolean isInvisibleChild = !mGroupManager.isVisible(entry.notification); + boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification); + boolean childWithVisibleSummary = childNotification + && mGroupManager.getGroupSummary(entry.notification).getVisibility() + == View.VISIBLE; boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification); if ((isLockscreenPublicMode() && !mShowLockscreenNotifications) || (onKeyguard && (visibleNotifications >= maxKeyguardNotifications - || !showOnKeyguard || isInvisibleChild))) { + && !childWithVisibleSummary + || !showOnKeyguard))) { entry.row.setVisibility(View.GONE); - if (onKeyguard && showOnKeyguard && !isInvisibleChild) { + if (onKeyguard && showOnKeyguard && !childNotification) { mKeyguardIconOverflowContainer.getIconsView().addNotification(entry); } } else { boolean wasGone = entry.row.getVisibility() == View.GONE; entry.row.setVisibility(View.VISIBLE); - if (!isInvisibleChild) { + if (!childNotification) { if (wasGone) { // notify the scroller of a child addition mStackScroller.generateAddAnimation(entry.row, true /* fromMoreCard */); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index b8df139c276de..7078f33b5af48 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -70,9 +70,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private boolean mIsSystemExpanded; /** - * Whether the notification expansion is disabled. This is the case on Keyguard. + * Whether the notification is on the keyguard and the expansion is disabled. */ - private boolean mExpansionDisabled; + private boolean mOnKeyguard; private NotificationContentView mPublicLayout; private NotificationContentView mPrivateLayout; @@ -162,6 +162,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private void setStatusBarNotification(StatusBarNotification statusBarNotification) { mStatusBarNotification = statusBarNotification; + mPrivateLayout.setStatusBarNotification(statusBarNotification); updateVetoButton(); onChildrenCountChanged(); } @@ -185,6 +186,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setGroupManager(NotificationGroupManager groupManager) { mGroupManager = groupManager; + mPrivateLayout.setGroupManager(groupManager); } public void addChildNotification(ExpandableNotificationRow row) { @@ -225,6 +227,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) { mChildInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup; mShowNoBackground = mChildInGroup && hasSameBgColor(parent); + mPrivateLayout.setIsChildInGroup(mShowNoBackground); updateBackground(); } @@ -265,34 +268,34 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } public void getChildrenStates(StackScrollState resultState) { - if (mChildrenExpanded) { + if (mIsSummaryWithChildren) { StackViewState parentState = resultState.getViewStateForView(this); mChildrenContainer.getState(resultState, parentState); } } public void applyChildrenState(StackScrollState state) { - if (mChildrenExpanded) { + if (mIsSummaryWithChildren) { mChildrenContainer.applyState(state); } } public void prepareExpansionChanged(StackScrollState state) { - if (mChildrenExpanded) { + if (mIsSummaryWithChildren) { mChildrenContainer.prepareExpansionChanged(state); } } public void startChildAnimation(StackScrollState finalState, StackStateAnimator stateAnimator, boolean withDelays, long delay, long duration) { - if (mChildrenExpanded) { + if (mIsSummaryWithChildren) { mChildrenContainer.startAnimationToState(finalState, stateAnimator, withDelays, delay, duration); } } public ExpandableNotificationRow getViewAtPosition(float y) { - if (!mChildrenExpanded) { + if (!mIsSummaryWithChildren || !mChildrenExpanded) { return this; } else { ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y); @@ -416,7 +419,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { mSensitive = false; mShowingPublicInitialized = false; mIsSystemExpanded = false; - mExpansionDisabled = false; + mOnKeyguard = false; mPublicLayout.reset(mIsHeadsUp); mPrivateLayout.reset(mIsHeadsUp); resetHeight(); @@ -580,16 +583,19 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { mIsSystemExpanded = expand; notifyHeightChanged(false /* needsAnimation */); logExpansionEvent(false, wasExpanded); + if (mChildrenContainer != null) { + mChildrenContainer.updateGroupOverflow(); + } } } /** - * @param expansionDisabled whether to prevent notification expansion + * @param onKeyguard whether to prevent notification expansion */ - public void setExpansionDisabled(boolean expansionDisabled) { - if (expansionDisabled != mExpansionDisabled) { + public void setOnKeyguard(boolean onKeyguard) { + if (onKeyguard != mOnKeyguard) { final boolean wasExpanded = isExpanded(); - mExpansionDisabled = expansionDisabled; + mOnKeyguard = onKeyguard; logExpansionEvent(false, wasExpanded); if (wasExpanded != isExpanded()) { notifyHeightChanged(false /* needsAnimation */); @@ -622,23 +628,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { return getActualHeight(); } boolean inExpansionState = isExpanded(); - int maxContentHeight; if (mSensitive && mHideSensitiveForIntrinsicHeight) { return mRowMinHeight; + } else if (mIsSummaryWithChildren && !mOnKeyguard) { + return mChildrenContainer.getIntrinsicHeight() + + mNotificationHeader.getHeight(); } else if (mIsHeadsUp) { if (inExpansionState) { - maxContentHeight = Math.max(mMaxExpandHeight, mHeadsUpHeight); + return Math.max(mMaxExpandHeight, mHeadsUpHeight); } else { - maxContentHeight = Math.max(mRowMinHeight, mHeadsUpHeight); + return Math.max(mRowMinHeight, mHeadsUpHeight); } - } else if ((!inExpansionState && !mChildrenExpanded)) { - maxContentHeight = mRowMinHeight; - } else if (mChildrenExpanded) { - maxContentHeight = mChildrenContainer.getIntrinsicHeight(); + } else if (!inExpansionState || (mChildInGroup && !isGroupExpanded())) { + return getMinHeight(); } else { - maxContentHeight = getMaxExpandHeight(); + return getMaxExpandHeight(); } - return maxContentHeight; } private boolean isGroupExpanded() { @@ -670,8 +675,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { * * @return whether the view state is currently expanded. */ - private boolean isExpanded() { - return !mExpansionDisabled + public boolean isExpanded() { + return !mOnKeyguard && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded()) || isUserExpanded()); } @@ -778,6 +783,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setChildrenExpanded(boolean expanded, boolean animate) { mChildrenExpanded = expanded; + if (mChildrenContainer != null) { + mChildrenContainer.setChildrenExpanded(expanded); + } } public void updateNotificationHeader() { @@ -844,12 +852,20 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { @Override public int getMaxContentHeight() { + if (mIsSummaryWithChildren && !mShowingPublic) { + return mChildrenContainer.getMaxContentHeight() + + mNotificationHeader.getHeight(); + } NotificationContentView showingLayout = getShowingLayout(); return showingLayout.getMaxHeight(); } @Override public int getMinHeight() { + if (mIsSummaryWithChildren && !mOnKeyguard) { + return mChildrenContainer.getMinHeight() + + mNotificationHeader.getHeight(); + } NotificationContentView showingLayout = getShowingLayout(); return showingLayout.getMinHeight(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 0e32b62cddba8..5aedaf1024212 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -22,6 +22,7 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; +import android.service.notification.StatusBarNotification; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -32,6 +33,9 @@ import android.view.animation.LinearInterpolator; import android.widget.FrameLayout; import com.android.systemui.R; +import com.android.systemui.statusbar.notification.HybridNotificationView; +import com.android.systemui.statusbar.notification.HybridNotificationViewManager; +import com.android.systemui.statusbar.phone.NotificationGroupManager; /** * A frame layout containing the actual payload of the notification, including the contracted, @@ -44,8 +48,10 @@ public class NotificationContentView extends FrameLayout { private static final int VISIBLE_TYPE_CONTRACTED = 0; 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 final Rect mClipBounds = new Rect(); + private final int mSingleLineHeight; private final int mSmallHeight; private final int mHeadsUpHeight; private final int mRoundRectRadius; @@ -55,10 +61,12 @@ public class NotificationContentView extends FrameLayout { private View mContractedChild; private View mExpandedChild; private View mHeadsUpChild; + private HybridNotificationView mSingleLineView; private NotificationViewWrapper mContractedWrapper; private NotificationViewWrapper mExpandedWrapper; private NotificationViewWrapper mHeadsUpWrapper; + private HybridNotificationViewManager mHybridViewManager; private int mClipTopAmount; private int mContentHeight; private int mUnrestrictedContentHeight; @@ -68,6 +76,8 @@ public class NotificationContentView extends FrameLayout { private boolean mAnimate; private boolean mIsHeadsUp; private boolean mShowingLegacyBackground; + private boolean mIsChildInGroup; + private StatusBarNotification mStatusBarNotification; private final ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener = new ViewTreeObserver.OnPreDrawListener() { @@ -86,10 +96,14 @@ public class NotificationContentView extends FrameLayout { mRoundRectRadius); } }; + private NotificationGroupManager mGroupManager; public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); + mHybridViewManager = new HybridNotificationViewManager(getContext(), this); mFadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); + mSingleLineHeight = getResources().getDimensionPixelSize( + R.dimen.notification_single_line_height); mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); mHeadsUpHeight = getResources().getDimensionPixelSize(R.dimen.notification_mid_height); mRoundRectRadius = getResources().getDimensionPixelSize( @@ -140,6 +154,12 @@ public class NotificationContentView extends FrameLayout { MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST)); maxChildHeight = Math.max(maxChildHeight, mHeadsUpChild.getMeasuredHeight()); } + if (mSingleLineView != null) { + int size = Math.min(maxSize, mSingleLineHeight); + mSingleLineView.measure(widthMeasureSpec, + MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY)); + maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight()); + } int ownHeight = Math.min(maxChildHeight, maxSize); int width = MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(width, ownHeight); @@ -271,7 +291,15 @@ public class NotificationContentView extends FrameLayout { } public int getMinHeight() { - return mSmallHeight; + if (mIsChildInGroup && !isGroupExpanded()) { + return mSingleLineHeight; + } else { + return mSmallHeight; + } + } + + private boolean isGroupExpanded() { + return mGroupManager.isGroupExpanded(mStatusBarNotification); } public void setClipTopAmount(int clipTopAmount) { @@ -313,6 +341,7 @@ public class NotificationContentView extends FrameLayout { if (visibleType != mVisibleType || force) { if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null) || (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null) + || (visibleType == VISIBLE_TYPE_SINGLELINE && mSingleLineView != null) || visibleType == VISIBLE_TYPE_CONTRACTED)) { runSwitchAnimation(visibleType); } else { @@ -339,6 +368,12 @@ public class NotificationContentView extends FrameLayout { mHeadsUpChild.setAlpha(headsUpVisible ? 1f : 0f); mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null); } + if (mSingleLineView != null) { + boolean singleLineVisible = visibleType == VISIBLE_TYPE_SINGLELINE; + mSingleLineView.setVisibility(singleLineVisible ? View.VISIBLE : View.INVISIBLE); + mSingleLineView.setAlpha(singleLineVisible ? 1f : 0f); + mSingleLineView.setLayerType(LAYER_TYPE_NONE, null); + } setLayerType(LAYER_TYPE_NONE, null); updateRoundRectClipping(); } @@ -379,6 +414,8 @@ public class NotificationContentView extends FrameLayout { return mExpandedChild; case VISIBLE_TYPE_HEADSUP: return mHeadsUpChild; + case VISIBLE_TYPE_SINGLELINE: + return mSingleLineView; default: return mContractedChild; } @@ -396,7 +433,9 @@ public class NotificationContentView extends FrameLayout { return VISIBLE_TYPE_EXPANDED; } } else { - if (mContentHeight <= mSmallHeight || noExpandedChild) { + if (mIsChildInGroup && !isGroupExpanded()) { + return VISIBLE_TYPE_SINGLELINE; + } else if (mContentHeight <= mSmallHeight || noExpandedChild) { return VISIBLE_TYPE_CONTRACTED; } else { return VISIBLE_TYPE_EXPANDED; @@ -405,6 +444,7 @@ public class NotificationContentView extends FrameLayout { } public void notifyContentUpdated() { + updateSingleLineView(); selectLayout(false /* animate */, true /* force */); if (mContractedChild != null) { mContractedWrapper.notifyContentUpdated(); @@ -443,6 +483,23 @@ public class NotificationContentView extends FrameLayout { mShowingLegacyBackground = showing; } + public void setIsChildInGroup(boolean isChildInGroup) { + mIsChildInGroup = isChildInGroup; + updateSingleLineView(); + } + + public void setStatusBarNotification(StatusBarNotification statusBarNotification) { + mStatusBarNotification = statusBarNotification; + updateSingleLineView(); + } + + private void updateSingleLineView() { + if (mIsChildInGroup) { + mSingleLineView = mHybridViewManager.bindFromNotification( + mSingleLineView, mStatusBarNotification.getNotification()); + } + } + public void setSubTextVisible(boolean visible) { if (mExpandedChild != null) { mExpandedWrapper.setSubTextVisible(visible); @@ -454,4 +511,8 @@ public class NotificationContentView extends FrameLayout { mHeadsUpWrapper.setSubTextVisible(visible); } } + + public void setGroupManager(NotificationGroupManager groupManager) { + mGroupManager = groupManager; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java new file mode 100644 index 0000000000000..8f46e89fa04f5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification; + +import android.annotation.Nullable; +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.statusbar.AlphaOptimizedFrameLayout; + +/** + * A hybrid view which may contain information about one ore more notifications. + */ +public class HybridNotificationView extends AlphaOptimizedFrameLayout { + + protected final int mSingleLineHeight; + protected final int mStartMargin; + protected final int mEndMargin; + protected TextView mTitleView; + protected TextView mTextView; + + public HybridNotificationView(Context context) { + this(context, null); + } + + public HybridNotificationView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public HybridNotificationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public HybridNotificationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + mSingleLineHeight = context.getResources().getDimensionPixelSize( + R.dimen.notification_single_line_height); + mStartMargin = context.getResources().getDimensionPixelSize( + R.dimen.notification_content_margin_start); + mEndMargin = context.getResources().getDimensionPixelSize( + R.dimen.notification_content_margin_end); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int totalWidth = MeasureSpec.getSize(widthMeasureSpec); + int remainingWidth = totalWidth - mStartMargin - mEndMargin; + int newHeightSpec = MeasureSpec.makeMeasureSpec( + MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST); + int newWidthSpec = MeasureSpec.makeMeasureSpec(remainingWidth, MeasureSpec.AT_MOST); + mTitleView.measure(newWidthSpec, newHeightSpec); + int maxTitleLength = getResources().getDimensionPixelSize( + R.dimen.notification_maximum_title_length); + int titleWidth = mTitleView.getMeasuredWidth(); + int heightSpec = MeasureSpec.makeMeasureSpec(mSingleLineHeight, MeasureSpec.AT_MOST); + boolean hasText = !TextUtils.isEmpty(mTextView.getText()); + if (titleWidth > maxTitleLength && hasText) { + titleWidth = maxTitleLength; + int widthSpec = MeasureSpec.makeMeasureSpec(titleWidth, MeasureSpec.EXACTLY); + mTitleView.measure(widthSpec, heightSpec); + } + if (hasText) { + remainingWidth -= titleWidth; + int widthSpec = MeasureSpec.makeMeasureSpec(remainingWidth, MeasureSpec.AT_MOST); + mTextView.measure(widthSpec, newHeightSpec); + } + setMeasuredDimension(totalWidth, mSingleLineHeight); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + int childLeft = mStartMargin; + int childRight = childLeft + mTitleView.getMeasuredWidth(); + int childBottom = (mSingleLineHeight + mTitleView.getMeasuredHeight()) / 2; + int childTop = childBottom - mTitleView.getMeasuredHeight(); + int rtlLeft = transformForRtl(childLeft); + int rtlRight = transformForRtl(childRight); + mTitleView.layout(Math.min(rtlLeft, rtlRight), childTop, Math.max(rtlLeft, rtlRight), + childBottom); + childLeft = childRight; + childRight = childLeft + mTextView.getMeasuredWidth(); + childTop = mTitleView.getTop() + mTitleView.getBaseline() - mTextView.getBaseline(); + childBottom = childTop + mTextView.getMeasuredHeight(); + rtlLeft = transformForRtl(childLeft); + rtlRight = transformForRtl(childRight); + mTextView.layout(Math.min(rtlLeft, rtlRight), childTop, Math.max(rtlLeft, rtlRight), + childBottom); + } + + private int transformForRtl(int left) { + return isLayoutRtl() ? getWidth() - left : left; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mTitleView = (TextView) findViewById(R.id.notification_title); + mTextView = (TextView) findViewById(R.id.notification_text); + } + + public void bind(CharSequence title) { + bind(title, null); + } + + public void bind(CharSequence title, CharSequence text) { + mTitleView.setText(title); + mTextView.setText(text); + requestLayout(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java new file mode 100644 index 0000000000000..987f7b831b452 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification; + +import android.app.Notification; +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import com.android.systemui.R; +import com.android.systemui.statusbar.ExpandableNotificationRow; + +import java.util.List; + +/** + * A class managing {@link HybridNotificationView} views + */ +public class HybridNotificationViewManager { + + private final Context mContext; + private ViewGroup mParent; + private String mConcadenationString; + + public HybridNotificationViewManager(Context ctx, ViewGroup parent) { + mContext = ctx; + mParent = parent; + mConcadenationString = mContext.getString(R.string.group_summary_concadenation); + } + + private HybridNotificationView inflateHybridView() { + LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class); + HybridNotificationView hybrid = (HybridNotificationView) inflater.inflate( + R.layout.hybrid_notification, mParent, false); + mParent.addView(hybrid); + return hybrid; + } + + public HybridNotificationView bindFromNotification(HybridNotificationView reusableView, + Notification notification) { + CharSequence titleText = resolveTitle(notification); + if (titleText == null) { + if (reusableView != null) { + mParent.removeView(reusableView); + } + return null; + } + if (reusableView == null) { + reusableView = inflateHybridView(); + } + CharSequence contentText = resolveText(notification); + reusableView.bind(titleText, contentText); + return reusableView; + } + + private CharSequence resolveText(Notification notification) { + CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT); + if (contentText == null) { + contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT); + } + return contentText; + } + + private CharSequence resolveTitle(Notification notification) { + CharSequence titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE); + if (titleText == null) { + titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE_BIG); + } + return titleText; + } + + public HybridNotificationView bindFromNotificationGroup( + HybridNotificationView reusableView, + List group, int startIndex) { + if (reusableView == null) { + reusableView = inflateHybridView(); + } + CharSequence summary = null; + int childCount = group.size(); + for (int i = startIndex; i < childCount; i++) { + ExpandableNotificationRow child = group.get(i); + CharSequence titleText = resolveTitle( + child.getStatusBarNotification().getNotification()); + if (titleText == null) { + continue; + } + if (TextUtils.isEmpty(summary)) { + summary = titleText; + } else if (reusableView.isLayoutRtl()) { + summary = titleText + mConcadenationString + summary; + } else { + summary = summary + mConcadenationString + titleText; + } + } + reusableView.bind(summary); + return reusableView; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java index d0b3c4bc5bad7..bbef1c031ff57 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java @@ -21,7 +21,6 @@ import android.service.notification.StatusBarNotification; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationData; -import com.android.systemui.statusbar.StatusBarState; import java.util.HashMap; import java.util.HashSet; @@ -93,21 +92,8 @@ public class NotificationGroupManager { if (group.children.isEmpty()) { if (group.summary == null) { mGroupMap.remove(groupKey); - } else { - if (group.expanded) { - // only the summary is left. Change it to unexpanded in a few ms. We do this to - // avoid raceconditions - removed.row.post(new Runnable() { - @Override - public void run() { - if (group.children.isEmpty()) { - setGroupExpanded(sbn, false); - } - } - }); - } else { - group.summary.row.updateNotificationHeader(); - } + } else if (!group.expanded) { + group.summary.row.updateNotificationHeader(); } } } @@ -155,9 +141,6 @@ public class NotificationGroupManager { } public boolean hasGroupChildren(StatusBarNotification sbn) { - if (areGroupsProhibited()) { - return false; - } if (!sbn.getNotification().isGroupSummary()) { return false; } @@ -168,29 +151,6 @@ public class NotificationGroupManager { return !group.children.isEmpty(); } - public void setStatusBarState(int newState) { - if (mBarState == newState) { - return; - } - boolean prohibitedBefore = areGroupsProhibited(); - mBarState = newState; - boolean nowProhibited = areGroupsProhibited(); - if (nowProhibited != prohibitedBefore) { - if (nowProhibited) { - for (NotificationGroup group : mGroupMap.values()) { - if (group.expanded) { - setGroupExpanded(group, false); - } - } - } - mListener.onGroupsProhibitedChanged(); - } - } - - private boolean areGroupsProhibited() { - return mBarState == StatusBarState.KEYGUARD; - } - /** * @return whether a given notification is a child in a group which has a summary */ @@ -226,6 +186,18 @@ public class NotificationGroupManager { : group.summary.row; } + public void onEntryHeadsUped(NotificationData.Entry headsUp) { + // TODO: handle this nicely + } + + public void toggleGroupExpansion(StatusBarNotification sbn) { + NotificationGroup group = mGroupMap.get(sbn.getGroupKey()); + if (group == null) { + return; + } + setGroupExpanded(group, !group.expanded); + } + public static class NotificationGroup { public final HashSet children = new HashSet<>(); public NotificationData.Entry summary; @@ -241,11 +213,6 @@ public class NotificationGroupManager { */ void onGroupExpansionChanged(ExpandableNotificationRow changedRow, boolean expanded); - /** - * Children group policy has changed and children may no be prohibited or allowed. - */ - void onGroupsProhibitedChanged(); - /** * A group of children just received a summary notification and should therefore become * children of it. 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 deb44025880c3..3e52515878207 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -714,7 +714,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, R.color.notification_panel_solid_background))); } - mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow); + mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager); mHeadsUpManager.setBar(this); mHeadsUpManager.addListener(this); mHeadsUpManager.addListener(mNotificationPanel); @@ -3859,7 +3859,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, clearNotificationEffects(); } mState = state; - mGroupManager.setStatusBarState(state); mFalsingManager.setStatusBarState(state); mStatusBarWindowManager.setStatusBarState(state); updateDozing(); 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 a515f23f33ea8..dc9f5e863379d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -33,6 +33,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.PhoneStatusBar; import java.io.FileDescriptor; @@ -85,6 +86,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL private final int mStatusBarHeight; private final int mNotificationsTopPadding; private final Context mContext; + private final NotificationGroupManager mGroupManager; private PhoneStatusBar mBar; private int mSnoozeLengthMs; private ContentObserver mSettingsObserver; @@ -104,7 +106,8 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL private boolean mIsObserving; private boolean mRemoteInputActive; - public HeadsUpManager(final Context context, View statusBarWindowView) { + public HeadsUpManager(final Context context, View statusBarWindowView, + NotificationGroupManager groupManager) { mContext = context; Resources resources = mContext.getResources(); mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay); @@ -132,6 +135,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false, mSettingsObserver); mStatusBarWindowView = statusBarWindowView; + mGroupManager = groupManager; mStatusBarHeight = resources.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); mNotificationsTopPadding = context.getResources() @@ -181,12 +185,12 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL public void updateNotification(NotificationData.Entry headsUp, boolean alert) { if (DEBUG) Log.v(TAG, "updateNotification"); - headsUp.row.setChildrenExpanded(false /* expanded */, false /* animated */); headsUp.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); if (alert) { HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key); headsUpEntry.updateEntry(); + mGroupManager.onEntryHeadsUped(headsUp); setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUp)); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java index da82456d69488..539dace6cae10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java @@ -24,7 +24,8 @@ import android.view.ViewGroup; import com.android.systemui.R; import com.android.systemui.statusbar.ExpandableNotificationRow; -import com.android.systemui.statusbar.ExpandableView; +import com.android.systemui.statusbar.notification.HybridNotificationView; +import com.android.systemui.statusbar.notification.HybridNotificationViewManager; import java.util.ArrayList; import java.util.List; @@ -34,6 +35,10 @@ import java.util.List; */ public class NotificationChildrenContainer extends ViewGroup { + private static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2; + private static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5; + private static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8; + private final int mChildPadding; private final int mDividerHeight; private final int mMaxNotificationHeight; @@ -42,6 +47,12 @@ public class NotificationChildrenContainer extends ViewGroup { private final int mNotificationHeaderHeight; private final int mNotificationAppearDistance; private final float mHeaderTopPaddingSubstraction; + private final HybridNotificationViewManager mHybridViewManager; + private final float mCollapsedBottompadding; + private boolean mChildrenExpanded; + private ExpandableNotificationRow mNotificationParent; + private HybridNotificationView mGroupOverflowContainer; + private ViewState mGroupOverFlowState; public NotificationChildrenContainer(Context context) { this(context, null); @@ -69,6 +80,8 @@ public class NotificationChildrenContainer extends ViewGroup { mNotificationHeaderHeight = getResources().getDimensionPixelSize( R.dimen.notification_header_height); mHeaderTopPaddingSubstraction = 2 * getResources().getDisplayMetrics().density; + mCollapsedBottompadding = 10 * getResources().getDisplayMetrics().density; + mHybridViewManager = new HybridNotificationViewManager(getContext(), this); } @Override @@ -78,14 +91,6 @@ public class NotificationChildrenContainer extends ViewGroup { for (int i = 0; i < childCount; i++) { View child = mChildren.get(i); boolean viewGone = child.getVisibility() == View.GONE; - if (i != 0) { - View divider = mDividers.get(i - 1); - int dividerVisibility = divider.getVisibility(); - int newVisibility = viewGone ? INVISIBLE : VISIBLE; - if (dividerVisibility != newVisibility) { - divider.setVisibility(newVisibility); - } - } if (viewGone) { continue; } @@ -96,6 +101,10 @@ public class NotificationChildrenContainer extends ViewGroup { firstChild = false; } } + if (mGroupOverflowContainer != null) { + mGroupOverflowContainer.layout(0, 0, getWidth(), + mGroupOverflowContainer.getMeasuredHeight()); + } } @Override @@ -115,9 +124,6 @@ public class NotificationChildrenContainer extends ViewGroup { boolean firstChild = true; for (int i = 0; i < childCount; i++) { View child = mChildren.get(i); - if (child.getVisibility() == View.GONE) { - continue; - } child.measure(widthMeasureSpec, newHeightSpec); height += child.getMeasuredHeight(); if (!firstChild) { @@ -130,9 +136,9 @@ public class NotificationChildrenContainer extends ViewGroup { } } int width = MeasureSpec.getSize(widthMeasureSpec); - height = hasFixedHeight ? ownMaxHeight - : isHeightLimited ? Math.min(ownMaxHeight, height) - : height; + if (mGroupOverflowContainer != null) { + mGroupOverflowContainer.measure(widthMeasureSpec, newHeightSpec); + } setMeasuredDimension(width, height); } @@ -151,8 +157,7 @@ public class NotificationChildrenContainer extends ViewGroup { addView(divider); mDividers.add(Math.max(newIndex - 1, 0), divider); } - // TODO: adapt background corners - // TODO: fix overdraw + updateGroupOverflow(); } public void removeNotification(ExpandableNotificationRow row) { @@ -164,7 +169,26 @@ public class NotificationChildrenContainer extends ViewGroup { removeView(divider); } row.setSystemChildExpanded(false); - // TODO: adapt background corners + updateGroupOverflow(); + } + + public void updateGroupOverflow() { + int childCount = mChildren.size(); + int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* likeCollapsed */); + boolean hasOverflow = childCount > maxAllowedVisibleChildren; + int lastVisibleIndex = hasOverflow ? maxAllowedVisibleChildren - 2 + : maxAllowedVisibleChildren - 1; + if (hasOverflow) { + mGroupOverflowContainer = mHybridViewManager.bindFromNotificationGroup( + mGroupOverflowContainer, mChildren, lastVisibleIndex + 1); + if (mGroupOverFlowState == null) { + mGroupOverFlowState = new ViewState(); + } + } else if (mGroupOverflowContainer != null) { + removeView(mGroupOverflowContainer); + mGroupOverflowContainer = null; + mGroupOverFlowState = null; + } } private View inflateDivider() { @@ -196,25 +220,42 @@ public class NotificationChildrenContainer extends ViewGroup { result = true; } } - - // Let's make the first child expanded! - boolean first = true; - for (int i = 0; i < childOrder.size(); i++) { - ExpandableNotificationRow child = childOrder.get(i); - child.setSystemChildExpanded(first); - first = false; - } + updateExpansionStates(); return result; } + private void updateExpansionStates() { + // Let's make the first child expanded if the parent is + for (int i = 0; i < mChildren.size(); i++) { + ExpandableNotificationRow child = mChildren.get(i); + child.setSystemChildExpanded(false); + } + } + + /** + * + * @return the intrinsic size of this children container, i.e the natural fully expanded state + */ public int getIntrinsicHeight() { - int childCount = mChildren.size(); + int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(); + return getIntrinsicHeight(maxAllowedVisibleChildren); + } + + /** + * @return the intrinsic height with a number of children given + * in @param maxAllowedVisibleChildren + */ + private int getIntrinsicHeight(float maxAllowedVisibleChildren) { int intrinsicHeight = 0; int visibleChildren = 0; + int childCount = mChildren.size(); for (int i = 0; i < childCount; i++) { + if (visibleChildren >= maxAllowedVisibleChildren) { + break; + } ExpandableNotificationRow child = mChildren.get(i); - if (child.getVisibility() == View.GONE) { - continue; + if (i == 0 && child.hasSameBgColor(mNotificationParent)) { + intrinsicHeight -= mHeaderTopPaddingSubstraction; } intrinsicHeight += child.getIntrinsicHeight(); visibleChildren++; @@ -222,6 +263,9 @@ public class NotificationChildrenContainer extends ViewGroup { if (visibleChildren > 0) { intrinsicHeight += (visibleChildren - 1) * mDividerHeight; } + if (!mChildrenExpanded) { + intrinsicHeight += mCollapsedBottompadding; + } return intrinsicHeight; } @@ -235,15 +279,21 @@ public class NotificationChildrenContainer extends ViewGroup { int childCount = mChildren.size(); int yPosition = mNotificationHeaderHeight; boolean firstChild = true; + int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(); + boolean hasOverflow = !mChildrenExpanded && childCount > maxAllowedVisibleChildren + && maxAllowedVisibleChildren != NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED; + int lastVisibleIndex = hasOverflow + ? maxAllowedVisibleChildren - 2 + : maxAllowedVisibleChildren - 1; for (int i = 0; i < childCount; i++) { ExpandableNotificationRow child = mChildren.get(i); - if (child.getVisibility() == View.GONE) { - continue; - } if (!firstChild) { // There's a divider yPosition += mChildPadding; } else { + if (child.hasSameBgColor(mNotificationParent)) { + yPosition -= mHeaderTopPaddingSubstraction; + } firstChild = false; } StackViewState childState = resultState.getViewStateForView(child); @@ -255,37 +305,62 @@ public class NotificationChildrenContainer extends ViewGroup { childState.dark = parentState.dark; childState.hideSensitive = parentState.hideSensitive; childState.belowSpeedBump = parentState.belowSpeedBump; - childState.scale = parentState.scale; + childState.scale = 1.0f; childState.clipTopAmount = 0; childState.topOverLap = 0; + boolean visible = i <= lastVisibleIndex; + childState.alpha = visible ? 1 : 0; childState.location = parentState.location; yPosition += intrinsicHeight; } + if (mGroupOverflowContainer != null) { + mGroupOverFlowState.initFrom(mGroupOverflowContainer); + if (hasOverflow) { + StackViewState firstOverflowState = + resultState.getViewStateForView(mChildren.get(lastVisibleIndex + 1)); + mGroupOverFlowState.yTranslation = firstOverflowState.yTranslation; + } + mGroupOverFlowState.alpha = mChildrenExpanded || !hasOverflow ? 0.0f : 1.0f; + } + } + + private int getMaxAllowedVisibleChildren() { + return getMaxAllowedVisibleChildren(false /* likeCollapsed */); + } + + private int getMaxAllowedVisibleChildren(boolean likeCollapsed) { + if (!likeCollapsed && (mChildrenExpanded || mNotificationParent.isUserLocked())) { + return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED; + } + if (mNotificationParent.isExpanded()) { + return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED; + } + return NUMBER_OF_CHILDREN_WHEN_COLLAPSED; } public void applyState(StackScrollState state) { int childCount = mChildren.size(); boolean firstChild = true; - ViewState dividerState = new ViewState(); + ViewState tmpState = new ViewState(); for (int i = 0; i < childCount; i++) { ExpandableNotificationRow child = mChildren.get(i); StackViewState viewState = state.getViewStateForView(child); - if (child.getVisibility() == View.GONE) { - continue; - } if (!firstChild) { // layout the divider View divider = mDividers.get(i - 1); - dividerState.initFrom(divider); - dividerState.yTranslation = (int) (viewState.yTranslation + tmpState.initFrom(divider); + tmpState.yTranslation = (int) (viewState.yTranslation - (mChildPadding + mDividerHeight) / 2.0f); - dividerState.alpha = 1; - state.applyViewState(divider, dividerState); + tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0; + state.applyViewState(divider, tmpState); } else { firstChild = false; } state.applyState(child, viewState); } + if (mGroupOverflowContainer != null) { + state.applyViewState(mGroupOverflowContainer, mGroupOverFlowState); + } } /** @@ -295,6 +370,10 @@ public class NotificationChildrenContainer extends ViewGroup { * @param state the new state we animate to */ public void prepareExpansionChanged(StackScrollState state) { + if (true) { + // TODO: do something that makes sense + return; + } int childCount = mChildren.size(); boolean firstChild = true; StackViewState sourceState = new StackViewState(); @@ -302,9 +381,6 @@ public class NotificationChildrenContainer extends ViewGroup { for (int i = 0; i < childCount; i++) { ExpandableNotificationRow child = mChildren.get(i); StackViewState viewState = state.getViewStateForView(child); - if (child.getVisibility() == View.GONE) { - continue; - } if (!firstChild) { // layout the divider View divider = mDividers.get(i - 1); @@ -321,23 +397,17 @@ public class NotificationChildrenContainer extends ViewGroup { sourceState.yTranslation += mNotificationAppearDistance; state.applyState(child, sourceState); } - mCollapseButton.setAlpha(0); - mCollapseDivider.setAlpha(0); - mCollapseDivider.setTranslationY(mNotificationAppearDistance / 4); } public void startAnimationToState(StackScrollState state, StackStateAnimator stateAnimator, boolean withDelays, long baseDelay, long duration) { int childCount = mChildren.size(); boolean firstChild = true; - ViewState dividerState = new ViewState(); + ViewState tmpState = new ViewState(); int notGoneIndex = 0; for (int i = 0; i < childCount; i++) { ExpandableNotificationRow child = mChildren.get(i); StackViewState viewState = state.getViewStateForView(child); - if (child.getVisibility() == View.GONE) { - continue; - } int difference = Math.min(StackStateAnimator.DELAY_EFFECT_MAX_INDEX_DIFFERENCE_CHILDREN, notGoneIndex + 1); long delay = withDelays @@ -347,17 +417,20 @@ public class NotificationChildrenContainer extends ViewGroup { if (!firstChild) { // layout the divider View divider = mDividers.get(i - 1); - dividerState.initFrom(divider); - dividerState.yTranslation = viewState.yTranslation + tmpState.initFrom(divider); + tmpState.yTranslation = viewState.yTranslation - (mChildPadding + mDividerHeight) / 2.0f; - dividerState.alpha = 1; - stateAnimator.startViewAnimations(divider, dividerState, delay, duration); + tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;; + stateAnimator.startViewAnimations(divider, tmpState, delay, duration); } else { firstChild = false; } stateAnimator.startStackAnimations(child, viewState, state, -1, delay); notGoneIndex++; } + if (mGroupOverflowContainer != null) { + stateAnimator.startViewAnimations(mGroupOverflowContainer, mGroupOverFlowState, -1, 0); + } } public ExpandableNotificationRow getViewAtPosition(float y) { @@ -375,7 +448,15 @@ public class NotificationChildrenContainer extends ViewGroup { return null; } - public void setTintColor(int color) { - ExpandableNotificationRow.applyTint(mCollapseDivider, color); + public void setChildrenExpanded(boolean childrenExpanded) { + mChildrenExpanded = childrenExpanded; + } + + public int getMaxContentHeight() { + return getIntrinsicHeight(NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED); + } + + public int getMinHeight() { + return getIntrinsicHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */)); } } 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 1b66073e7f1c8..573e45b1d87b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -1726,7 +1726,7 @@ public class NotificationStackScrollLayout extends ViewGroup ExpandableNotificationRow groupSummary = mGroupManager.getGroupSummary(row.getStatusBarNotification()); if (groupSummary != null && groupSummary != row) { - return !groupSummary.areChildrenExpanded(); + return row.getVisibility() == View.INVISIBLE; } } return false; @@ -2799,10 +2799,6 @@ public class NotificationStackScrollLayout extends ViewGroup onHeightChanged(changedRow, false /* needsAnimation */); } - @Override - public void onGroupsProhibitedChanged() { - } - @Override public void onGroupCreatedFromChildren(NotificationGroupManager.NotificationGroup group) { for (NotificationData.Entry entry : group.children) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index cf696a1208c94..65ca95bfd8d42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -361,7 +361,7 @@ public class StackScrollAlgorithm { // handle the notgoneIndex for the children as well List children = row.getNotificationChildren(); - if (row.areChildrenExpanded() && children != null) { + if (row.isSummaryWithChildren() && children != null) { for (ExpandableNotificationRow childRow : children) { if (childRow.getVisibility() != View.GONE) { StackViewState childState diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index 3768ca481772e..e155d70083131 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -65,7 +65,7 @@ public class StackScrollState { ExpandableNotificationRow row = (ExpandableNotificationRow) child; List children = row.getNotificationChildren(); - if (row.areChildrenExpanded() && children != null) { + if (row.isSummaryWithChildren() && children != null) { for (ExpandableNotificationRow childRow : children) { resetViewState(childRow); }