Merge "KeyguardRotateController handles minimum show time" into sc-v2-dev
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