Merge "Hold a wake-lock for battery % changes in AOD" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b81195b5fb
@@ -599,10 +599,6 @@ public class KeyguardIndicationController {
|
||||
mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
||||
if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
|
||||
// Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
|
||||
mWakeLock.setAcquired(true);
|
||||
}
|
||||
hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
|
||||
|
||||
updateIndication(false);
|
||||
@@ -622,10 +618,6 @@ public class KeyguardIndicationController {
|
||||
}
|
||||
|
||||
protected final void updateIndication(boolean animate) {
|
||||
if (TextUtils.isEmpty(mTransientIndication)) {
|
||||
mWakeLock.setAcquired(false);
|
||||
}
|
||||
|
||||
if (!mVisible) {
|
||||
return;
|
||||
}
|
||||
@@ -643,24 +635,31 @@ public class KeyguardIndicationController {
|
||||
// colors can be hard to read in low brightness.
|
||||
mTopIndicationView.setTextColor(Color.WHITE);
|
||||
if (!TextUtils.isEmpty(mTransientIndication)) {
|
||||
mTopIndicationView.switchIndication(mTransientIndication, null);
|
||||
mWakeLock.setAcquired(true);
|
||||
mTopIndicationView.switchIndication(mTransientIndication, null,
|
||||
true, () -> mWakeLock.setAcquired(false));
|
||||
} else if (!mBatteryPresent) {
|
||||
// If there is no battery detected, hide the indication and bail
|
||||
mIndicationArea.setVisibility(GONE);
|
||||
} else if (!TextUtils.isEmpty(mAlignmentIndication)) {
|
||||
mTopIndicationView.switchIndication(mAlignmentIndication, null);
|
||||
mTopIndicationView.switchIndication(mAlignmentIndication, null,
|
||||
false /* animate */, null /* onAnimationEndCallback */);
|
||||
mTopIndicationView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
|
||||
} else if (mPowerPluggedIn || mEnableBatteryDefender) {
|
||||
String indication = computePowerIndication();
|
||||
if (animate) {
|
||||
animateText(mTopIndicationView, indication);
|
||||
mWakeLock.setAcquired(true);
|
||||
mTopIndicationView.switchIndication(indication, null, true /* animate */,
|
||||
() -> mWakeLock.setAcquired(false));
|
||||
} else {
|
||||
mTopIndicationView.switchIndication(indication, null);
|
||||
mTopIndicationView.switchIndication(indication, null, false /* animate */,
|
||||
null /* onAnimationEndCallback */);
|
||||
}
|
||||
} else {
|
||||
String percentage = NumberFormat.getPercentInstance()
|
||||
.format(mBatteryLevel / 100f);
|
||||
mTopIndicationView.switchIndication(percentage, null);
|
||||
mTopIndicationView.switchIndication(percentage, null /* indication */,
|
||||
false /* animate */, null /* onAnimationEnd*/);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -95,44 +95,85 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text with an animation and makes sure a single indication is shown long enough.
|
||||
* Changes the text with an animation. Makes sure a single indication is shown long enough.
|
||||
*/
|
||||
public void switchIndication(CharSequence text, KeyguardIndication indication) {
|
||||
switchIndication(text, indication, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text with an optional animation. For animating text, makes sure a single
|
||||
* indication is shown long enough.
|
||||
*
|
||||
* @param text The text to show.
|
||||
* @param indication optional display information for the text
|
||||
* @param animate whether to animate this indication in - we may not want this on AOD
|
||||
* @param onAnimationEndCallback runnable called after this indication is animated in
|
||||
*/
|
||||
public void switchIndication(CharSequence text, KeyguardIndication indication) {
|
||||
public void switchIndication(CharSequence text, KeyguardIndication indication,
|
||||
boolean animate, Runnable onAnimationEndCallback) {
|
||||
if (text == null) text = "";
|
||||
|
||||
CharSequence lastPendingMessage = mMessages.peekLast();
|
||||
if (TextUtils.equals(lastPendingMessage, text)
|
||||
|| (lastPendingMessage == null && TextUtils.equals(text, getText()))) {
|
||||
if (onAnimationEndCallback != null) {
|
||||
onAnimationEndCallback.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
mMessages.add(text);
|
||||
mKeyguardIndicationInfo.add(indication);
|
||||
|
||||
final boolean hasIcon = indication != null && indication.getIcon() != null;
|
||||
final AnimatorSet animSet = new AnimatorSet();
|
||||
final AnimatorSet.Builder animSetBuilder = animSet.play(getOutAnimator());
|
||||
if (animate) {
|
||||
final boolean hasIcon = indication != null && indication.getIcon() != null;
|
||||
final AnimatorSet animator = new AnimatorSet();
|
||||
// Make sure each animation is visible for a minimum amount of time, while not worrying
|
||||
// about fading in blank text
|
||||
long timeInMillis = System.currentTimeMillis();
|
||||
long delay = Math.max(0, mNextAnimationTime - timeInMillis);
|
||||
setNextAnimationTime(timeInMillis + delay + getFadeOutDuration());
|
||||
final long minDurationMillis =
|
||||
(indication != null && indication.getMinVisibilityMillis() != null)
|
||||
? indication.getMinVisibilityMillis()
|
||||
: MSG_MIN_DURATION_MILLIS_DEFAULT;
|
||||
if (!text.equals("") || hasIcon) {
|
||||
setNextAnimationTime(mNextAnimationTime + minDurationMillis);
|
||||
Animator inAnimator = getInAnimator();
|
||||
inAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
if (onAnimationEndCallback != null) {
|
||||
onAnimationEndCallback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.playSequentially(getOutAnimator(), inAnimator);
|
||||
} else {
|
||||
Animator outAnimator = getOutAnimator();
|
||||
outAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
if (onAnimationEndCallback != null) {
|
||||
onAnimationEndCallback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.play(outAnimator);
|
||||
}
|
||||
|
||||
// Make sure each animation is visible for a minimum amount of time, while not worrying
|
||||
// about fading in blank text
|
||||
long timeInMillis = System.currentTimeMillis();
|
||||
long delay = Math.max(0, mNextAnimationTime - timeInMillis);
|
||||
setNextAnimationTime(timeInMillis + delay + getFadeOutDuration());
|
||||
|
||||
final long minDurationMillis =
|
||||
(indication != null && indication.getMinVisibilityMillis() != null)
|
||||
? indication.getMinVisibilityMillis()
|
||||
: MSG_MIN_DURATION_MILLIS_DEFAULT;
|
||||
|
||||
if (!text.equals("") || hasIcon) {
|
||||
setNextAnimationTime(mNextAnimationTime + minDurationMillis);
|
||||
animSetBuilder.before(getInAnimator());
|
||||
animator.setStartDelay(delay);
|
||||
animator.start();
|
||||
} else {
|
||||
setAlpha(1f);
|
||||
setTranslationY(0f);
|
||||
setNextIndication();
|
||||
if (onAnimationEndCallback != null) {
|
||||
onAnimationEndCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
animSet.setStartDelay(delay);
|
||||
animSet.start();
|
||||
}
|
||||
|
||||
private AnimatorSet getOutAnimator() {
|
||||
@@ -143,29 +184,8 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
fadeOut.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
KeyguardIndication info = mKeyguardIndicationInfo.poll();
|
||||
if (info != null) {
|
||||
// First, update the style.
|
||||
// If a background is set on the text, we don't want shadow on the text
|
||||
if (info.getBackground() != null) {
|
||||
setTextAppearance(sButtonStyleId);
|
||||
} else {
|
||||
setTextAppearance(sStyleId);
|
||||
}
|
||||
setBackground(info.getBackground());
|
||||
setTextColor(info.getTextColor());
|
||||
setOnClickListener(info.getClickListener());
|
||||
setClickable(info.getClickListener() != null);
|
||||
final Drawable icon = info.getIcon();
|
||||
if (icon != null) {
|
||||
icon.setTint(getCurrentTextColor());
|
||||
if (icon instanceof AnimatedVectorDrawable) {
|
||||
((AnimatedVectorDrawable) icon).start();
|
||||
}
|
||||
}
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
|
||||
}
|
||||
setText(mMessages.poll());
|
||||
super.onAnimationEnd(animator);
|
||||
setNextIndication();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -177,6 +197,32 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
private void setNextIndication() {
|
||||
KeyguardIndication info = mKeyguardIndicationInfo.poll();
|
||||
if (info != null) {
|
||||
// First, update the style.
|
||||
// If a background is set on the text, we don't want shadow on the text
|
||||
if (info.getBackground() != null) {
|
||||
setTextAppearance(sButtonStyleId);
|
||||
} else {
|
||||
setTextAppearance(sStyleId);
|
||||
}
|
||||
setBackground(info.getBackground());
|
||||
setTextColor(info.getTextColor());
|
||||
setOnClickListener(info.getClickListener());
|
||||
setClickable(info.getClickListener() != null);
|
||||
final Drawable icon = info.getIcon();
|
||||
if (icon != null) {
|
||||
icon.setTint(getCurrentTextColor());
|
||||
if (icon instanceof AnimatedVectorDrawable) {
|
||||
((AnimatedVectorDrawable) icon).start();
|
||||
}
|
||||
}
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
|
||||
}
|
||||
setText(mMessages.poll());
|
||||
}
|
||||
|
||||
private AnimatorSet getInAnimator() {
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(this, View.ALPHA, 1f);
|
||||
@@ -190,6 +236,7 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
yTranslate.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
super.onAnimationCancel(animation);
|
||||
setTranslationY(0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,7 +166,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
private BroadcastReceiver mBroadcastReceiver;
|
||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
private KeyguardIndicationTextView mTextView;
|
||||
private KeyguardIndicationTextView mTextView; // AOD text
|
||||
|
||||
private KeyguardIndicationController mController;
|
||||
private WakeLockFake.Builder mWakeLockBuilder;
|
||||
@@ -412,41 +412,32 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void transientIndication_holdsWakeLock_whenDozing() {
|
||||
// GIVEN animations are enabled and text is visible
|
||||
mTextView.setAnimationsEnabled(true);
|
||||
createController();
|
||||
mController.setVisible(true);
|
||||
|
||||
// WHEN transient text is shown
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
mController.showTransientIndication("Test");
|
||||
|
||||
assertTrue(mWakeLock.isHeld());
|
||||
// THEN wake lock is held while the animation is running
|
||||
assertTrue("WakeLock expected: HELD, was: RELEASED", mWakeLock.isHeld());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transientIndication_releasesWakeLock_afterHiding() {
|
||||
public void transientIndication_releasesWakeLock_whenDozing() {
|
||||
// GIVEN animations aren't enabled
|
||||
mTextView.setAnimationsEnabled(false);
|
||||
createController();
|
||||
mController.setVisible(true);
|
||||
|
||||
// WHEN we show the transient indication
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
mController.showTransientIndication("Test");
|
||||
mController.hideTransientIndication();
|
||||
|
||||
assertFalse(mWakeLock.isHeld());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transientIndication_releasesWakeLock_afterHidingDelayed() throws Throwable {
|
||||
mInstrumentation.runOnMainSync(() -> {
|
||||
createController();
|
||||
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
mController.showTransientIndication("Test");
|
||||
mController.hideTransientIndicationDelayed(0);
|
||||
});
|
||||
mInstrumentation.waitForIdleSync();
|
||||
|
||||
Boolean[] held = new Boolean[1];
|
||||
mInstrumentation.runOnMainSync(() -> {
|
||||
held[0] = mWakeLock.isHeld();
|
||||
});
|
||||
assertFalse("WakeLock expected: RELEASED, was: HELD", held[0]);
|
||||
// THEN wake lock is RELEASED, not held
|
||||
assertFalse("WakeLock expected: RELEASED, was: HELD", mWakeLock.isHeld());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user