AOD: Update wakeup animation
Fixes several issues with the wakeup transition.
Bug: 34716110
Test: Trigger ambient display, press power button
Change-Id: I1fa6e0be13c80a84356a8826ed18e9477bf2aba2
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index ec56e15..3e424d0 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 @@
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 64a152e..ea33ebf 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 @@
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 b91561e..f5718d9 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 @@
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 @@
}
mDark = dark;
updateBackground();
- updateBackgroundTint(fade);
+ updateBackgroundTint(false);
if (!dark && fade && !shouldHideBackground()) {
fadeInFromDark(delay);
}
@@ -555,23 +555,15 @@
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 49d20a5..3a39e91 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 @@
@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 f41670e..8e7ab57 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 @@
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 930191e..9000eb4 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.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 @@
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 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 boolean useFullTransitionAmount;
public boolean useLinearTransitionAmount;
public boolean translateContent;
+ public boolean justUndarkened;
public int iconColor = StatusBarIconView.NO_COLOR;
public boolean noAnimations;
@@ -474,7 +489,8 @@
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 @@
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 @@
}
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 b33d509..a597e5b 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 @@
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 @@
private final class DozeServiceHost implements DozeHost {
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+ private boolean mAnimateWakeup;
@Override
public String toString() {
@@ -5114,6 +5115,14 @@
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 34fa658..53377d9 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.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 @@
boolean animateAlpha;
boolean animateX;
boolean animateY;
+ ArraySet<View> animateYViews = new ArraySet<>();
boolean animateZ;
boolean animateHeight;
boolean animateTopInset;
@@ -39,9 +40,7 @@
public boolean animateShadowAlpha;
boolean hasDelays;
boolean hasGoToFullShadeEvent;
- boolean hasDarkEvent;
boolean hasHeadsUpDisappearClickEvent;
- int darkAnimationOriginIndex;
private ArraySet<Property> mAnimatedProperties = new ArraySet<>();
public AnimationFilter animateAlpha() {
@@ -105,6 +104,15 @@
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 @@
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 @@
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 @@
animateAlpha = false;
animateX = false;
animateY = false;
+ animateYViews.clear();
animateZ = false;
animateHeight = false;
animateShadowAlpha = false;
@@ -160,10 +165,7 @@
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 5f83e3d..2f7a4ed 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.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 @@
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 @@
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 @@
.animateZ(),
// ANIMATION_TYPE_DARK
- new AnimationFilter()
- .animateDark()
- .hasDelays(),
+ null, // Unused
// ANIMATION_TYPE_GO_TO_FULL_SHADE
new AnimationFilter()
@@ -4674,7 +4666,7 @@
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 @@
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 9893434..f78a718 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 @@
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 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 @@
private long calculateChildAnimationDelay(ExpandableViewState viewState,
StackScrollState finalState) {
- if (mAnimationFilter.hasDarkEvent) {
- return calculateDelayDark(viewState);
- }
if (mAnimationFilter.hasGoToFullShadeEvent) {
return calculateDelayGoToFullShade(viewState);
}
@@ -278,20 +275,6 @@
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 5b594be..d664b12 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.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 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 @@
}
}
- protected boolean isAnimating(View view) {
+ public boolean isAnimating(View view) {
if (isAnimating(view, TAG_ANIMATOR_TRANSLATION_X)) {
return true;
}
@@ -540,7 +542,7 @@
}
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 d2afa2a..ee0fe7b 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 @@
*/
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 @@
public void extendPulse() {
pulseExtended = true;
}
+
+ @Override
+ public void setAnimateWakeup(boolean animateWakeup) {
+ this.animateWakeup = animateWakeup;
+ }
}