From 28f90c78b213fb436b243126e8bc10c4f554bd1c Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Mon, 8 May 2017 17:24:26 -0700 Subject: [PATCH] AOD: Update wakeup animation Fixes several issues with the wakeup transition. Bug: 34716110 Test: Trigger ambient display, press power button Change-Id: I1fa6e0be13c80a84356a8826ed18e9477bf2aba2 --- .../src/com/android/systemui/doze/DozeHost.java | 2 ++ .../src/com/android/systemui/doze/DozeUi.java | 13 ++++++++ .../statusbar/ActivatableNotificationView.java | 14 ++------- .../statusbar/ExpandableNotificationRow.java | 4 +++ .../systemui/statusbar/NotificationShelf.java | 2 +- .../statusbar/phone/NotificationIconContainer.java | 24 +++++++++++++-- .../systemui/statusbar/phone/StatusBar.java | 11 ++++++- .../systemui/statusbar/stack/AnimationFilter.java | 24 ++++++++------- .../stack/NotificationStackScrollLayout.java | 36 +++++++++++----------- .../statusbar/stack/StackStateAnimator.java | 19 +----------- .../systemui/statusbar/stack/ViewState.java | 6 ++-- .../com/android/systemui/doze/DozeHostFake.java | 10 ++++-- 12 files changed, 99 insertions(+), 66 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index ec56e15dbd8d..3e424d05373a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -36,6 +36,8 @@ public interface DozeHost { void abortPulsing(); void extendPulse(); + void setAnimateWakeup(boolean animateWakeup); + interface Callback { default void onNotificationHeadsUp() {} default void onPowerSaveChanged(boolean active) {} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 64a152e1ac15..ea33ebf764f1 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -95,6 +95,19 @@ public class DozeUi implements DozeMachine.Part { unscheduleTimeTick(); break; } + mHost.setAnimateWakeup(shouldAnimateWakeup(newState)); + } + + private boolean shouldAnimateWakeup(DozeMachine.State state) { + switch (state) { + case DOZE_AOD: + case DOZE_REQUEST_PULSE: + case DOZE_PULSING: + case DOZE_PULSE_DONE: + return true; + default: + return false; + } } private void scheduleTimeTick() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index b91561e01290..f5718d92198f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -50,7 +50,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220; private static final int ACTIVATE_ANIMATION_LENGTH = 220; - private static final int DARK_ANIMATION_LENGTH = 170; + private static final long DARK_ANIMATION_LENGTH = StackStateAnimator.ANIMATION_DURATION_WAKEUP; /** * The amount of width, which is kept in the end when performing a disappear animation (also @@ -418,7 +418,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } mDark = dark; updateBackground(); - updateBackgroundTint(fade); + updateBackgroundTint(false); if (!dark && fade && !shouldHideBackground()) { fadeInFromDark(delay); } @@ -555,23 +555,15 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView final View background = mDimmed ? mBackgroundDimmed : mBackgroundNormal; background.setAlpha(0f); mBackgroundVisibilityUpdater.onAnimationUpdate(null); - background.setPivotX(mBackgroundDimmed.getWidth() / 2f); - background.setPivotY(getActualHeight() / 2f); - background.setScaleX(DARK_EXIT_SCALE_START); - background.setScaleY(DARK_EXIT_SCALE_START); background.animate() .alpha(1f) - .scaleX(1f) - .scaleY(1f) .setDuration(DARK_ANIMATION_LENGTH) .setStartDelay(delay) - .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) + .setInterpolator(Interpolators.ALPHA_IN) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationCancel(Animator animation) { // Jump state if we are cancelled - background.setScaleX(1f); - background.setScaleY(1f); background.setAlpha(1f); } }) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 49d20a528c7d..3a39e9111be4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1368,6 +1368,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override public void setDark(boolean dark, boolean fade, long delay) { super.setDark(dark, fade, delay); + if (!mIsHeadsUp) { + // Only fade the showing view of the pulsing notification. + fade = false; + } final NotificationContentView showing = getShowingLayout(); if (showing != null) { showing.setDark(dark, fade, delay); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index f41670e0bdce..8e7ab57b08a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -427,7 +427,7 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState != null) { iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale(); iconState.scaleY = iconState.scaleX; - iconState.hidden = transitionAmount == 0.0f; + iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); iconState.alpha = alpha; iconState.yTranslation = iconYTranslation; if (stayingInShelf) { 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 930191e6d51d..9000eb4655d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -30,6 +30,7 @@ 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.StackStateAnimator; import com.android.systemui.statusbar.stack.ViewState; import java.util.HashMap; @@ -87,6 +88,16 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { return mAnimationFilter; } }.setDuration(200).setDelay(50); + + private static final AnimationProperties UNDARK_PROPERTIES = new AnimationProperties() { + private AnimationFilter mAnimationFilter = new AnimationFilter() + .animateX(); + + @Override + public AnimationFilter getAnimationFilter() { + return mAnimationFilter; + } + }.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); public static final int MAX_VISIBLE_ICONS_WHEN_DARK = 5; private boolean mShowAllIcons = true; @@ -404,11 +415,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public void setDark(boolean dark, boolean fade, long delay) { mDark = dark; - mDisallowNextAnimation = true; + mDisallowNextAnimation |= !fade; for (int i = 0; i < getChildCount(); i++) { View view = getChildAt(i); if (view instanceof StatusBarIconView) { ((StatusBarIconView) view).setDark(dark, fade, delay); + if (!dark && fade) { + getIconState((StatusBarIconView) view).justUndarkened = true; + } } } } @@ -465,6 +479,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean useFullTransitionAmount; public boolean useLinearTransitionAmount; public boolean translateContent; + public boolean justUndarkened; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; @@ -474,7 +489,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { StatusBarIconView icon = (StatusBarIconView) view; boolean animate = false; AnimationProperties animationProperties = null; - boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation + boolean animationsAllowed = (mAnimationsEnabled || justUndarkened) + && !mDisallowNextAnimation && !noAnimations; if (animationsAllowed) { if (justAdded) { @@ -486,6 +502,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { animationProperties = ADD_ICON_PROPERTIES; animate = true; } + } else if (justUndarkened) { + animationProperties = UNDARK_PROPERTIES; + animate = true; } else if (visibleState != icon.getVisibleState()) { animationProperties = DOT_ANIMATION_PROPERTIES; animate = true; @@ -536,6 +555,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } justAdded = false; needsCannedAnimation = false; + justUndarkened = false; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index b33d50931d81..a597e5b2ad39 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -4355,7 +4355,7 @@ public class StatusBar extends SystemUI implements DemoMode, private void updateDozingState() { Trace.beginSection("StatusBar#updateDozingState"); - boolean animate = !mDozing && mDozeScrimController.isPulsing(); + boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup(); mNotificationPanel.setDozing(mDozing, animate); mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation); mScrimController.setDozing(mDozing); @@ -5007,6 +5007,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final class DozeServiceHost implements DozeHost { private final ArrayList mCallbacks = new ArrayList(); + private boolean mAnimateWakeup; @Override public String toString() { @@ -5114,6 +5115,14 @@ public class StatusBar extends SystemUI implements DemoMode, mDozeScrimController.extendPulse(); } + @Override + public void setAnimateWakeup(boolean animateWakeup) { + mAnimateWakeup = animateWakeup; + } + + private boolean shouldAnimateWakeup() { + return mAnimateWakeup; + } } // Begin Extra BaseStatusBar methods. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java index 34fa658c85e1..53377d955722 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java @@ -21,7 +21,7 @@ import android.util.Property; import android.view.View; import java.util.ArrayList; -import java.util.HashSet; +import java.util.Set; /** * Filters the animations for only a certain type of properties. @@ -30,6 +30,7 @@ public class AnimationFilter { boolean animateAlpha; boolean animateX; boolean animateY; + ArraySet animateYViews = new ArraySet<>(); boolean animateZ; boolean animateHeight; boolean animateTopInset; @@ -39,9 +40,7 @@ public class AnimationFilter { public boolean animateShadowAlpha; boolean hasDelays; boolean hasGoToFullShadeEvent; - boolean hasDarkEvent; boolean hasHeadsUpDisappearClickEvent; - int darkAnimationOriginIndex; private ArraySet mAnimatedProperties = new ArraySet<>(); public AnimationFilter animateAlpha() { @@ -105,6 +104,15 @@ public class AnimationFilter { return this; } + public AnimationFilter animateY(View view) { + animateYViews.add(view); + return this; + } + + public boolean shouldAnimateY(View view) { + return animateY || animateYViews.contains(view); + } + /** * Combines multiple filters into {@code this} filter, using or as the operand . * @@ -120,11 +128,6 @@ public class AnimationFilter { NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) { hasGoToFullShadeEvent = true; } - if (ev.animationType == - NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_DARK) { - hasDarkEvent = true; - darkAnimationOriginIndex = ev.darkAnimationOriginIndex; - } if (ev.animationType == NotificationStackScrollLayout.AnimationEvent .ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) { hasHeadsUpDisappearClickEvent = true; @@ -136,6 +139,7 @@ public class AnimationFilter { animateAlpha |= filter.animateAlpha; animateX |= filter.animateX; animateY |= filter.animateY; + animateYViews.addAll(filter.animateYViews); animateZ |= filter.animateZ; animateHeight |= filter.animateHeight; animateTopInset |= filter.animateTopInset; @@ -151,6 +155,7 @@ public class AnimationFilter { animateAlpha = false; animateX = false; animateY = false; + animateYViews.clear(); animateZ = false; animateHeight = false; animateShadowAlpha = false; @@ -160,10 +165,7 @@ public class AnimationFilter { animateHideSensitive = false; hasDelays = false; hasGoToFullShadeEvent = false; - hasDarkEvent = false; hasHeadsUpDisappearClickEvent = false; - darkAnimationOriginIndex = - NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE; mAnimatedProperties.clear(); } 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 5f83e3d0a519..2f7a4ed5afdb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -53,6 +53,7 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.OverScroller; @@ -3119,7 +3120,11 @@ public class NotificationStackScrollLayout extends ViewGroup private void generateDarkEvent() { if (mDarkNeedsAnimation) { - AnimationEvent ev = new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_DARK); + AnimationEvent ev = new AnimationEvent(null, + AnimationEvent.ANIMATION_TYPE_DARK, + new AnimationFilter() + .animateDark() + .animateY(mShelf)); ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex; mAnimationEvents.add(ev); startBackgroundFadeIn(); @@ -3701,18 +3706,7 @@ public class NotificationStackScrollLayout extends ViewGroup private void startBackgroundFadeIn() { ObjectAnimator fadeAnimator = ObjectAnimator.ofFloat(this, BACKGROUND_FADE, 0f, 1f); - int maxLength; - if (mDarkAnimationOriginIndex == AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE - || mDarkAnimationOriginIndex == AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW) { - maxLength = getNotGoneChildCount() - 1; - } else { - maxLength = Math.max(mDarkAnimationOriginIndex, - getNotGoneChildCount() - mDarkAnimationOriginIndex - 1); - } - maxLength = Math.max(0, maxLength); - long delay = maxLength * StackStateAnimator.ANIMATION_DELAY_PER_ELEMENT_DARK; - fadeAnimator.setStartDelay(delay); - fadeAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); + fadeAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); fadeAnimator.setInterpolator(Interpolators.ALPHA_IN); fadeAnimator.start(); } @@ -4563,9 +4557,7 @@ public class NotificationStackScrollLayout extends ViewGroup .animateZ(), // ANIMATION_TYPE_DARK - new AnimationFilter() - .animateDark() - .hasDelays(), + null, // Unused // ANIMATION_TYPE_GO_TO_FULL_SHADE new AnimationFilter() @@ -4674,7 +4666,7 @@ public class NotificationStackScrollLayout extends ViewGroup StackStateAnimator.ANIMATION_DURATION_STANDARD, // ANIMATION_TYPE_DARK - StackStateAnimator.ANIMATION_DURATION_STANDARD, + StackStateAnimator.ANIMATION_DURATION_WAKEUP, // ANIMATION_TYPE_GO_TO_FULL_SHADE StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, @@ -4740,12 +4732,20 @@ public class NotificationStackScrollLayout extends ViewGroup this(view, type, LENGTHS[type]); } + AnimationEvent(View view, int type, AnimationFilter filter) { + this(view, type, LENGTHS[type], filter); + } + AnimationEvent(View view, int type, long length) { + this(view, type, length, FILTERS[type]); + } + + AnimationEvent(View view, int type, long length, AnimationFilter filter) { eventStartTime = AnimationUtils.currentAnimationTimeMillis(); changingView = view; animationType = type; - filter = FILTERS[type]; this.length = length; + this.filter = filter; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index 98934341b41e..f78a718eff9f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -40,6 +40,7 @@ import java.util.Stack; public class StackStateAnimator { public static final int ANIMATION_DURATION_STANDARD = 360; + public static final int ANIMATION_DURATION_WAKEUP = 200; public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448; public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464; public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220; @@ -49,7 +50,6 @@ public class StackStateAnimator { public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80; public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32; public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48; - public static final int ANIMATION_DELAY_PER_ELEMENT_DARK = 24; public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2; public static final int ANIMATION_DELAY_HEADS_UP = 120; @@ -219,9 +219,6 @@ public class StackStateAnimator { private long calculateChildAnimationDelay(ExpandableViewState viewState, StackScrollState finalState) { - if (mAnimationFilter.hasDarkEvent) { - return calculateDelayDark(viewState); - } if (mAnimationFilter.hasGoToFullShadeEvent) { return calculateDelayGoToFullShade(viewState); } @@ -278,20 +275,6 @@ public class StackStateAnimator { return minDelay; } - private long calculateDelayDark(ExpandableViewState viewState) { - int referenceIndex; - if (mAnimationFilter.darkAnimationOriginIndex == - NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE) { - referenceIndex = 0; - } else if (mAnimationFilter.darkAnimationOriginIndex == - NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW) { - referenceIndex = mHostLayout.getNotGoneChildCount() - 1; - } else { - referenceIndex = mAnimationFilter.darkAnimationOriginIndex; - } - return Math.abs(referenceIndex - viewState.notGoneIndex) * ANIMATION_DELAY_PER_ELEMENT_DARK; - } - private long calculateDelayGoToFullShade(ExpandableViewState viewState) { int shelfIndex = mShelf.getNotGoneIndex(); float index = viewState.notGoneIndex; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java index 5b594be507d2..d664b1239519 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java @@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; +import android.app.Notification; import android.util.Property; import android.view.View; import android.view.animation.Interpolator; @@ -28,6 +29,7 @@ import android.view.animation.Interpolator; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.ExpandableView; +import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -223,7 +225,7 @@ public class ViewState { } } - protected boolean isAnimating(View view) { + public boolean isAnimating(View view) { if (isAnimating(view, TAG_ANIMATOR_TRANSLATION_X)) { return true; } @@ -540,7 +542,7 @@ public class ViewState { } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y); AnimationFilter filter = properties.getAnimationFilter(); - if (!filter.animateY) { + if (!filter.shouldAnimateY(child)) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java index d2afa2aae28a..ee0fe7b85c89 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java @@ -24,8 +24,9 @@ import android.app.PendingIntent; */ class DozeHostFake implements DozeHost { Callback callback; - private boolean pulseAborted; - private boolean pulseExtended; + boolean pulseAborted; + boolean pulseExtended; + boolean animateWakeup; @Override public void addCallback(@NonNull Callback callback) { @@ -81,4 +82,9 @@ class DozeHostFake implements DozeHost { public void extendPulse() { pulseExtended = true; } + + @Override + public void setAnimateWakeup(boolean animateWakeup) { + this.animateWakeup = animateWakeup; + } } -- 2.11.0