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.annotation.Nullable;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
@@ -40,13 +41,24 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotates through messages to show on the keyguard bottom area on the lock screen
|
* Animates 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.
|
* 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
|
public class KeyguardIndicationRotateTextViewController extends
|
||||||
ViewController<KeyguardIndicationTextView> implements Dumpable {
|
ViewController<KeyguardIndicationTextView> implements Dumpable {
|
||||||
public static String TAG = "KgIndicationRotatingCtrl";
|
public static String TAG = "KgIndicationRotatingCtrl";
|
||||||
private static final long DEFAULT_INDICATION_SHOW_LENGTH = 3500; // milliseconds
|
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 StatusBarStateController mStatusBarStateController;
|
||||||
private final float mMaxAlpha;
|
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
|
// List of indication types to show. The next indication to show is always at index 0
|
||||||
private final List<Integer> mIndicationQueue = new LinkedList<>();
|
private final List<Integer> mIndicationQueue = new LinkedList<>();
|
||||||
private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
|
private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
|
||||||
|
private CharSequence mCurrMessage;
|
||||||
|
private long mLastIndicationSwitch;
|
||||||
|
|
||||||
private boolean mIsDozing;
|
private boolean mIsDozing;
|
||||||
|
|
||||||
@@ -94,17 +108,19 @@ public class KeyguardIndicationRotateTextViewController extends
|
|||||||
* Update the indication type with the given String.
|
* Update the indication type with the given String.
|
||||||
* @param type of indication
|
* @param type of indication
|
||||||
* @param newIndication message to associate with this indication type
|
* @param newIndication message to associate with this indication type
|
||||||
* @param showImmediately if true: shows this indication message immediately. Else, the text
|
* @param showAsap if true: shows this indication message as soon as possible. If false,
|
||||||
* associated with this type is updated and will show when its turn in
|
* the text associated with this type is updated and will show when its turn
|
||||||
* the IndicationQueue comes around.
|
* in the IndicationQueue comes around.
|
||||||
*/
|
*/
|
||||||
public void updateIndication(@IndicationType int type, KeyguardIndication newIndication,
|
public void updateIndication(@IndicationType int type, KeyguardIndication newIndication,
|
||||||
boolean updateImmediately) {
|
boolean showAsap) {
|
||||||
if (type == INDICATION_TYPE_REVERSE_CHARGING) {
|
if (type == INDICATION_TYPE_REVERSE_CHARGING) {
|
||||||
// temporarily don't show here, instead use AmbientContainer b/181049781
|
// temporarily don't show here, instead use AmbientContainer b/181049781
|
||||||
return;
|
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;
|
final boolean hasNewIndication = newIndication != null;
|
||||||
if (!hasNewIndication) {
|
if (!hasNewIndication) {
|
||||||
mIndicationMessages.remove(type);
|
mIndicationMessages.remove(type);
|
||||||
@@ -121,26 +137,47 @@ public class KeyguardIndicationRotateTextViewController extends
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean showNow = updateImmediately
|
long currTime = SystemClock.uptimeMillis();
|
||||||
|| mCurrIndicationType == INDICATION_TYPE_NONE
|
long timeSinceLastIndicationSwitch = currTime - mLastIndicationSwitch;
|
||||||
|| mCurrIndicationType == type;
|
boolean currMsgShownForMinTime = timeSinceLastIndicationSwitch >= minShowDuration;
|
||||||
if (hasNewIndication) {
|
if (hasNewIndication) {
|
||||||
if (showNow) {
|
if (mCurrIndicationType == INDICATION_TYPE_NONE || mCurrIndicationType == type) {
|
||||||
showIndication(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()) {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// current indication is updated to empty
|
||||||
if (mCurrIndicationType == type
|
if (mCurrIndicationType == type
|
||||||
&& !hasNewIndication
|
&& !hasNewIndication
|
||||||
&& updateImmediately) {
|
&& showAsap) {
|
||||||
|
if (currMsgShownForMinTime) {
|
||||||
if (mShowNextIndicationRunnable != null) {
|
if (mShowNextIndicationRunnable != null) {
|
||||||
mShowNextIndicationRunnable.runImmediately();
|
mShowNextIndicationRunnable.runImmediately();
|
||||||
} else {
|
} else {
|
||||||
showIndication(INDICATION_TYPE_NONE);
|
showIndication(INDICATION_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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.
|
* - will continue to be in the rotation of messages shown until hideTransient is called.
|
||||||
*/
|
*/
|
||||||
public void showTransient(CharSequence newIndication) {
|
public void showTransient(CharSequence newIndication) {
|
||||||
final long inAnimationDuration = 600L; // see KeyguardIndicationTextView.getYInDuration
|
|
||||||
updateIndication(INDICATION_TYPE_TRANSIENT,
|
updateIndication(INDICATION_TYPE_TRANSIENT,
|
||||||
new KeyguardIndication.Builder()
|
new KeyguardIndication.Builder()
|
||||||
.setMessage(newIndication)
|
.setMessage(newIndication)
|
||||||
.setMinVisibilityMillis(2000L + inAnimationDuration)
|
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
|
||||||
.setTextColor(mInitialTextColorState)
|
.setTextColor(mInitialTextColorState)
|
||||||
.build(),
|
.build(),
|
||||||
/* showImmediately */true);
|
/* showImmediately */true);
|
||||||
@@ -188,6 +224,15 @@ public class KeyguardIndicationRotateTextViewController extends
|
|||||||
return mIndicationMessages.keySet().size() > 0;
|
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.
|
* 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
|
* 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) {
|
private void showIndication(@IndicationType int type) {
|
||||||
cancelScheduledIndication();
|
cancelScheduledIndication();
|
||||||
|
|
||||||
|
final CharSequence previousMessage = mCurrMessage;
|
||||||
|
final @IndicationType int previousIndicationType = mCurrIndicationType;
|
||||||
mCurrIndicationType = type;
|
mCurrIndicationType = type;
|
||||||
|
mCurrMessage = mIndicationMessages.get(type) != null
|
||||||
|
? mIndicationMessages.get(type).getMessage()
|
||||||
|
: null;
|
||||||
|
|
||||||
mIndicationQueue.removeIf(x -> x == type);
|
mIndicationQueue.removeIf(x -> x == type);
|
||||||
if (mCurrIndicationType != INDICATION_TYPE_NONE) {
|
if (mCurrIndicationType != INDICATION_TYPE_NONE) {
|
||||||
mIndicationQueue.add(type); // re-add to show later
|
mIndicationQueue.add(type); // re-add to show later
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mLastIndicationSwitch = SystemClock.uptimeMillis();
|
||||||
|
if (!TextUtils.equals(previousMessage, mCurrMessage)
|
||||||
|
|| previousIndicationType != mCurrIndicationType) {
|
||||||
mView.switchIndication(mIndicationMessages.get(type));
|
mView.switchIndication(mIndicationMessages.get(type));
|
||||||
|
}
|
||||||
|
|
||||||
// only schedule next indication if there's more than just this indication in the queue
|
// only schedule next indication if there's more than just this indication in the queue
|
||||||
if (mCurrIndicationType != INDICATION_TYPE_NONE && mIndicationQueue.size() > 1) {
|
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() {
|
protected boolean isNextIndicationScheduled() {
|
||||||
return mShowNextIndicationRunnable != null;
|
return mShowNextIndicationRunnable != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleShowNextIndication() {
|
|
||||||
|
private void scheduleShowNextIndication(long msUntilShowNextMsg) {
|
||||||
cancelScheduledIndication();
|
cancelScheduledIndication();
|
||||||
mShowNextIndicationRunnable = new ShowNextIndication(DEFAULT_INDICATION_SHOW_LENGTH);
|
mShowNextIndicationRunnable = new ShowNextIndication(msUntilShowNextMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelScheduledIndication() {
|
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;
|
static final int INDICATION_TYPE_NONE = -1;
|
||||||
|
|
||||||
public static final int INDICATION_TYPE_OWNER_INFO = 0;
|
public static final int INDICATION_TYPE_OWNER_INFO = 0;
|
||||||
public static final int INDICATION_TYPE_DISCLOSURE = 1;
|
public static final int INDICATION_TYPE_DISCLOSURE = 1;
|
||||||
public static final int INDICATION_TYPE_LOGOUT = 2;
|
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_RESTING = 7;
|
||||||
public static final int INDICATION_TYPE_USER_LOCKED = 8;
|
public static final int INDICATION_TYPE_USER_LOCKED = 8;
|
||||||
public static final int INDICATION_TYPE_REVERSE_CHARGING = 10;
|
public static final int INDICATION_TYPE_REVERSE_CHARGING = 10;
|
||||||
|
public static final int INDICATION_TYPE_BIOMETRIC_MESSAGE = 11;
|
||||||
|
|
||||||
@IntDef({
|
@IntDef({
|
||||||
INDICATION_TYPE_NONE,
|
INDICATION_TYPE_NONE,
|
||||||
@@ -316,6 +389,7 @@ public class KeyguardIndicationRotateTextViewController extends
|
|||||||
INDICATION_TYPE_RESTING,
|
INDICATION_TYPE_RESTING,
|
||||||
INDICATION_TYPE_USER_LOCKED,
|
INDICATION_TYPE_USER_LOCKED,
|
||||||
INDICATION_TYPE_REVERSE_CHARGING,
|
INDICATION_TYPE_REVERSE_CHARGING,
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface IndicationType{}
|
public @interface IndicationType{}
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ import static android.view.View.GONE;
|
|||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
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_ALIGNMENT;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
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_DISCLOSURE;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_LOGOUT;
|
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_LOGOUT;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
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
|
* 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
|
@SysUISingleton
|
||||||
public class KeyguardIndicationController {
|
public class KeyguardIndicationController {
|
||||||
@@ -103,6 +114,7 @@ public class KeyguardIndicationController {
|
|||||||
|
|
||||||
private static final int MSG_HIDE_TRANSIENT = 1;
|
private static final int MSG_HIDE_TRANSIENT = 1;
|
||||||
private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
|
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 long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
|
||||||
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
|
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
|
||||||
|
|
||||||
@@ -132,9 +144,9 @@ public class KeyguardIndicationController {
|
|||||||
private String mRestingIndication;
|
private String mRestingIndication;
|
||||||
private String mAlignmentIndication;
|
private String mAlignmentIndication;
|
||||||
private CharSequence mTransientIndication;
|
private CharSequence mTransientIndication;
|
||||||
|
private CharSequence mBiometricMessage;
|
||||||
protected ColorStateList mInitialTextColorState;
|
protected ColorStateList mInitialTextColorState;
|
||||||
private boolean mVisible;
|
private boolean mVisible;
|
||||||
private boolean mHideTransientMessageOnScreenOff;
|
|
||||||
|
|
||||||
private boolean mPowerPluggedIn;
|
private boolean mPowerPluggedIn;
|
||||||
private boolean mPowerPluggedInWired;
|
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();
|
updateOwnerInfo();
|
||||||
updateBattery(animate);
|
updateBattery(animate);
|
||||||
updateUserLocked(userId);
|
updateUserLocked(userId);
|
||||||
updateTransient();
|
|
||||||
updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
|
updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
|
||||||
updateAlignment();
|
updateAlignment();
|
||||||
updateLogoutView();
|
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() {
|
private void updateTransient() {
|
||||||
if (!TextUtils.isEmpty(mTransientIndication)) {
|
if (!TextUtils.isEmpty(mTransientIndication)) {
|
||||||
mRotateTextViewController.showTransient(mTransientIndication);
|
mRotateTextViewController.showTransient(mTransientIndication);
|
||||||
} else {
|
} else {
|
||||||
mRotateTextViewController.hideTransient();
|
mRotateTextViewController.hideTransient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDozing) {
|
||||||
|
updateIndication(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTrust(int userId, CharSequence trustGrantedIndication,
|
private void updateTrust(int userId, CharSequence trustGrantedIndication,
|
||||||
@@ -576,6 +614,14 @@ public class KeyguardIndicationController {
|
|||||||
mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
|
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}.
|
* 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}.
|
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
|
||||||
*/
|
*/
|
||||||
public void showTransientIndication(CharSequence transientIndication) {
|
private void showTransientIndication(CharSequence transientIndication) {
|
||||||
showTransientIndication(transientIndication, false /* isError */,
|
mTransientIndication = transientIndication;
|
||||||
false /* hideOnScreenOff */);
|
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,
|
public void showBiometricMessage(int biometricMessage) {
|
||||||
boolean isError, boolean hideOnScreenOff) {
|
showBiometricMessage(mContext.getResources().getString(biometricMessage));
|
||||||
mTransientIndication = transientIndication;
|
}
|
||||||
mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
|
|
||||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
|
||||||
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
|
||||||
hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
|
|
||||||
|
|
||||||
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() {
|
public void hideTransientIndication() {
|
||||||
if (mTransientIndication != null) {
|
if (mTransientIndication != null) {
|
||||||
mTransientIndication = null;
|
mTransientIndication = null;
|
||||||
mHideTransientMessageOnScreenOff = false;
|
|
||||||
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
|
||||||
mRotateTextViewController.hideTransient();
|
updateTransient();
|
||||||
updateIndication(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,7 +696,11 @@ public class KeyguardIndicationController {
|
|||||||
// When dozing we ignore any text color and use white instead, because
|
// When dozing we ignore any text color and use white instead, because
|
||||||
// colors can be hard to read in low brightness.
|
// colors can be hard to read in low brightness.
|
||||||
mTopIndicationView.setTextColor(Color.WHITE);
|
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);
|
mWakeLock.setAcquired(true);
|
||||||
mTopIndicationView.switchIndication(mTransientIndication, null,
|
mTopIndicationView.switchIndication(mTransientIndication, null,
|
||||||
true, () -> mWakeLock.setAcquired(false));
|
true, () -> mWakeLock.setAcquired(false));
|
||||||
@@ -669,7 +734,7 @@ public class KeyguardIndicationController {
|
|||||||
mTopIndicationView.setVisibility(GONE);
|
mTopIndicationView.setVisibility(GONE);
|
||||||
mTopIndicationView.setText(null);
|
mTopIndicationView.setText(null);
|
||||||
mLockScreenIndicationView.setVisibility(View.VISIBLE);
|
mLockScreenIndicationView.setVisibility(View.VISIBLE);
|
||||||
updateIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
|
updatePersistentIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// animates textView - textView moves up and bounces down
|
// animates textView - textView moves up and bounces down
|
||||||
@@ -798,6 +863,8 @@ public class KeyguardIndicationController {
|
|||||||
hideTransientIndication();
|
hideTransientIndication();
|
||||||
} else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
|
} else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
|
||||||
showActionToUnlock();
|
showActionToUnlock();
|
||||||
|
} else if (msg.what == MSG_HIDE_BIOMETRIC_MESSAGE) {
|
||||||
|
hideBiometricMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -820,8 +887,7 @@ public class KeyguardIndicationController {
|
|||||||
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
|
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showTransientIndication(mContext.getString(R.string.keyguard_unlock),
|
showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
|
||||||
false /* isError */, true /* hideOnScreenOff */);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,15 +896,15 @@ public class KeyguardIndicationController {
|
|||||||
// if udfps available, there will always be a tappable affordance to unlock
|
// if udfps available, there will always be a tappable affordance to unlock
|
||||||
// For example, the lock icon
|
// For example, the lock icon
|
||||||
if (mKeyguardBypassController.getUserHasDeviceEntryIntent()) {
|
if (mKeyguardBypassController.getUserHasDeviceEntryIntent()) {
|
||||||
showTransientIndication(R.string.keyguard_unlock_press);
|
showBiometricMessage(R.string.keyguard_unlock_press);
|
||||||
} else if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
|
} else if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
|
||||||
// since face is locked out, simply show "try fingerprint"
|
// since face is locked out, simply show "try fingerprint"
|
||||||
showTransientIndication(R.string.keyguard_try_fingerprint);
|
showBiometricMessage(R.string.keyguard_try_fingerprint);
|
||||||
} else {
|
} else {
|
||||||
showTransientIndication(R.string.keyguard_face_failed_use_fp);
|
showBiometricMessage(R.string.keyguard_face_failed_use_fp);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// 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(" mChargingWattage: " + mChargingWattage);
|
||||||
pw.println(" mMessageToShowOnScreenOn: " + mMessageToShowOnScreenOn);
|
pw.println(" mMessageToShowOnScreenOn: " + mMessageToShowOnScreenOn);
|
||||||
pw.println(" mDozing: " + mDozing);
|
pw.println(" mDozing: " + mDozing);
|
||||||
|
pw.println(" mTransientIndication: " + mTransientIndication);
|
||||||
|
pw.println(" mBiometricMessage: " + mBiometricMessage);
|
||||||
pw.println(" mBatteryLevel: " + mBatteryLevel);
|
pw.println(" mBatteryLevel: " + mBatteryLevel);
|
||||||
pw.println(" mBatteryPresent: " + mBatteryPresent);
|
pw.println(" mBatteryPresent: " + mBatteryPresent);
|
||||||
pw.println(" mTextView.getText(): " + (
|
pw.println(" mTextView.getText(): " + (
|
||||||
@@ -871,7 +939,7 @@ public class KeyguardIndicationController {
|
|||||||
@Override
|
@Override
|
||||||
public void onRefreshBatteryInfo(BatteryStatus status) {
|
public void onRefreshBatteryInfo(BatteryStatus status) {
|
||||||
boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|
boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|
||||||
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
|
|| status.isCharged();
|
||||||
boolean wasPluggedIn = mPowerPluggedIn;
|
boolean wasPluggedIn = mPowerPluggedIn;
|
||||||
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
|
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
|
||||||
mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
|
mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
|
||||||
@@ -912,7 +980,6 @@ public class KeyguardIndicationController {
|
|||||||
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
|
.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean showActionToUnlock =
|
boolean showActionToUnlock =
|
||||||
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||||
@@ -921,14 +988,10 @@ public class KeyguardIndicationController {
|
|||||||
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
||||||
if (biometricSourceType == BiometricSourceType.FACE
|
if (biometricSourceType == BiometricSourceType.FACE
|
||||||
&& shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
|
&& shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
|
||||||
// don't show any help messages, b/c they can come in right before a success
|
showTryFingerprintMsg(msgId, helpString);
|
||||||
// However, continue to announce help messages for a11y
|
|
||||||
if (!TextUtils.isEmpty(helpString)) {
|
|
||||||
mLockScreenIndicationView.announceForAccessibility(helpString);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showTransientIndication(helpString, false /* isError */, showActionToUnlock);
|
showBiometricMessage(helpString);
|
||||||
} else if (showActionToUnlock) {
|
} else if (showActionToUnlock) {
|
||||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK),
|
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK),
|
||||||
TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
|
TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
|
||||||
@@ -967,8 +1030,7 @@ public class KeyguardIndicationController {
|
|||||||
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||||
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
|
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
|
||||||
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
|
||||||
showTransientIndication(errString, /* isError */ true,
|
showBiometricMessage(errString);
|
||||||
/* hideOnScreenOff */ true);
|
|
||||||
} else {
|
} else {
|
||||||
mMessageToShowOnScreenOn = errString;
|
mMessageToShowOnScreenOn = errString;
|
||||||
}
|
}
|
||||||
@@ -1014,16 +1076,15 @@ public class KeyguardIndicationController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrustAgentErrorMessage(CharSequence message) {
|
public void onTrustAgentErrorMessage(CharSequence message) {
|
||||||
showTransientIndication(message, true /* isError */, false /* hideOnScreenOff */);
|
showBiometricMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScreenTurnedOn() {
|
public void onScreenTurnedOn() {
|
||||||
if (mMessageToShowOnScreenOn != null) {
|
if (mMessageToShowOnScreenOn != null) {
|
||||||
showTransientIndication(mMessageToShowOnScreenOn, true /* isError */,
|
showBiometricMessage(mMessageToShowOnScreenOn);
|
||||||
false /* hideOnScreenOff */);
|
|
||||||
// We want to keep this message around in case the screen was off
|
// We want to keep this message around in case the screen was off
|
||||||
hideTransientIndicationDelayed(HIDE_DELAY_MS);
|
hideBiometricMessageDelayed(HIDE_DELAY_MS);
|
||||||
mMessageToShowOnScreenOn = null;
|
mMessageToShowOnScreenOn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1034,7 +1095,7 @@ public class KeyguardIndicationController {
|
|||||||
if (running && biometricSourceType == BiometricSourceType.FACE) {
|
if (running && biometricSourceType == BiometricSourceType.FACE) {
|
||||||
// Let's hide any previous messages when authentication starts, otherwise
|
// Let's hide any previous messages when authentication starts, otherwise
|
||||||
// multiple auth attempts would overlap.
|
// multiple auth attempts would overlap.
|
||||||
hideTransientIndication();
|
hideBiometricMessage();
|
||||||
mMessageToShowOnScreenOn = null;
|
mMessageToShowOnScreenOn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1043,11 +1104,11 @@ public class KeyguardIndicationController {
|
|||||||
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
||||||
boolean isStrongBiometric) {
|
boolean isStrongBiometric) {
|
||||||
super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric);
|
super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric);
|
||||||
mHandler.sendEmptyMessage(MSG_HIDE_TRANSIENT);
|
hideBiometricMessage();
|
||||||
|
|
||||||
if (biometricSourceType == BiometricSourceType.FACE
|
if (biometricSourceType == BiometricSourceType.FACE
|
||||||
&& !mKeyguardBypassController.canBypass()) {
|
&& !mKeyguardBypassController.canBypass()) {
|
||||||
mHandler.sendEmptyMessage(MSG_SHOW_ACTION_TO_UNLOCK);
|
showActionToUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,8 +1135,7 @@ public class KeyguardIndicationController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequireUnlockForNfc() {
|
public void onRequireUnlockForNfc() {
|
||||||
showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc),
|
showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc));
|
||||||
false /* isError */, false /* hideOnScreenOff */);
|
|
||||||
hideTransientIndicationDelayed(HIDE_DELAY_MS);
|
hideTransientIndicationDelayed(HIDE_DELAY_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1094,8 +1154,8 @@ public class KeyguardIndicationController {
|
|||||||
}
|
}
|
||||||
mDozing = dozing;
|
mDozing = dozing;
|
||||||
|
|
||||||
if (mHideTransientMessageOnScreenOff && mDozing) {
|
if (mDozing) {
|
||||||
hideTransientIndication();
|
hideBiometricMessage();
|
||||||
}
|
}
|
||||||
updateIndication(false);
|
updateIndication(false);
|
||||||
}
|
}
|
||||||
@@ -1112,7 +1172,7 @@ public class KeyguardIndicationController {
|
|||||||
public void onKeyguardShowingChanged() {
|
public void onKeyguardShowingChanged() {
|
||||||
if (!mKeyguardStateController.isShowing()) {
|
if (!mKeyguardStateController.isShowing()) {
|
||||||
mTopIndicationView.clearMessages();
|
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.animation.Interpolators;
|
||||||
import com.android.systemui.keyguard.KeyguardIndication;
|
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").
|
* A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
|
||||||
*/
|
*/
|
||||||
public class KeyguardIndicationTextView extends TextView {
|
public class KeyguardIndicationTextView extends TextView {
|
||||||
private static final long MSG_MIN_DURATION_MILLIS_DEFAULT = 1500;
|
|
||||||
|
|
||||||
@StyleRes
|
@StyleRes
|
||||||
private static int sStyleId = R.style.TextAppearance_Keyguard_BottomArea;
|
private static int sStyleId = R.style.TextAppearance_Keyguard_BottomArea;
|
||||||
@StyleRes
|
@StyleRes
|
||||||
private static int sButtonStyleId = R.style.TextAppearance_Keyguard_BottomArea_Button;
|
private static int sButtonStyleId = R.style.TextAppearance_Keyguard_BottomArea_Button;
|
||||||
|
|
||||||
private long mNextAnimationTime = 0;
|
|
||||||
private boolean mAnimationsEnabled = true;
|
private boolean mAnimationsEnabled = true;
|
||||||
private LinkedList<CharSequence> mMessages = new LinkedList<>();
|
private CharSequence mMessage;
|
||||||
private LinkedList<KeyguardIndication> mKeyguardIndicationInfo = new LinkedList<>();
|
private KeyguardIndication mKeyguardIndicationInfo;
|
||||||
|
|
||||||
|
private Animator mLastAnimator;
|
||||||
|
|
||||||
public KeyguardIndicationTextView(Context context) {
|
public KeyguardIndicationTextView(Context context) {
|
||||||
super(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() {
|
public void clearMessages() {
|
||||||
mMessages.clear();
|
if (mLastAnimator != null) {
|
||||||
mKeyguardIndicationInfo.clear();
|
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) {
|
public void switchIndication(int textResId) {
|
||||||
switchIndication(getResources().getText(textResId), null);
|
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.
|
* @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) {
|
public void switchIndication(CharSequence text, KeyguardIndication indication) {
|
||||||
switchIndication(text, indication, true, null);
|
switchIndication(text, indication, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the text with an optional animation. For animating text, makes sure a single
|
* Updates the text with an optional animation.
|
||||||
* indication is shown long enough.
|
|
||||||
*
|
*
|
||||||
* @param text The text to show.
|
* @param text The text to show.
|
||||||
* @param indication optional display information for the text
|
* @param indication optional display information for the text
|
||||||
@@ -112,33 +110,15 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
*/
|
*/
|
||||||
public void switchIndication(CharSequence text, KeyguardIndication indication,
|
public void switchIndication(CharSequence text, KeyguardIndication indication,
|
||||||
boolean animate, Runnable onAnimationEndCallback) {
|
boolean animate, Runnable onAnimationEndCallback) {
|
||||||
if (text == null) text = "";
|
mMessage = text;
|
||||||
|
mKeyguardIndicationInfo = indication;
|
||||||
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);
|
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
final boolean hasIcon = indication != null && indication.getIcon() != null;
|
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
|
// Make sure each animation is visible for a minimum amount of time, while not worrying
|
||||||
// about fading in blank text
|
// about fading in blank text
|
||||||
long timeInMillis = System.currentTimeMillis();
|
if (!TextUtils.isEmpty(mMessage) || hasIcon) {
|
||||||
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();
|
Animator inAnimator = getInAnimator();
|
||||||
inAnimator.addListener(new AnimatorListenerAdapter() {
|
inAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
@@ -164,7 +144,10 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
animator.play(outAnimator);
|
animator.play(outAnimator);
|
||||||
}
|
}
|
||||||
|
|
||||||
animator.setStartDelay(delay);
|
if (mLastAnimator != null) {
|
||||||
|
mLastAnimator.cancel();
|
||||||
|
}
|
||||||
|
mLastAnimator = animator;
|
||||||
animator.start();
|
animator.start();
|
||||||
} else {
|
} else {
|
||||||
setAlpha(1f);
|
setAlpha(1f);
|
||||||
@@ -173,6 +156,10 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
if (onAnimationEndCallback != null) {
|
if (onAnimationEndCallback != null) {
|
||||||
onAnimationEndCallback.run();
|
onAnimationEndCallback.run();
|
||||||
}
|
}
|
||||||
|
if (mLastAnimator != null) {
|
||||||
|
mLastAnimator.cancel();
|
||||||
|
mLastAnimator = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,11 +169,21 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
fadeOut.setDuration(getFadeOutDuration());
|
fadeOut.setDuration(getFadeOutDuration());
|
||||||
fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
|
fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
|
||||||
fadeOut.addListener(new AnimatorListenerAdapter() {
|
fadeOut.addListener(new AnimatorListenerAdapter() {
|
||||||
|
private boolean mCancelled = false;
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animator) {
|
public void onAnimationEnd(Animator animator) {
|
||||||
super.onAnimationEnd(animator);
|
super.onAnimationEnd(animator);
|
||||||
|
if (!mCancelled) {
|
||||||
setNextIndication();
|
setNextIndication();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animator) {
|
||||||
|
super.onAnimationCancel(animator);
|
||||||
|
mCancelled = true;
|
||||||
|
setAlpha(0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Animator yTranslate =
|
Animator yTranslate =
|
||||||
@@ -198,20 +195,19 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setNextIndication() {
|
private void setNextIndication() {
|
||||||
KeyguardIndication info = mKeyguardIndicationInfo.poll();
|
if (mKeyguardIndicationInfo != null) {
|
||||||
if (info != null) {
|
|
||||||
// First, update the style.
|
// First, update the style.
|
||||||
// If a background is set on the text, we don't want shadow on the text
|
// 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);
|
setTextAppearance(sButtonStyleId);
|
||||||
} else {
|
} else {
|
||||||
setTextAppearance(sStyleId);
|
setTextAppearance(sStyleId);
|
||||||
}
|
}
|
||||||
setBackground(info.getBackground());
|
setBackground(mKeyguardIndicationInfo.getBackground());
|
||||||
setTextColor(info.getTextColor());
|
setTextColor(mKeyguardIndicationInfo.getTextColor());
|
||||||
setOnClickListener(info.getClickListener());
|
setOnClickListener(mKeyguardIndicationInfo.getClickListener());
|
||||||
setClickable(info.getClickListener() != null);
|
setClickable(mKeyguardIndicationInfo.getClickListener() != null);
|
||||||
final Drawable icon = info.getIcon();
|
final Drawable icon = mKeyguardIndicationInfo.getIcon();
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
icon.setTint(getCurrentTextColor());
|
icon.setTint(getCurrentTextColor());
|
||||||
if (icon instanceof AnimatedVectorDrawable) {
|
if (icon instanceof AnimatedVectorDrawable) {
|
||||||
@@ -220,7 +216,7 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
}
|
}
|
||||||
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
|
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
|
||||||
}
|
}
|
||||||
setText(mMessages.poll());
|
setText(mMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnimatorSet getInAnimator() {
|
private AnimatorSet getInAnimator() {
|
||||||
@@ -238,6 +234,7 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
public void onAnimationCancel(Animator animation) {
|
public void onAnimationCancel(Animator animation) {
|
||||||
super.onAnimationCancel(animation);
|
super.onAnimationCancel(animation);
|
||||||
setTranslationY(0);
|
setTranslationY(0);
|
||||||
|
setAlpha(1f);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
animatorSet.playTogether(yTranslate, fadeIn);
|
animatorSet.playTogether(yTranslate, fadeIn);
|
||||||
@@ -270,14 +267,6 @@ public class KeyguardIndicationTextView extends TextView {
|
|||||||
return 167L;
|
return 167L;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNextAnimationTime(long time) {
|
|
||||||
if (mAnimationsEnabled) {
|
|
||||||
mNextAnimationTime = time;
|
|
||||||
} else {
|
|
||||||
mNextAnimationTime = 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getYTranslationPixels() {
|
private int getYTranslationPixels() {
|
||||||
return mContext.getResources().getDimensionPixelSize(
|
return mContext.getResources().getDimensionPixelSize(
|
||||||
com.android.systemui.R.dimen.keyguard_indication_y_translation);
|
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_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_DISCLOSURE;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||||
|
|
||||||
@@ -56,7 +57,8 @@ import org.mockito.MockitoAnnotations;
|
|||||||
public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCase {
|
public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
private static final String TEST_MESSAGE = "test message";
|
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
|
@Mock
|
||||||
private DelayableExecutor mExecutor;
|
private DelayableExecutor mExecutor;
|
||||||
@@ -200,6 +202,24 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
|||||||
verify(mExecutor).executeDelayed(any(), anyLong());
|
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
|
@Test
|
||||||
public void testTransientIndication() {
|
public void testTransientIndication() {
|
||||||
// GIVEN we already have two indication messages
|
// GIVEN we already have two indication messages
|
||||||
@@ -223,8 +243,11 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
|||||||
@Test
|
@Test
|
||||||
public void testHideIndicationOneMessage() {
|
public void testHideIndicationOneMessage() {
|
||||||
// GIVEN we have one indication message
|
// GIVEN we have one indication message
|
||||||
|
KeyguardIndication indication = createIndication();
|
||||||
mController.updateIndication(
|
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
|
// WHEN we hide the current indication type
|
||||||
mController.hideIndication(INDICATION_TYPE_OWNER_INFO);
|
mController.hideIndication(INDICATION_TYPE_OWNER_INFO);
|
||||||
@@ -254,6 +277,10 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartDozing() {
|
public void testStartDozing() {
|
||||||
|
// GIVEN a biometric message is showing
|
||||||
|
mController.updateIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE,
|
||||||
|
createIndication(), true);
|
||||||
|
|
||||||
// WHEN the device is dozing
|
// WHEN the device is dozing
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
mStatusBarStateListener.onDozingChanged(true);
|
||||||
|
|
||||||
@@ -293,9 +320,19 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
|
|||||||
verify(mView, never()).switchIndication(any());
|
verify(mView, never()).switchIndication(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an indication with a unique message.
|
||||||
|
*/
|
||||||
private KeyguardIndication createIndication() {
|
private KeyguardIndication createIndication() {
|
||||||
|
return createIndication(TEST_MESSAGE + " " + mMsgId++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an indication with the given message.
|
||||||
|
*/
|
||||||
|
private KeyguardIndication createIndication(String msg) {
|
||||||
return new KeyguardIndication.Builder()
|
return new KeyguardIndication.Builder()
|
||||||
.setMessage(TEST_MESSAGE)
|
.setMessage(msg)
|
||||||
.setTextColor(ColorStateList.valueOf(Color.WHITE))
|
.setTextColor(ColorStateList.valueOf(Color.WHITE))
|
||||||
.build();
|
.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_ALIGNMENT;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
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_DISCLOSURE;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
|
||||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_RESTING;
|
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",
|
private static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName("com.android.foo",
|
||||||
"bar");
|
"bar");
|
||||||
|
|
||||||
|
private static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
|
||||||
|
|
||||||
private String mKeyguardTryFingerprintMsg;
|
private String mKeyguardTryFingerprintMsg;
|
||||||
private String mDisclosureWithOrganization;
|
private String mDisclosureWithOrganization;
|
||||||
private String mDisclosureGeneric;
|
private String mDisclosureGeneric;
|
||||||
@@ -419,7 +422,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// WHEN transient text is shown
|
// WHEN transient text is shown
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
mStatusBarStateListener.onDozingChanged(true);
|
||||||
mController.showTransientIndication("Test");
|
mController.showTransientIndication(TEST_STRING_RES);
|
||||||
|
|
||||||
// THEN wake lock is held while the animation is running
|
// THEN wake lock is held while the animation is running
|
||||||
assertTrue("WakeLock expected: HELD, was: RELEASED", mWakeLock.isHeld());
|
assertTrue("WakeLock expected: HELD, was: RELEASED", mWakeLock.isHeld());
|
||||||
@@ -434,7 +437,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// WHEN we show the transient indication
|
// WHEN we show the transient indication
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
mStatusBarStateListener.onDozingChanged(true);
|
||||||
mController.showTransientIndication("Test");
|
mController.showTransientIndication(TEST_STRING_RES);
|
||||||
|
|
||||||
// THEN wake lock is RELEASED, not held
|
// THEN wake lock is RELEASED, not held
|
||||||
assertFalse("WakeLock expected: RELEASED, was: HELD", mWakeLock.isHeld());
|
assertFalse("WakeLock expected: RELEASED, was: HELD", mWakeLock.isHeld());
|
||||||
@@ -445,10 +448,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
createController();
|
createController();
|
||||||
|
|
||||||
mController.setVisible(true);
|
mController.setVisible(true);
|
||||||
mController.showTransientIndication("Test");
|
mController.showTransientIndication(TEST_STRING_RES);
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
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.getCurrentTextColor()).isEqualTo(Color.WHITE);
|
||||||
assertThat(mTextView.getAlpha()).isEqualTo(1f);
|
assertThat(mTextView.getAlpha()).isEqualTo(1f);
|
||||||
}
|
}
|
||||||
@@ -462,11 +466,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
mController.getKeyguardCallback().onBiometricHelp(
|
mController.getKeyguardCallback().onBiometricHelp(
|
||||||
KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
|
KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
|
||||||
BiometricSourceType.FACE);
|
BiometricSourceType.FACE);
|
||||||
verifyTransientMessage(message);
|
verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message);
|
||||||
reset(mRotateTextViewController);
|
reset(mRotateTextViewController);
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
mStatusBarStateListener.onDozingChanged(true);
|
||||||
|
|
||||||
verifyHideIndication(INDICATION_TYPE_TRANSIENT);
|
verifyHideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -478,7 +482,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
|
mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
|
||||||
"A message", BiometricSourceType.FACE);
|
"A message", BiometricSourceType.FACE);
|
||||||
|
|
||||||
verifyTransientMessage(message);
|
verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message);
|
||||||
mStatusBarStateListener.onDozingChanged(true);
|
mStatusBarStateListener.onDozingChanged(true);
|
||||||
|
|
||||||
assertThat(mTextView.getText()).isNotEqualTo(message);
|
assertThat(mTextView.getText()).isNotEqualTo(message);
|
||||||
@@ -497,7 +501,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
FingerprintManager.FINGERPRINT_ERROR_CANCELED, "bar",
|
FingerprintManager.FINGERPRINT_ERROR_CANCELED, "bar",
|
||||||
BiometricSourceType.FINGERPRINT);
|
BiometricSourceType.FINGERPRINT);
|
||||||
|
|
||||||
verifyNoTransientMessage();
|
verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||||
|
verifyNoMessage(INDICATION_TYPE_TRANSIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -757,7 +762,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
verify(mRotateTextViewController).showTransient(eq(message));
|
verify(mRotateTextViewController).showTransient(eq(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNoTransientMessage() {
|
private void verifyNoMessage(int type) {
|
||||||
verify(mRotateTextViewController, never()).showTransient(any());
|
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