KeyguardRotateController handles minimum show time
Instead of KeyguardIndicationTextView ensuring that keyguard messages are shown for a minimum amount of time, move logic into KeygaurdIndicationRotateTextViewController, since the rotating text view controller already handles the rotating text durations its easier to coordinate the timing in one class rather than across two. Update the charging info if the device is at full charged and is plugged in. Sometimes the battery status is not updated so we need to check the actual %. Test: manual, atest KeyguardIndicationControllerTest KeyguardIndicationRotateTextViewControllerTest Fixes: 188134239 Fixes: 206342960 Fixes: 195347563 Change-Id: Id0cf9bb6c5ac95f83dbb2dcf32f41fa719c0853e Change-Id: If67b1b1cef2fd6db554df105005a185b1ad0f7d2
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
@@ -40,13 +41,24 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Rotates through messages to show on the keyguard bottom area on the lock screen
|
||||
* NOTE: This controller should not be used on AoD to avoid waking up the AP too often.
|
||||
* Animates through messages to show on the keyguard bottom area on the lock screen.
|
||||
* Utilizes a {@link KeyguardIndicationTextView} for animations. This class handles the rotating
|
||||
* nature of the messages including:
|
||||
* - ensuring a message is shown for its minimum amount of time. Minimum time is determined by
|
||||
* {@link KeyguardIndication#getMinVisibilityMillis()}
|
||||
* - showing the next message after a default of 3.5 seconds before animating to the next
|
||||
* - statically showing a single message if there is only one message to show
|
||||
* - showing certain messages immediately, assuming te current message has been shown for
|
||||
* at least {@link KeyguardIndication#getMinVisibilityMillis()}. For example, transient and
|
||||
* biometric messages are meant to be shown immediately.
|
||||
* - ending animations when dozing begins, and resuming when dozing ends. Rotating messages on
|
||||
* AoD is undesirable since it wakes up the AP too often.
|
||||
*/
|
||||
public class KeyguardIndicationRotateTextViewController extends
|
||||
ViewController<KeyguardIndicationTextView> implements Dumpable {
|
||||
public static String TAG = "KgIndicationRotatingCtrl";
|
||||
private static final long DEFAULT_INDICATION_SHOW_LENGTH = 3500; // milliseconds
|
||||
public static final long IMPORTANT_MSG_MIN_DURATION = 2000L + 600L; // 2000ms + [Y in duration]
|
||||
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private final float mMaxAlpha;
|
||||
@@ -62,6 +74,8 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
// List of indication types to show. The next indication to show is always at index 0
|
||||
private final List<Integer> mIndicationQueue = new LinkedList<>();
|
||||
private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
|
||||
private CharSequence mCurrMessage;
|
||||
private long mLastIndicationSwitch;
|
||||
|
||||
private boolean mIsDozing;
|
||||
|
||||
@@ -94,17 +108,19 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
* Update the indication type with the given String.
|
||||
* @param type of indication
|
||||
* @param newIndication message to associate with this indication type
|
||||
* @param showImmediately if true: shows this indication message immediately. Else, the text
|
||||
* associated with this type is updated and will show when its turn in
|
||||
* the IndicationQueue comes around.
|
||||
* @param showAsap if true: shows this indication message as soon as possible. If false,
|
||||
* the text associated with this type is updated and will show when its turn
|
||||
* in the IndicationQueue comes around.
|
||||
*/
|
||||
public void updateIndication(@IndicationType int type, KeyguardIndication newIndication,
|
||||
boolean updateImmediately) {
|
||||
boolean showAsap) {
|
||||
if (type == INDICATION_TYPE_REVERSE_CHARGING) {
|
||||
// temporarily don't show here, instead use AmbientContainer b/181049781
|
||||
return;
|
||||
}
|
||||
final boolean hasPreviousIndication = mIndicationMessages.get(type) != null;
|
||||
long minShowDuration = getMinVisibilityMillis(mIndicationMessages.get(mCurrIndicationType));
|
||||
final boolean hasPreviousIndication = mIndicationMessages.get(type) != null
|
||||
&& !TextUtils.isEmpty(mIndicationMessages.get(type).getMessage());
|
||||
final boolean hasNewIndication = newIndication != null;
|
||||
if (!hasNewIndication) {
|
||||
mIndicationMessages.remove(type);
|
||||
@@ -121,25 +137,46 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean showNow = updateImmediately
|
||||
|| mCurrIndicationType == INDICATION_TYPE_NONE
|
||||
|| mCurrIndicationType == type;
|
||||
long currTime = SystemClock.uptimeMillis();
|
||||
long timeSinceLastIndicationSwitch = currTime - mLastIndicationSwitch;
|
||||
boolean currMsgShownForMinTime = timeSinceLastIndicationSwitch >= minShowDuration;
|
||||
if (hasNewIndication) {
|
||||
if (showNow) {
|
||||
if (mCurrIndicationType == INDICATION_TYPE_NONE || mCurrIndicationType == type) {
|
||||
showIndication(type);
|
||||
} else if (showAsap) {
|
||||
if (currMsgShownForMinTime) {
|
||||
showIndication(type);
|
||||
} else {
|
||||
mIndicationQueue.removeIf(x -> x == type);
|
||||
mIndicationQueue.add(0 /* index */, type /* type */);
|
||||
scheduleShowNextIndication(minShowDuration - timeSinceLastIndicationSwitch);
|
||||
}
|
||||
} else if (!isNextIndicationScheduled()) {
|
||||
scheduleShowNextIndication();
|
||||
long nextShowTime = Math.max(
|
||||
getMinVisibilityMillis(mIndicationMessages.get(type)),
|
||||
DEFAULT_INDICATION_SHOW_LENGTH);
|
||||
if (timeSinceLastIndicationSwitch >= nextShowTime) {
|
||||
showIndication(type);
|
||||
} else {
|
||||
scheduleShowNextIndication(
|
||||
nextShowTime - timeSinceLastIndicationSwitch);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// current indication is updated to empty
|
||||
if (mCurrIndicationType == type
|
||||
&& !hasNewIndication
|
||||
&& updateImmediately) {
|
||||
if (mShowNextIndicationRunnable != null) {
|
||||
mShowNextIndicationRunnable.runImmediately();
|
||||
&& showAsap) {
|
||||
if (currMsgShownForMinTime) {
|
||||
if (mShowNextIndicationRunnable != null) {
|
||||
mShowNextIndicationRunnable.runImmediately();
|
||||
} else {
|
||||
showIndication(INDICATION_TYPE_NONE);
|
||||
}
|
||||
} else {
|
||||
showIndication(INDICATION_TYPE_NONE);
|
||||
scheduleShowNextIndication(minShowDuration - timeSinceLastIndicationSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,11 +201,10 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
* - will continue to be in the rotation of messages shown until hideTransient is called.
|
||||
*/
|
||||
public void showTransient(CharSequence newIndication) {
|
||||
final long inAnimationDuration = 600L; // see KeyguardIndicationTextView.getYInDuration
|
||||
updateIndication(INDICATION_TYPE_TRANSIENT,
|
||||
new KeyguardIndication.Builder()
|
||||
.setMessage(newIndication)
|
||||
.setMinVisibilityMillis(2000L + inAnimationDuration)
|
||||
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
|
||||
.setTextColor(mInitialTextColorState)
|
||||
.build(),
|
||||
/* showImmediately */true);
|
||||
@@ -188,6 +224,15 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
return mIndicationMessages.keySet().size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all messages in the queue and sets the current message to an empty string.
|
||||
*/
|
||||
public void clearMessages() {
|
||||
mCurrIndicationType = INDICATION_TYPE_NONE;
|
||||
mIndicationQueue.clear();
|
||||
mView.clearMessages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately show the passed indication type and schedule the next indication to show.
|
||||
* Will re-add this indication to be re-shown after all other indications have been
|
||||
@@ -196,27 +241,52 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
private void showIndication(@IndicationType int type) {
|
||||
cancelScheduledIndication();
|
||||
|
||||
final CharSequence previousMessage = mCurrMessage;
|
||||
final @IndicationType int previousIndicationType = mCurrIndicationType;
|
||||
mCurrIndicationType = type;
|
||||
mCurrMessage = mIndicationMessages.get(type) != null
|
||||
? mIndicationMessages.get(type).getMessage()
|
||||
: null;
|
||||
|
||||
mIndicationQueue.removeIf(x -> x == type);
|
||||
if (mCurrIndicationType != INDICATION_TYPE_NONE) {
|
||||
mIndicationQueue.add(type); // re-add to show later
|
||||
}
|
||||
|
||||
mView.switchIndication(mIndicationMessages.get(type));
|
||||
mLastIndicationSwitch = SystemClock.uptimeMillis();
|
||||
if (!TextUtils.equals(previousMessage, mCurrMessage)
|
||||
|| previousIndicationType != mCurrIndicationType) {
|
||||
mView.switchIndication(mIndicationMessages.get(type));
|
||||
}
|
||||
|
||||
// only schedule next indication if there's more than just this indication in the queue
|
||||
if (mCurrIndicationType != INDICATION_TYPE_NONE && mIndicationQueue.size() > 1) {
|
||||
scheduleShowNextIndication();
|
||||
scheduleShowNextIndication(Math.max(
|
||||
getMinVisibilityMillis(mIndicationMessages.get(type)),
|
||||
DEFAULT_INDICATION_SHOW_LENGTH));
|
||||
}
|
||||
}
|
||||
|
||||
private long getMinVisibilityMillis(KeyguardIndication indication) {
|
||||
if (indication == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (indication.getMinVisibilityMillis() == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return indication.getMinVisibilityMillis();
|
||||
}
|
||||
|
||||
protected boolean isNextIndicationScheduled() {
|
||||
return mShowNextIndicationRunnable != null;
|
||||
}
|
||||
|
||||
private void scheduleShowNextIndication() {
|
||||
|
||||
private void scheduleShowNextIndication(long msUntilShowNextMsg) {
|
||||
cancelScheduledIndication();
|
||||
mShowNextIndicationRunnable = new ShowNextIndication(DEFAULT_INDICATION_SHOW_LENGTH);
|
||||
mShowNextIndicationRunnable = new ShowNextIndication(msUntilShowNextMsg);
|
||||
}
|
||||
|
||||
private void cancelScheduledIndication() {
|
||||
@@ -292,7 +362,9 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
}
|
||||
}
|
||||
|
||||
// only used locally to stop showing any messages & stop the rotating messages
|
||||
static final int INDICATION_TYPE_NONE = -1;
|
||||
|
||||
public static final int INDICATION_TYPE_OWNER_INFO = 0;
|
||||
public static final int INDICATION_TYPE_DISCLOSURE = 1;
|
||||
public static final int INDICATION_TYPE_LOGOUT = 2;
|
||||
@@ -303,6 +375,7 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
public static final int INDICATION_TYPE_RESTING = 7;
|
||||
public static final int INDICATION_TYPE_USER_LOCKED = 8;
|
||||
public static final int INDICATION_TYPE_REVERSE_CHARGING = 10;
|
||||
public static final int INDICATION_TYPE_BIOMETRIC_MESSAGE = 11;
|
||||
|
||||
@IntDef({
|
||||
INDICATION_TYPE_NONE,
|
||||
@@ -316,6 +389,7 @@ public class KeyguardIndicationRotateTextViewController extends
|
||||
INDICATION_TYPE_RESTING,
|
||||
INDICATION_TYPE_USER_LOCKED,
|
||||
INDICATION_TYPE_REVERSE_CHARGING,
|
||||
INDICATION_TYPE_BIOMETRIC_MESSAGE
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface IndicationType{}
|
||||
|
||||
@@ -21,8 +21,10 @@ import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_LOGOUT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||
@@ -94,6 +96,15 @@ import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Controls the indications and error messages shown on the Keyguard
|
||||
*
|
||||
* On AoD, only one message shows with the following priorities:
|
||||
* 1. Biometric
|
||||
* 2. Transient
|
||||
* 3. Charging alignment
|
||||
* 4. Battery information
|
||||
*
|
||||
* On the lock screen, message rotate through different message types.
|
||||
* See {@link KeyguardIndicationRotateTextViewController.IndicationType} for the list of types.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class KeyguardIndicationController {
|
||||
@@ -103,6 +114,7 @@ public class KeyguardIndicationController {
|
||||
|
||||
private static final int MSG_HIDE_TRANSIENT = 1;
|
||||
private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
|
||||
private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3;
|
||||
private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
|
||||
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
|
||||
|
||||
@@ -132,9 +144,9 @@ public class KeyguardIndicationController {
|
||||
private String mRestingIndication;
|
||||
private String mAlignmentIndication;
|
||||
private CharSequence mTransientIndication;
|
||||
private CharSequence mBiometricMessage;
|
||||
protected ColorStateList mInitialTextColorState;
|
||||
private boolean mVisible;
|
||||
private boolean mHideTransientMessageOnScreenOff;
|
||||
|
||||
private boolean mPowerPluggedIn;
|
||||
private boolean mPowerPluggedInWired;
|
||||
@@ -277,13 +289,15 @@ public class KeyguardIndicationController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Doesn't include disclosure which gets triggered separately.
|
||||
* Doesn't include disclosure (also a persistent indication) which gets triggered separately.
|
||||
*
|
||||
* This method also doesn't update transient messages like biometrics since those messages
|
||||
* are also updated separately.
|
||||
*/
|
||||
private void updateIndications(boolean animate, int userId) {
|
||||
private void updatePersistentIndications(boolean animate, int userId) {
|
||||
updateOwnerInfo();
|
||||
updateBattery(animate);
|
||||
updateUserLocked(userId);
|
||||
updateTransient();
|
||||
updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
|
||||
updateAlignment();
|
||||
updateLogoutView();
|
||||
@@ -383,12 +397,36 @@ public class KeyguardIndicationController {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBiometricMessage() {
|
||||
if (!TextUtils.isEmpty(mBiometricMessage)) {
|
||||
mRotateTextViewController.updateIndication(
|
||||
INDICATION_TYPE_BIOMETRIC_MESSAGE,
|
||||
new KeyguardIndication.Builder()
|
||||
.setMessage(mBiometricMessage)
|
||||
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
|
||||
.setTextColor(mInitialTextColorState)
|
||||
.build(),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||
}
|
||||
|
||||
if (mDozing) {
|
||||
updateIndication(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTransient() {
|
||||
if (!TextUtils.isEmpty(mTransientIndication)) {
|
||||
mRotateTextViewController.showTransient(mTransientIndication);
|
||||
} else {
|
||||
mRotateTextViewController.hideTransient();
|
||||
}
|
||||
|
||||
if (mDozing) {
|
||||
updateIndication(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTrust(int userId, CharSequence trustGrantedIndication,
|
||||
@@ -576,6 +614,14 @@ public class KeyguardIndicationController {
|
||||
mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides biometric indication in {@param delayMs}.
|
||||
*/
|
||||
public void hideBiometricMessageDelayed(long delayMs) {
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MSG_HIDE_BIOMETRIC_MESSAGE), delayMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
|
||||
*/
|
||||
@@ -586,23 +632,40 @@ public class KeyguardIndicationController {
|
||||
/**
|
||||
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
|
||||
*/
|
||||
public void showTransientIndication(CharSequence transientIndication) {
|
||||
showTransientIndication(transientIndication, false /* isError */,
|
||||
false /* hideOnScreenOff */);
|
||||
private void showTransientIndication(CharSequence transientIndication) {
|
||||
mTransientIndication = transientIndication;
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
|
||||
|
||||
updateTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
|
||||
* Shows {@param biometricMessage} until it is hidden by {@link #hideBiometricMessage}.
|
||||
*/
|
||||
private void showTransientIndication(CharSequence transientIndication,
|
||||
boolean isError, boolean hideOnScreenOff) {
|
||||
mTransientIndication = transientIndication;
|
||||
mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
||||
hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
|
||||
public void showBiometricMessage(int biometricMessage) {
|
||||
showBiometricMessage(mContext.getResources().getString(biometricMessage));
|
||||
}
|
||||
|
||||
updateIndication(false);
|
||||
/**
|
||||
* Shows {@param biometricMessage} until it is hidden by {@link #hideBiometricMessage}.
|
||||
*/
|
||||
private void showBiometricMessage(CharSequence biometricMessage) {
|
||||
mBiometricMessage = biometricMessage;
|
||||
|
||||
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
||||
mHandler.removeMessages(MSG_HIDE_BIOMETRIC_MESSAGE);
|
||||
hideBiometricMessageDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
|
||||
|
||||
updateBiometricMessage();
|
||||
}
|
||||
|
||||
private void hideBiometricMessage() {
|
||||
if (mBiometricMessage != null) {
|
||||
mBiometricMessage = null;
|
||||
mHandler.removeMessages(MSG_HIDE_BIOMETRIC_MESSAGE);
|
||||
updateBiometricMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,10 +674,8 @@ public class KeyguardIndicationController {
|
||||
public void hideTransientIndication() {
|
||||
if (mTransientIndication != null) {
|
||||
mTransientIndication = null;
|
||||
mHideTransientMessageOnScreenOff = false;
|
||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||
mRotateTextViewController.hideTransient();
|
||||
updateIndication(false);
|
||||
updateTransient();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +696,11 @@ public class KeyguardIndicationController {
|
||||
// When dozing we ignore any text color and use white instead, because
|
||||
// colors can be hard to read in low brightness.
|
||||
mTopIndicationView.setTextColor(Color.WHITE);
|
||||
if (!TextUtils.isEmpty(mTransientIndication)) {
|
||||
if (!TextUtils.isEmpty(mBiometricMessage)) {
|
||||
mWakeLock.setAcquired(true);
|
||||
mTopIndicationView.switchIndication(mBiometricMessage, null,
|
||||
true, () -> mWakeLock.setAcquired(false));
|
||||
} else if (!TextUtils.isEmpty(mTransientIndication)) {
|
||||
mWakeLock.setAcquired(true);
|
||||
mTopIndicationView.switchIndication(mTransientIndication, null,
|
||||
true, () -> mWakeLock.setAcquired(false));
|
||||
@@ -669,7 +734,7 @@ public class KeyguardIndicationController {
|
||||
mTopIndicationView.setVisibility(GONE);
|
||||
mTopIndicationView.setText(null);
|
||||
mLockScreenIndicationView.setVisibility(View.VISIBLE);
|
||||
updateIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
|
||||
updatePersistentIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
|
||||
}
|
||||
|
||||
// animates textView - textView moves up and bounces down
|
||||
@@ -798,6 +863,8 @@ public class KeyguardIndicationController {
|
||||
hideTransientIndication();
|
||||
} else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
|
||||
showActionToUnlock();
|
||||
} else if (msg.what == MSG_HIDE_BIOMETRIC_MESSAGE) {
|
||||
hideBiometricMessage();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -820,8 +887,7 @@ public class KeyguardIndicationController {
|
||||
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
|
||||
}
|
||||
} else {
|
||||
showTransientIndication(mContext.getString(R.string.keyguard_unlock),
|
||||
false /* isError */, true /* hideOnScreenOff */);
|
||||
showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,15 +896,15 @@ public class KeyguardIndicationController {
|
||||
// if udfps available, there will always be a tappable affordance to unlock
|
||||
// For example, the lock icon
|
||||
if (mKeyguardBypassController.getUserHasDeviceEntryIntent()) {
|
||||
showTransientIndication(R.string.keyguard_unlock_press);
|
||||
showBiometricMessage(R.string.keyguard_unlock_press);
|
||||
} else if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
|
||||
// since face is locked out, simply show "try fingerprint"
|
||||
showTransientIndication(R.string.keyguard_try_fingerprint);
|
||||
showBiometricMessage(R.string.keyguard_try_fingerprint);
|
||||
} else {
|
||||
showTransientIndication(R.string.keyguard_face_failed_use_fp);
|
||||
showBiometricMessage(R.string.keyguard_face_failed_use_fp);
|
||||
}
|
||||
} else {
|
||||
showTransientIndication(R.string.keyguard_try_fingerprint);
|
||||
showBiometricMessage(R.string.keyguard_try_fingerprint);
|
||||
}
|
||||
|
||||
// Although we suppress face auth errors visually, we still announce them for a11y
|
||||
@@ -857,6 +923,8 @@ public class KeyguardIndicationController {
|
||||
pw.println(" mChargingWattage: " + mChargingWattage);
|
||||
pw.println(" mMessageToShowOnScreenOn: " + mMessageToShowOnScreenOn);
|
||||
pw.println(" mDozing: " + mDozing);
|
||||
pw.println(" mTransientIndication: " + mTransientIndication);
|
||||
pw.println(" mBiometricMessage: " + mBiometricMessage);
|
||||
pw.println(" mBatteryLevel: " + mBatteryLevel);
|
||||
pw.println(" mBatteryPresent: " + mBatteryPresent);
|
||||
pw.println(" mTextView.getText(): " + (
|
||||
@@ -871,7 +939,7 @@ public class KeyguardIndicationController {
|
||||
@Override
|
||||
public void onRefreshBatteryInfo(BatteryStatus status) {
|
||||
boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|
||||
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
|
||||
|| status.isCharged();
|
||||
boolean wasPluggedIn = mPowerPluggedIn;
|
||||
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
|
||||
mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
|
||||
@@ -912,7 +980,6 @@ public class KeyguardIndicationController {
|
||||
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean showActionToUnlock =
|
||||
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
@@ -921,14 +988,10 @@ public class KeyguardIndicationController {
|
||||
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
||||
if (biometricSourceType == BiometricSourceType.FACE
|
||||
&& shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
|
||||
// don't show any help messages, b/c they can come in right before a success
|
||||
// However, continue to announce help messages for a11y
|
||||
if (!TextUtils.isEmpty(helpString)) {
|
||||
mLockScreenIndicationView.announceForAccessibility(helpString);
|
||||
}
|
||||
showTryFingerprintMsg(msgId, helpString);
|
||||
return;
|
||||
}
|
||||
showTransientIndication(helpString, false /* isError */, showActionToUnlock);
|
||||
showBiometricMessage(helpString);
|
||||
} else if (showActionToUnlock) {
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK),
|
||||
TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
|
||||
@@ -967,8 +1030,7 @@ public class KeyguardIndicationController {
|
||||
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
|
||||
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
||||
showTransientIndication(errString, /* isError */ true,
|
||||
/* hideOnScreenOff */ true);
|
||||
showBiometricMessage(errString);
|
||||
} else {
|
||||
mMessageToShowOnScreenOn = errString;
|
||||
}
|
||||
@@ -1014,16 +1076,15 @@ public class KeyguardIndicationController {
|
||||
|
||||
@Override
|
||||
public void onTrustAgentErrorMessage(CharSequence message) {
|
||||
showTransientIndication(message, true /* isError */, false /* hideOnScreenOff */);
|
||||
showBiometricMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenTurnedOn() {
|
||||
if (mMessageToShowOnScreenOn != null) {
|
||||
showTransientIndication(mMessageToShowOnScreenOn, true /* isError */,
|
||||
false /* hideOnScreenOff */);
|
||||
showBiometricMessage(mMessageToShowOnScreenOn);
|
||||
// We want to keep this message around in case the screen was off
|
||||
hideTransientIndicationDelayed(HIDE_DELAY_MS);
|
||||
hideBiometricMessageDelayed(HIDE_DELAY_MS);
|
||||
mMessageToShowOnScreenOn = null;
|
||||
}
|
||||
}
|
||||
@@ -1034,7 +1095,7 @@ public class KeyguardIndicationController {
|
||||
if (running && biometricSourceType == BiometricSourceType.FACE) {
|
||||
// Let's hide any previous messages when authentication starts, otherwise
|
||||
// multiple auth attempts would overlap.
|
||||
hideTransientIndication();
|
||||
hideBiometricMessage();
|
||||
mMessageToShowOnScreenOn = null;
|
||||
}
|
||||
}
|
||||
@@ -1043,11 +1104,11 @@ public class KeyguardIndicationController {
|
||||
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
||||
boolean isStrongBiometric) {
|
||||
super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric);
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_TRANSIENT);
|
||||
hideBiometricMessage();
|
||||
|
||||
if (biometricSourceType == BiometricSourceType.FACE
|
||||
&& !mKeyguardBypassController.canBypass()) {
|
||||
mHandler.sendEmptyMessage(MSG_SHOW_ACTION_TO_UNLOCK);
|
||||
showActionToUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1074,8 +1135,7 @@ public class KeyguardIndicationController {
|
||||
|
||||
@Override
|
||||
public void onRequireUnlockForNfc() {
|
||||
showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc),
|
||||
false /* isError */, false /* hideOnScreenOff */);
|
||||
showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc));
|
||||
hideTransientIndicationDelayed(HIDE_DELAY_MS);
|
||||
}
|
||||
}
|
||||
@@ -1094,8 +1154,8 @@ public class KeyguardIndicationController {
|
||||
}
|
||||
mDozing = dozing;
|
||||
|
||||
if (mHideTransientMessageOnScreenOff && mDozing) {
|
||||
hideTransientIndication();
|
||||
if (mDozing) {
|
||||
hideBiometricMessage();
|
||||
}
|
||||
updateIndication(false);
|
||||
}
|
||||
@@ -1112,7 +1172,7 @@ public class KeyguardIndicationController {
|
||||
public void onKeyguardShowingChanged() {
|
||||
if (!mKeyguardStateController.isShowing()) {
|
||||
mTopIndicationView.clearMessages();
|
||||
mLockScreenIndicationView.clearMessages();
|
||||
mRotateTextViewController.clearMessages();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,23 +35,20 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
|
||||
*/
|
||||
public class KeyguardIndicationTextView extends TextView {
|
||||
private static final long MSG_MIN_DURATION_MILLIS_DEFAULT = 1500;
|
||||
|
||||
@StyleRes
|
||||
private static int sStyleId = R.style.TextAppearance_Keyguard_BottomArea;
|
||||
@StyleRes
|
||||
private static int sButtonStyleId = R.style.TextAppearance_Keyguard_BottomArea_Button;
|
||||
|
||||
private long mNextAnimationTime = 0;
|
||||
private boolean mAnimationsEnabled = true;
|
||||
private LinkedList<CharSequence> mMessages = new LinkedList<>();
|
||||
private LinkedList<KeyguardIndication> mKeyguardIndicationInfo = new LinkedList<>();
|
||||
private CharSequence mMessage;
|
||||
private KeyguardIndication mKeyguardIndicationInfo;
|
||||
|
||||
private Animator mLastAnimator;
|
||||
|
||||
public KeyguardIndicationTextView(Context context) {
|
||||
super(context);
|
||||
@@ -71,22 +68,24 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears message queue.
|
||||
* Clears message queue and currently shown message.
|
||||
*/
|
||||
public void clearMessages() {
|
||||
mMessages.clear();
|
||||
mKeyguardIndicationInfo.clear();
|
||||
if (mLastAnimator != null) {
|
||||
mLastAnimator.cancel();
|
||||
}
|
||||
setText("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text with an animation and makes sure a single indication is shown long enough.
|
||||
* Changes the text with an animation.
|
||||
*/
|
||||
public void switchIndication(int textResId) {
|
||||
switchIndication(getResources().getText(textResId), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text with an animation and makes sure a single indication is shown long enough.
|
||||
* Changes the text with an animation.
|
||||
*
|
||||
* @param indication The text to show.
|
||||
*/
|
||||
@@ -95,15 +94,14 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text with an animation. Makes sure a single indication is shown long enough.
|
||||
* Changes the text with an animation.
|
||||
*/
|
||||
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.
|
||||
* Updates the text with an optional animation.
|
||||
*
|
||||
* @param text The text to show.
|
||||
* @param indication optional display information for the text
|
||||
@@ -112,33 +110,15 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
*/
|
||||
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);
|
||||
mMessage = text;
|
||||
mKeyguardIndicationInfo = indication;
|
||||
|
||||
if (animate) {
|
||||
final boolean hasIcon = indication != null && indication.getIcon() != null;
|
||||
final AnimatorSet animator = new AnimatorSet();
|
||||
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);
|
||||
if (!TextUtils.isEmpty(mMessage) || hasIcon) {
|
||||
Animator inAnimator = getInAnimator();
|
||||
inAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -164,7 +144,10 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
animator.play(outAnimator);
|
||||
}
|
||||
|
||||
animator.setStartDelay(delay);
|
||||
if (mLastAnimator != null) {
|
||||
mLastAnimator.cancel();
|
||||
}
|
||||
mLastAnimator = animator;
|
||||
animator.start();
|
||||
} else {
|
||||
setAlpha(1f);
|
||||
@@ -173,6 +156,10 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
if (onAnimationEndCallback != null) {
|
||||
onAnimationEndCallback.run();
|
||||
}
|
||||
if (mLastAnimator != null) {
|
||||
mLastAnimator.cancel();
|
||||
mLastAnimator = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,10 +169,20 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
fadeOut.setDuration(getFadeOutDuration());
|
||||
fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
|
||||
fadeOut.addListener(new AnimatorListenerAdapter() {
|
||||
private boolean mCancelled = false;
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
super.onAnimationEnd(animator);
|
||||
setNextIndication();
|
||||
if (!mCancelled) {
|
||||
setNextIndication();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
super.onAnimationCancel(animator);
|
||||
mCancelled = true;
|
||||
setAlpha(0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -198,20 +195,19 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
}
|
||||
|
||||
private void setNextIndication() {
|
||||
KeyguardIndication info = mKeyguardIndicationInfo.poll();
|
||||
if (info != null) {
|
||||
if (mKeyguardIndicationInfo != 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) {
|
||||
if (mKeyguardIndicationInfo.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();
|
||||
setBackground(mKeyguardIndicationInfo.getBackground());
|
||||
setTextColor(mKeyguardIndicationInfo.getTextColor());
|
||||
setOnClickListener(mKeyguardIndicationInfo.getClickListener());
|
||||
setClickable(mKeyguardIndicationInfo.getClickListener() != null);
|
||||
final Drawable icon = mKeyguardIndicationInfo.getIcon();
|
||||
if (icon != null) {
|
||||
icon.setTint(getCurrentTextColor());
|
||||
if (icon instanceof AnimatedVectorDrawable) {
|
||||
@@ -220,7 +216,7 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
}
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
|
||||
}
|
||||
setText(mMessages.poll());
|
||||
setText(mMessage);
|
||||
}
|
||||
|
||||
private AnimatorSet getInAnimator() {
|
||||
@@ -238,6 +234,7 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
super.onAnimationCancel(animation);
|
||||
setTranslationY(0);
|
||||
setAlpha(1f);
|
||||
}
|
||||
});
|
||||
animatorSet.playTogether(yTranslate, fadeIn);
|
||||
@@ -270,14 +267,6 @@ public class KeyguardIndicationTextView extends TextView {
|
||||
return 167L;
|
||||
}
|
||||
|
||||
private void setNextAnimationTime(long time) {
|
||||
if (mAnimationsEnabled) {
|
||||
mNextAnimationTime = time;
|
||||
} else {
|
||||
mNextAnimationTime = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private int getYTranslationPixels() {
|
||||
return mContext.getResources().getDimensionPixelSize(
|
||||
com.android.systemui.R.dimen.keyguard_indication_y_translation);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard;
|
||||
|
||||
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||
|
||||
@@ -56,7 +57,8 @@ import org.mockito.MockitoAnnotations;
|
||||
public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCase {
|
||||
|
||||
private static final String TEST_MESSAGE = "test message";
|
||||
private static final String TEST_MESSAGE_2 = "test message 2";
|
||||
private static final String TEST_MESSAGE_2 = "test message two";
|
||||
private int mMsgId = 0;
|
||||
|
||||
@Mock
|
||||
private DelayableExecutor mExecutor;
|
||||
@@ -200,6 +202,24 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
||||
verify(mExecutor).executeDelayed(any(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMessage_noIndicationUpdate() {
|
||||
// GIVEN we are showing and indication with a test message
|
||||
mController.updateIndication(
|
||||
INDICATION_TYPE_OWNER_INFO, createIndication(TEST_MESSAGE), true);
|
||||
reset(mView);
|
||||
reset(mExecutor);
|
||||
|
||||
// WHEN the same type tries to show the same exact message
|
||||
final KeyguardIndication sameIndication = createIndication(TEST_MESSAGE);
|
||||
mController.updateIndication(
|
||||
INDICATION_TYPE_OWNER_INFO, sameIndication, true);
|
||||
|
||||
// THEN
|
||||
// - we don't update the indication b/c there's no reason the animate the same text
|
||||
verify(mView, never()).switchIndication(sameIndication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransientIndication() {
|
||||
// GIVEN we already have two indication messages
|
||||
@@ -223,8 +243,11 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
||||
@Test
|
||||
public void testHideIndicationOneMessage() {
|
||||
// GIVEN we have one indication message
|
||||
KeyguardIndication indication = createIndication();
|
||||
mController.updateIndication(
|
||||
INDICATION_TYPE_OWNER_INFO, createIndication(), false);
|
||||
INDICATION_TYPE_OWNER_INFO, indication, false);
|
||||
verify(mView).switchIndication(indication);
|
||||
reset(mView);
|
||||
|
||||
// WHEN we hide the current indication type
|
||||
mController.hideIndication(INDICATION_TYPE_OWNER_INFO);
|
||||
@@ -254,6 +277,10 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
||||
|
||||
@Test
|
||||
public void testStartDozing() {
|
||||
// GIVEN a biometric message is showing
|
||||
mController.updateIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE,
|
||||
createIndication(), true);
|
||||
|
||||
// WHEN the device is dozing
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
|
||||
@@ -293,9 +320,19 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
||||
verify(mView, never()).switchIndication(any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an indication with a unique message.
|
||||
*/
|
||||
private KeyguardIndication createIndication() {
|
||||
return createIndication(TEST_MESSAGE + " " + mMsgId++);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an indication with the given message.
|
||||
*/
|
||||
private KeyguardIndication createIndication(String msg) {
|
||||
return new KeyguardIndication.Builder()
|
||||
.setMessage(TEST_MESSAGE)
|
||||
.setMessage(msg)
|
||||
.setTextColor(ColorStateList.valueOf(Color.WHITE))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
|
||||
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_RESTING;
|
||||
@@ -112,6 +113,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
private static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName("com.android.foo",
|
||||
"bar");
|
||||
|
||||
private static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
|
||||
|
||||
private String mKeyguardTryFingerprintMsg;
|
||||
private String mDisclosureWithOrganization;
|
||||
private String mDisclosureGeneric;
|
||||
@@ -419,7 +422,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
|
||||
// WHEN transient text is shown
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
mController.showTransientIndication("Test");
|
||||
mController.showTransientIndication(TEST_STRING_RES);
|
||||
|
||||
// THEN wake lock is held while the animation is running
|
||||
assertTrue("WakeLock expected: HELD, was: RELEASED", mWakeLock.isHeld());
|
||||
@@ -434,7 +437,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
|
||||
// WHEN we show the transient indication
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
mController.showTransientIndication("Test");
|
||||
mController.showTransientIndication(TEST_STRING_RES);
|
||||
|
||||
// THEN wake lock is RELEASED, not held
|
||||
assertFalse("WakeLock expected: RELEASED, was: HELD", mWakeLock.isHeld());
|
||||
@@ -445,10 +448,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
createController();
|
||||
|
||||
mController.setVisible(true);
|
||||
mController.showTransientIndication("Test");
|
||||
mController.showTransientIndication(TEST_STRING_RES);
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
|
||||
assertThat(mTextView.getText()).isEqualTo("Test");
|
||||
assertThat(mTextView.getText()).isEqualTo(
|
||||
mContext.getResources().getString(TEST_STRING_RES));
|
||||
assertThat(mTextView.getCurrentTextColor()).isEqualTo(Color.WHITE);
|
||||
assertThat(mTextView.getAlpha()).isEqualTo(1f);
|
||||
}
|
||||
@@ -462,11 +466,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
mController.getKeyguardCallback().onBiometricHelp(
|
||||
KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
|
||||
BiometricSourceType.FACE);
|
||||
verifyTransientMessage(message);
|
||||
verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message);
|
||||
reset(mRotateTextViewController);
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
|
||||
verifyHideIndication(INDICATION_TYPE_TRANSIENT);
|
||||
verifyHideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -478,7 +482,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
|
||||
"A message", BiometricSourceType.FACE);
|
||||
|
||||
verifyTransientMessage(message);
|
||||
verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message);
|
||||
mStatusBarStateListener.onDozingChanged(true);
|
||||
|
||||
assertThat(mTextView.getText()).isNotEqualTo(message);
|
||||
@@ -497,7 +501,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
FingerprintManager.FINGERPRINT_ERROR_CANCELED, "bar",
|
||||
BiometricSourceType.FINGERPRINT);
|
||||
|
||||
verifyNoTransientMessage();
|
||||
verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||
verifyNoMessage(INDICATION_TYPE_TRANSIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -757,7 +762,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
verify(mRotateTextViewController).showTransient(eq(message));
|
||||
}
|
||||
|
||||
private void verifyNoTransientMessage() {
|
||||
verify(mRotateTextViewController, never()).showTransient(any());
|
||||
private void verifyNoMessage(int type) {
|
||||
if (type == INDICATION_TYPE_TRANSIENT) {
|
||||
verify(mRotateTextViewController, never()).showTransient(anyString());
|
||||
} else {
|
||||
verify(mRotateTextViewController, never()).updateIndication(eq(type),
|
||||
anyObject(), anyBoolean());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user