Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +47 −7 Original line number Diff line number Diff line Loading @@ -519,27 +519,67 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable { return mChangingPosition; } /** * Called when removing a view from its transient container, such as at the end of an animation. * Generally, when operating on ExpandableView instances, this should be used rather than * {@link ExpandableView#removeTransientView(View)} to ensure that the * {@link #getTransientContainer() transient container} is correctly reset. */ public void removeFromTransientContainer() { final ViewGroup transientContainer = getTransientContainer(); if (transientContainer == null) { return; } final ViewParent parent = getParent(); if (parent != transientContainer) { Log.w(TAG, "Expandable view " + this + " has transient container " + transientContainer + " but different parent " + parent); setTransientContainer(null); return; } transientContainer.removeTransientView(this); setTransientContainer(null); } /** * Called before adding this view to a group, which would always throw an exception if this view * has a parent, so clean up the transient container and throw an exception if the parent isn't * a transient container. Provide as much detail in the event of a crash as possible. * has a different parent, so clean up the transient container and throw an exception if the * parent isn't a transient container. Provide as much detail as possible in the crash. */ public void removeFromTransientContainerForAdditionTo(ViewGroup newParent) { final ViewParent parent = getParent(); final ViewGroup transientContainer = getTransientContainer(); if (parent == null) { // If this view has no parent, the add will succeed, so do nothing. // If this view has no parent, the add will succeed, so just make sure the tracked // transient container is in sync with the lack of a parent. if (transientContainer != null) { Log.w(TAG, "Expandable view " + this + " has transient container " + transientContainer + " but no parent"); setTransientContainer(null); } return; } ViewGroup transientContainer = getTransientContainer(); if (transientContainer == null) { throw new IllegalStateException( "Can't add view " + this + " to container " + newParent + "; current parent " + parent + " is not a transient container"); } if (transientContainer != parent) { throw new IllegalStateException( "Expandable view " + this + " has transient container " + transientContainer + " which is not the same as its parent " + parent); String transientContainerOutOfSyncError = "Expandable view " + this + " has transient container " + transientContainer + " but different parent " + parent; if (parent != newParent) { // Crash with details before addView() crashes without any; the view is being added // to a different parent, and the transient container isn't the parent, so we can't // even (safely) clean that up. throw new IllegalStateException(transientContainerOutOfSyncError); } else { Log.w(TAG, transientContainerOutOfSyncError); setTransientContainer(null); return; } } if (parent != newParent) { Log.w(TAG, "Moving view " + this + " from transient container " Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +1 −2 Original line number Diff line number Diff line Loading @@ -215,8 +215,7 @@ class NotificationSectionsManager @Inject internal constructor( // TODO: We should really cancel the active animations here. This will // happen automatically when the view's intro animation starts, but // it's a fragile link. header.transientContainer?.removeTransientView(header) header.transientContainer = null header.removeFromTransientContainer() parent.addView(header, target) } else { parent.changeViewPosition(header, target) Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +7 −6 Original line number Diff line number Diff line Loading @@ -3213,10 +3213,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // Clean up any potential transient views if the child has already been swiped // out, as we won't be animating it further (due to its height already being // clipped to 0. ViewGroup transientContainer = child.getTransientContainer(); if (transientContainer != null) { transientContainer.removeTransientView(child); } child.removeFromTransientContainer(); } } int animationType = childWasSwipedOut Loading Loading @@ -3933,7 +3930,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private void clearTemporaryViewsInGroup(ViewGroup viewGroup) { while (viewGroup != null && viewGroup.getTransientViewCount() != 0) { viewGroup.removeTransientView(viewGroup.getTransientView(0)); final View transientView = viewGroup.getTransientView(0); viewGroup.removeTransientView(transientView); if (transientView instanceof ExpandableView) { ((ExpandableView) transientView).setTransientContainer(null); } } } Loading Loading @@ -4102,7 +4103,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private void clearTransient() { for (ExpandableView view : mClearTransientViewsWhenFinished) { StackStateAnimator.removeTransientView(view); view.removeFromTransientContainer(); } mClearTransientViewsWhenFinished.clear(); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +1 −4 Original line number Diff line number Diff line Loading @@ -455,10 +455,7 @@ public class NotificationStackScrollLayoutController { if (!row.isDismissed()) { handleChildViewDismissed(view); } ViewGroup transientContainer = row.getTransientContainer(); if (transientContainer != null) { transientContainer.removeTransientView(view); } row.removeFromTransientContainer(); } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +7 −15 Original line number Diff line number Diff line Loading @@ -322,9 +322,8 @@ public class StackStateAnimator { private void onAnimationFinished() { mHostLayout.onChildAnimationFinished(); for (ExpandableView transientViewsToRemove : mTransientViewsToRemove) { transientViewsToRemove.getTransientContainer() .removeTransientView(transientViewsToRemove); for (ExpandableView transientViewToRemove : mTransientViewsToRemove) { transientViewToRemove.removeFromTransientContainer(); } mTransientViewsToRemove.clear(); } Loading Loading @@ -353,7 +352,7 @@ public class StackStateAnimator { } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE) { if (changingView.getVisibility() != View.VISIBLE) { removeTransientView(changingView); changingView.removeFromTransientContainer(); continue; } Loading Loading @@ -390,12 +389,11 @@ public class StackStateAnimator { } changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR, 0 /* delay */, translationDirection, false /* isHeadsUpAppear */, 0, () -> removeTransientView(changingView), null); 0, changingView::removeFromTransientContainer, null); } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) { if (mHostLayout.isFullySwipedOut(changingView) && changingView.getTransientContainer() != null) { changingView.getTransientContainer().removeTransientView(changingView); if (mHostLayout.isFullySwipedOut(changingView)) { changingView.removeFromTransientContainer(); } } else if (event.animationType == NotificationStackScrollLayout .AnimationEvent.ANIMATION_TYPE_GROUP_EXPANSION_CHANGED) { Loading Loading @@ -425,7 +423,7 @@ public class StackStateAnimator { mHostLayout.addTransientView(changingView, 0); changingView.setTransientContainer(mHostLayout); mTmpState.initFrom(changingView); endRunnable = () -> removeTransientView(changingView); endRunnable = changingView::removeFromTransientContainer; } float targetLocation = 0; boolean needsAnimation = true; Loading Loading @@ -468,12 +466,6 @@ public class StackStateAnimator { } } public static void removeTransientView(ExpandableView viewToRemove) { if (viewToRemove.getTransientContainer() != null) { viewToRemove.getTransientContainer().removeTransientView(viewToRemove); } } public void animateOverScrollToAmount(float targetAmount, final boolean onTop, final boolean isRubberbanded) { final float startOverScrollAmount = mHostLayout.getCurrentOverScrollAmount(onTop); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +47 −7 Original line number Diff line number Diff line Loading @@ -519,27 +519,67 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable { return mChangingPosition; } /** * Called when removing a view from its transient container, such as at the end of an animation. * Generally, when operating on ExpandableView instances, this should be used rather than * {@link ExpandableView#removeTransientView(View)} to ensure that the * {@link #getTransientContainer() transient container} is correctly reset. */ public void removeFromTransientContainer() { final ViewGroup transientContainer = getTransientContainer(); if (transientContainer == null) { return; } final ViewParent parent = getParent(); if (parent != transientContainer) { Log.w(TAG, "Expandable view " + this + " has transient container " + transientContainer + " but different parent " + parent); setTransientContainer(null); return; } transientContainer.removeTransientView(this); setTransientContainer(null); } /** * Called before adding this view to a group, which would always throw an exception if this view * has a parent, so clean up the transient container and throw an exception if the parent isn't * a transient container. Provide as much detail in the event of a crash as possible. * has a different parent, so clean up the transient container and throw an exception if the * parent isn't a transient container. Provide as much detail as possible in the crash. */ public void removeFromTransientContainerForAdditionTo(ViewGroup newParent) { final ViewParent parent = getParent(); final ViewGroup transientContainer = getTransientContainer(); if (parent == null) { // If this view has no parent, the add will succeed, so do nothing. // If this view has no parent, the add will succeed, so just make sure the tracked // transient container is in sync with the lack of a parent. if (transientContainer != null) { Log.w(TAG, "Expandable view " + this + " has transient container " + transientContainer + " but no parent"); setTransientContainer(null); } return; } ViewGroup transientContainer = getTransientContainer(); if (transientContainer == null) { throw new IllegalStateException( "Can't add view " + this + " to container " + newParent + "; current parent " + parent + " is not a transient container"); } if (transientContainer != parent) { throw new IllegalStateException( "Expandable view " + this + " has transient container " + transientContainer + " which is not the same as its parent " + parent); String transientContainerOutOfSyncError = "Expandable view " + this + " has transient container " + transientContainer + " but different parent " + parent; if (parent != newParent) { // Crash with details before addView() crashes without any; the view is being added // to a different parent, and the transient container isn't the parent, so we can't // even (safely) clean that up. throw new IllegalStateException(transientContainerOutOfSyncError); } else { Log.w(TAG, transientContainerOutOfSyncError); setTransientContainer(null); return; } } if (parent != newParent) { Log.w(TAG, "Moving view " + this + " from transient container " Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +1 −2 Original line number Diff line number Diff line Loading @@ -215,8 +215,7 @@ class NotificationSectionsManager @Inject internal constructor( // TODO: We should really cancel the active animations here. This will // happen automatically when the view's intro animation starts, but // it's a fragile link. header.transientContainer?.removeTransientView(header) header.transientContainer = null header.removeFromTransientContainer() parent.addView(header, target) } else { parent.changeViewPosition(header, target) Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +7 −6 Original line number Diff line number Diff line Loading @@ -3213,10 +3213,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // Clean up any potential transient views if the child has already been swiped // out, as we won't be animating it further (due to its height already being // clipped to 0. ViewGroup transientContainer = child.getTransientContainer(); if (transientContainer != null) { transientContainer.removeTransientView(child); } child.removeFromTransientContainer(); } } int animationType = childWasSwipedOut Loading Loading @@ -3933,7 +3930,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private void clearTemporaryViewsInGroup(ViewGroup viewGroup) { while (viewGroup != null && viewGroup.getTransientViewCount() != 0) { viewGroup.removeTransientView(viewGroup.getTransientView(0)); final View transientView = viewGroup.getTransientView(0); viewGroup.removeTransientView(transientView); if (transientView instanceof ExpandableView) { ((ExpandableView) transientView).setTransientContainer(null); } } } Loading Loading @@ -4102,7 +4103,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private void clearTransient() { for (ExpandableView view : mClearTransientViewsWhenFinished) { StackStateAnimator.removeTransientView(view); view.removeFromTransientContainer(); } mClearTransientViewsWhenFinished.clear(); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +1 −4 Original line number Diff line number Diff line Loading @@ -455,10 +455,7 @@ public class NotificationStackScrollLayoutController { if (!row.isDismissed()) { handleChildViewDismissed(view); } ViewGroup transientContainer = row.getTransientContainer(); if (transientContainer != null) { transientContainer.removeTransientView(view); } row.removeFromTransientContainer(); } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +7 −15 Original line number Diff line number Diff line Loading @@ -322,9 +322,8 @@ public class StackStateAnimator { private void onAnimationFinished() { mHostLayout.onChildAnimationFinished(); for (ExpandableView transientViewsToRemove : mTransientViewsToRemove) { transientViewsToRemove.getTransientContainer() .removeTransientView(transientViewsToRemove); for (ExpandableView transientViewToRemove : mTransientViewsToRemove) { transientViewToRemove.removeFromTransientContainer(); } mTransientViewsToRemove.clear(); } Loading Loading @@ -353,7 +352,7 @@ public class StackStateAnimator { } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE) { if (changingView.getVisibility() != View.VISIBLE) { removeTransientView(changingView); changingView.removeFromTransientContainer(); continue; } Loading Loading @@ -390,12 +389,11 @@ public class StackStateAnimator { } changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR, 0 /* delay */, translationDirection, false /* isHeadsUpAppear */, 0, () -> removeTransientView(changingView), null); 0, changingView::removeFromTransientContainer, null); } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) { if (mHostLayout.isFullySwipedOut(changingView) && changingView.getTransientContainer() != null) { changingView.getTransientContainer().removeTransientView(changingView); if (mHostLayout.isFullySwipedOut(changingView)) { changingView.removeFromTransientContainer(); } } else if (event.animationType == NotificationStackScrollLayout .AnimationEvent.ANIMATION_TYPE_GROUP_EXPANSION_CHANGED) { Loading Loading @@ -425,7 +423,7 @@ public class StackStateAnimator { mHostLayout.addTransientView(changingView, 0); changingView.setTransientContainer(mHostLayout); mTmpState.initFrom(changingView); endRunnable = () -> removeTransientView(changingView); endRunnable = changingView::removeFromTransientContainer; } float targetLocation = 0; boolean needsAnimation = true; Loading Loading @@ -468,12 +466,6 @@ public class StackStateAnimator { } } public static void removeTransientView(ExpandableView viewToRemove) { if (viewToRemove.getTransientContainer() != null) { viewToRemove.getTransientContainer().removeTransientView(viewToRemove); } } public void animateOverScrollToAmount(float targetAmount, final boolean onTop, final boolean isRubberbanded) { final float startOverScrollAmount = mHostLayout.getCurrentOverScrollAmount(onTop); Loading