Merge "GPay activity can use passive biometric auth" into sc-dev
This commit is contained in:
@@ -12,6 +12,7 @@ data class KeyguardFaceListenModel(
|
|||||||
val isListeningForFace: Boolean,
|
val isListeningForFace: Boolean,
|
||||||
val isBouncer: Boolean,
|
val isBouncer: Boolean,
|
||||||
val isAuthInterruptActive: Boolean,
|
val isAuthInterruptActive: Boolean,
|
||||||
|
val isOccludingAppRequestingFaceAuth: Boolean,
|
||||||
val isKeyguardAwake: Boolean,
|
val isKeyguardAwake: Boolean,
|
||||||
val isListeningForFaceAssistant: Boolean,
|
val isListeningForFaceAssistant: Boolean,
|
||||||
val isSwitchingUser: Boolean,
|
val isSwitchingUser: Boolean,
|
||||||
|
|||||||
@@ -276,6 +276,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
private boolean mHasLockscreenWallpaper;
|
private boolean mHasLockscreenWallpaper;
|
||||||
private boolean mAssistantVisible;
|
private boolean mAssistantVisible;
|
||||||
private boolean mKeyguardOccluded;
|
private boolean mKeyguardOccluded;
|
||||||
|
private boolean mOccludingAppRequestingFp;
|
||||||
|
private boolean mOccludingAppRequestingFace;
|
||||||
private boolean mSecureCameraLaunched;
|
private boolean mSecureCameraLaunched;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected boolean mTelephonyCapable;
|
protected boolean mTelephonyCapable;
|
||||||
@@ -587,6 +589,29 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
updateBiometricListeningState();
|
updateBiometricListeningState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to listen for face authentication when an app is occluding keyguard.
|
||||||
|
* @param request if true and mKeyguardOccluded, request face auth listening, else default
|
||||||
|
* to normal behavior.
|
||||||
|
* See {@link KeyguardUpdateMonitor#shouldListenForFace()}
|
||||||
|
*/
|
||||||
|
public void requestFaceAuthOnOccludingApp(boolean request) {
|
||||||
|
mOccludingAppRequestingFace = request;
|
||||||
|
updateFaceListeningState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to listen for fingerprint when an app is occluding keyguard.
|
||||||
|
* @param request if true and mKeyguardOccluded, request fingerprint listening, else default
|
||||||
|
* to normal behavior.
|
||||||
|
* See {@link KeyguardUpdateMonitor#shouldListenForFingerprint(boolean)}
|
||||||
|
*/
|
||||||
|
public void requestFingerprintAuthOnOccludingApp(boolean request) {
|
||||||
|
mOccludingAppRequestingFp = request;
|
||||||
|
updateFingerprintListeningState();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the secure camera is launched.
|
* Invoked when the secure camera is launched.
|
||||||
*/
|
*/
|
||||||
@@ -2093,6 +2118,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected boolean shouldListenForFingerprint(boolean isUdfps) {
|
protected boolean shouldListenForFingerprint(boolean isUdfps) {
|
||||||
|
final boolean userDoesNotHaveTrust = !getUserHasTrust(getCurrentUser());
|
||||||
final boolean shouldListenKeyguardState =
|
final boolean shouldListenKeyguardState =
|
||||||
mKeyguardIsVisible
|
mKeyguardIsVisible
|
||||||
|| !mDeviceInteractive
|
|| !mDeviceInteractive
|
||||||
@@ -2100,7 +2126,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|| mGoingToSleep
|
|| mGoingToSleep
|
||||||
|| shouldListenForFingerprintAssistant()
|
|| shouldListenForFingerprintAssistant()
|
||||||
|| (mKeyguardOccluded && mIsDreaming)
|
|| (mKeyguardOccluded && mIsDreaming)
|
||||||
|| (isUdfps && mKeyguardOccluded);
|
|| (mKeyguardOccluded && userDoesNotHaveTrust
|
||||||
|
&& (mOccludingAppRequestingFp || isUdfps));
|
||||||
|
|
||||||
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
|
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
|
||||||
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
|
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
|
||||||
@@ -2117,7 +2144,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
final boolean shouldListenUdfpsState = !isUdfps
|
final boolean shouldListenUdfpsState = !isUdfps
|
||||||
|| (!getUserCanSkipBouncer(getCurrentUser())
|
|| (!getUserCanSkipBouncer(getCurrentUser())
|
||||||
&& !isEncryptedOrLockdown(getCurrentUser())
|
&& !isEncryptedOrLockdown(getCurrentUser())
|
||||||
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot());
|
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot()
|
||||||
|
&& userDoesNotHaveTrust);
|
||||||
|
|
||||||
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
|
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
|
||||||
&& shouldListenUdfpsState;
|
&& shouldListenUdfpsState;
|
||||||
@@ -2166,7 +2194,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
|
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
|
||||||
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
|
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
|
||||||
final boolean shouldListen =
|
final boolean shouldListen =
|
||||||
(mBouncer || mAuthInterruptActive || awakeKeyguard
|
(mBouncer || mAuthInterruptActive || mOccludingAppRequestingFace || awakeKeyguard
|
||||||
|| shouldListenForFaceAssistant())
|
|| shouldListenForFaceAssistant())
|
||||||
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
|
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
|
||||||
&& !mKeyguardGoingAway && mBiometricEnabledForUser.get(user) && !mLockIconPressed
|
&& !mKeyguardGoingAway && mBiometricEnabledForUser.get(user) && !mLockIconPressed
|
||||||
@@ -2181,6 +2209,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
shouldListen,
|
shouldListen,
|
||||||
mBouncer,
|
mBouncer,
|
||||||
mAuthInterruptActive,
|
mAuthInterruptActive,
|
||||||
|
mOccludingAppRequestingFace,
|
||||||
awakeKeyguard,
|
awakeKeyguard,
|
||||||
shouldListenForFaceAssistant(),
|
shouldListenForFaceAssistant(),
|
||||||
mSwitchingUser,
|
mSwitchingUser,
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
|||||||
mView.announceForAccessibility(mView.getContext().getString(
|
mView.announceForAccessibility(mView.getContext().getString(
|
||||||
R.string.accessibility_fingerprint_bouncer));
|
R.string.accessibility_fingerprint_bouncer));
|
||||||
} else {
|
} else {
|
||||||
mView.animateAwayUdfpsBouncer(() -> mKeyguardViewManager.cancelPostAuthActions());
|
mView.animateAwayUdfpsBouncer(null);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,8 +231,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
|
|||||||
*/
|
*/
|
||||||
private void maybeShowInputBouncer() {
|
private void maybeShowInputBouncer() {
|
||||||
if (mShowingUdfpsBouncer) {
|
if (mShowingUdfpsBouncer) {
|
||||||
mKeyguardViewManager.resetAlternateAuth(false);
|
|
||||||
mKeyguardViewManager.showBouncer(true);
|
mKeyguardViewManager.showBouncer(true);
|
||||||
|
mKeyguardViewManager.resetAlternateAuth(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ public class MediaControlPanel {
|
|||||||
mMediaDataManagerLazy.get().dismissMediaData(mKey,
|
mMediaDataManagerLazy.get().dismissMediaData(mKey,
|
||||||
MediaViewController.GUTS_ANIMATION_DURATION + 100);
|
MediaViewController.GUTS_ANIMATION_DURATION + 100);
|
||||||
return true;
|
return true;
|
||||||
}, /* requiresShadeOpen */ true);
|
}, /* requiresShadeOpen */ true, false);
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Dismiss media with null notification. Token uid="
|
Log.w(TAG, "Dismiss media with null notification. Token uid="
|
||||||
+ data.getToken().getUid());
|
+ data.getToken().getUid());
|
||||||
@@ -564,7 +564,7 @@ public class MediaControlPanel {
|
|||||||
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
|
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
|
||||||
MediaViewController.GUTS_ANIMATION_DURATION + 100L);
|
MediaViewController.GUTS_ANIMATION_DURATION + 100L);
|
||||||
return true;
|
return true;
|
||||||
}, true /* requiresShadeOpen */);
|
}, true /* requiresShadeOpen */, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
mController = null;
|
mController = null;
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
|
|||||||
mHost.getUserContext().startActivity(intent);
|
mHost.getUserContext().startActivity(intent);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false);
|
mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelCountdown() {
|
private void cancelCountdown() {
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis
|
|||||||
// Remove notification
|
// Remove notification
|
||||||
mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
|
mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
|
||||||
return false;
|
return false;
|
||||||
}, false);
|
}, false, false);
|
||||||
|
|
||||||
// Close quick shade
|
// Close quick shade
|
||||||
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ class SensorUseStartedActivity @Inject constructor(
|
|||||||
keyguardDismissUtil.executeWhenUnlocked({
|
keyguardDismissUtil.executeWhenUnlocked({
|
||||||
disableSensorPrivacy()
|
disableSensorPrivacy()
|
||||||
false
|
false
|
||||||
}, false)
|
}, false, false)
|
||||||
} else {
|
} else {
|
||||||
disableSensorPrivacy()
|
disableSensorPrivacy()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import com.android.keyguard.KeyguardConstants;
|
|||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||||
import com.android.keyguard.KeyguardViewController;
|
import com.android.keyguard.KeyguardViewController;
|
||||||
import com.android.systemui.Dependency;
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
@@ -250,16 +249,20 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
|||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||||
@Main Resources resources,
|
@Main Resources resources,
|
||||||
KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters,
|
KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters,
|
||||||
MetricsLogger metricsLogger, DumpManager dumpManager) {
|
MetricsLogger metricsLogger, DumpManager dumpManager,
|
||||||
|
PowerManager powerManager,
|
||||||
|
NotificationMediaManager notificationMediaManager,
|
||||||
|
WakefulnessLifecycle wakefulnessLifecycle,
|
||||||
|
ScreenLifecycle screenLifecycle) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPowerManager = context.getSystemService(PowerManager.class);
|
mPowerManager = powerManager;
|
||||||
mShadeController = shadeController;
|
mShadeController = shadeController;
|
||||||
mUpdateMonitor = keyguardUpdateMonitor;
|
mUpdateMonitor = keyguardUpdateMonitor;
|
||||||
mDozeParameters = dozeParameters;
|
mDozeParameters = dozeParameters;
|
||||||
mUpdateMonitor.registerCallback(this);
|
mUpdateMonitor.registerCallback(this);
|
||||||
mMediaManager = Dependency.get(NotificationMediaManager.class);
|
mMediaManager = notificationMediaManager;
|
||||||
Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
|
wakefulnessLifecycle.addObserver(mWakefulnessObserver);
|
||||||
Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
|
screenLifecycle.addObserver(mScreenObserver);
|
||||||
|
|
||||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||||
mDozeScrimController = dozeScrimController;
|
mDozeScrimController = dozeScrimController;
|
||||||
@@ -415,7 +418,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
|||||||
if (!wasDeviceInteractive) {
|
if (!wasDeviceInteractive) {
|
||||||
mPendingShowBouncer = true;
|
mPendingShowBouncer = true;
|
||||||
} else {
|
} else {
|
||||||
showBouncer();
|
mPendingShowBouncer = false;
|
||||||
mKeyguardViewController.notifyKeyguardAuthenticated(
|
mKeyguardViewController.notifyKeyguardAuthenticated(
|
||||||
false /* strongAuth */);
|
false /* strongAuth */);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public interface KeyguardDismissHandler {
|
|||||||
* Executes an action that requres the screen to be unlocked, showing the keyguard if
|
* Executes an action that requres the screen to be unlocked, showing the keyguard if
|
||||||
* necessary. Does not close the notification shade (in case it was open).
|
* necessary. Does not close the notification shade (in case it was open).
|
||||||
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
|
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
|
||||||
|
* @param afterKeyguardGone run the dismiss action after keyguard is gone?
|
||||||
*/
|
*/
|
||||||
void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen);
|
void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
|
||||||
|
boolean afterKeyguardGone);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,13 +50,14 @@ public class KeyguardDismissUtil implements KeyguardDismissHandler {
|
|||||||
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
|
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
|
public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
|
||||||
|
boolean afterKeyguardGone) {
|
||||||
KeyguardDismissHandler dismissHandler = mDismissHandler;
|
KeyguardDismissHandler dismissHandler = mDismissHandler;
|
||||||
if (dismissHandler == null) {
|
if (dismissHandler == null) {
|
||||||
Log.wtf(TAG, "KeyguardDismissHandler not set.");
|
Log.wtf(TAG, "KeyguardDismissHandler not set.");
|
||||||
action.onDismiss();
|
action.onDismiss();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dismissHandler.executeWhenUnlocked(action, requiresShadeOpen);
|
dismissHandler.executeWhenUnlocked(action, requiresShadeOpen, afterKeyguardGone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2988,11 +2988,13 @@ public class StatusBar extends SystemUI implements DemoMode,
|
|||||||
mNotificationsController.resetUserExpandedStates();
|
mNotificationsController.resetUserExpandedStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
|
private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
|
||||||
|
boolean afterKeyguardGone) {
|
||||||
if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
|
if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
|
||||||
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
|
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
|
||||||
}
|
}
|
||||||
dismissKeyguardThenExecute(action, null /* cancelAction */, false /* afterKeyguardGone */);
|
dismissKeyguardThenExecute(action, null /* cancelAction */,
|
||||||
|
afterKeyguardGone /* afterKeyguardGone */);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
|
protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVisibilityChanged(boolean isVisible) {
|
public void onVisibilityChanged(boolean isVisible) {
|
||||||
|
if (!isVisible) {
|
||||||
|
cancelPostAuthActions();
|
||||||
|
}
|
||||||
if (mAlternateAuthInterceptor != null) {
|
if (mAlternateAuthInterceptor != null) {
|
||||||
mAlternateAuthInterceptor.onBouncerVisibilityChanged();
|
mAlternateAuthInterceptor.onBouncerVisibilityChanged();
|
||||||
}
|
}
|
||||||
@@ -406,21 +409,25 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAlternateAuthInterceptor != null) {
|
|
||||||
mAfterKeyguardGoneAction = r;
|
mAfterKeyguardGoneAction = r;
|
||||||
mKeyguardGoneCancelAction = cancelAction;
|
mKeyguardGoneCancelAction = cancelAction;
|
||||||
|
if (mAlternateAuthInterceptor != null) {
|
||||||
if (mAlternateAuthInterceptor.showAlternateAuthBouncer()) {
|
if (mAlternateAuthInterceptor.showAlternateAuthBouncer()) {
|
||||||
mStatusBar.updateScrimController();
|
mStatusBar.updateScrimController();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!afterKeyguardGone) {
|
if (afterKeyguardGone) {
|
||||||
mBouncer.showWithDismissAction(r, cancelAction);
|
// we'll handle the dismiss action after keyguard is gone, so just show the bouncer
|
||||||
} else {
|
|
||||||
mAfterKeyguardGoneAction = r;
|
|
||||||
mKeyguardGoneCancelAction = cancelAction;
|
|
||||||
mBouncer.show(false /* resetSecuritySelection */);
|
mBouncer.show(false /* resetSecuritySelection */);
|
||||||
|
} else {
|
||||||
|
// after authentication success, run dismiss action with the option to defer
|
||||||
|
// hiding the keyguard based on the return value of the OnDismissAction
|
||||||
|
mBouncer.showWithDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
|
||||||
|
// bouncer will handle the dismiss action, so we no longer need to track it here
|
||||||
|
mAfterKeyguardGoneAction = null;
|
||||||
|
mKeyguardGoneCancelAction = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateStates();
|
updateStates();
|
||||||
@@ -1133,15 +1140,21 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to show the udfps affordance in a particular color. This can be used if an
|
* Request to authenticate using face.
|
||||||
* occluding app on the keyguard would like to request udfps. This method does nothing if
|
|
||||||
* {@link KeyguardUpdateMonitor#shouldListenForFingerprint} is false.
|
|
||||||
*/
|
*/
|
||||||
public void requestUdfps(boolean request, int color) {
|
public void requestFace(boolean request) {
|
||||||
if (mAlternateAuthInterceptor == null) {
|
mKeyguardUpdateManager.requestFaceAuthOnOccludingApp(request);
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to authenticate using the fingerprint sensor. If the fingerprint sensor is udfps,
|
||||||
|
* uses the color provided by udfpsColor for the fingerprint icon.
|
||||||
|
*/
|
||||||
|
public void requestFp(boolean request, int udfpsColor) {
|
||||||
|
mKeyguardUpdateManager.requestFingerprintAuthOnOccludingApp(request);
|
||||||
|
if (mAlternateAuthInterceptor != null) {
|
||||||
|
mAlternateAuthInterceptor.requestUdfps(request, udfpsColor);
|
||||||
}
|
}
|
||||||
mAlternateAuthInterceptor.requestUdfps(request, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
|
|||||||
private fun KeyguardDismissUtil.executeWhenUnlocked(
|
private fun KeyguardDismissUtil.executeWhenUnlocked(
|
||||||
requiresShadeOpen: Boolean,
|
requiresShadeOpen: Boolean,
|
||||||
onDismissAction: () -> Boolean
|
onDismissAction: () -> Boolean
|
||||||
) = executeWhenUnlocked(onDismissAction, requiresShadeOpen)
|
) = executeWhenUnlocked(onDismissAction, requiresShadeOpen, false)
|
||||||
|
|
||||||
// convenience function that swaps parameter order so that lambda can be placed at the end
|
// convenience function that swaps parameter order so that lambda can be placed at the end
|
||||||
private fun ActivityStarter.startPendingIntentDismissingKeyguard(
|
private fun ActivityStarter.startPendingIntentDismissingKeyguard(
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
getActionBar().setHomeAsUpIndicator(getHomeIndicatorDrawable());
|
getActionBar().setHomeAsUpIndicator(getHomeIndicatorDrawable());
|
||||||
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
|
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
|
||||||
WalletView walletView = requireViewById(R.id.wallet_view);
|
WalletView walletView = requireViewById(R.id.wallet_view);
|
||||||
|
|
||||||
mWalletScreenController = new WalletScreenController(
|
mWalletScreenController = new WalletScreenController(
|
||||||
this,
|
this,
|
||||||
walletView,
|
walletView,
|
||||||
@@ -116,21 +117,32 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mKeyguardStateController.isUnlocked()) {
|
||||||
mActivityStarter.startActivity(
|
mActivityStarter.startActivity(
|
||||||
mQuickAccessWalletClient.createWalletIntent(), true);
|
mQuickAccessWalletClient.createWalletIntent(), true);
|
||||||
finish();
|
finish();
|
||||||
|
} else {
|
||||||
|
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
|
||||||
|
mActivityStarter.startActivity(
|
||||||
|
mQuickAccessWalletClient.createWalletIntent(), true);
|
||||||
|
finish();
|
||||||
|
return false;
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Click the action button to re-render the screen when the device is unlocked.
|
// Click the action button to re-render the screen when the device is unlocked.
|
||||||
if (!mKeyguardStateController.isUnlocked()) {
|
walletView.setDeviceLockedActionOnClickListener(
|
||||||
walletView.getActionButton().setOnClickListener(
|
|
||||||
v -> {
|
v -> {
|
||||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false);
|
|
||||||
|
mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false,
|
||||||
|
false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
@@ -142,13 +154,15 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
mWalletScreenController.queryWalletCards();
|
mWalletScreenController.queryWalletCards();
|
||||||
mKeyguardViewManager.requestUdfps(true, Color.BLACK);
|
mKeyguardViewManager.requestFp(true, Color.BLACK);
|
||||||
|
mKeyguardViewManager.requestFace(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
mKeyguardViewManager.requestUdfps(false, -1);
|
mKeyguardViewManager.requestFp(false, -1);
|
||||||
|
mKeyguardViewManager.requestFace(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -177,6 +177,11 @@ public class WalletScreenController implements
|
|||||||
queryWalletCards();
|
queryWalletCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnlockedChanged() {
|
||||||
|
queryWalletCards();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCardSelected(@NonNull WalletCardViewInfo card) {
|
public void onCardSelected(@NonNull WalletCardViewInfo card) {
|
||||||
if (mIsDismissed) {
|
if (mIsDismissed) {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
private final ViewGroup mEmptyStateView;
|
private final ViewGroup mEmptyStateView;
|
||||||
private CharSequence mCenterCardText;
|
private CharSequence mCenterCardText;
|
||||||
private boolean mIsDeviceLocked = false;
|
private boolean mIsDeviceLocked = false;
|
||||||
|
private OnClickListener mDeviceLockedActionOnClickListener;
|
||||||
|
|
||||||
public WalletView(Context context) {
|
public WalletView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -178,6 +179,10 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
mEmptyStateView.setVisibility(GONE);
|
mEmptyStateView.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDeviceLockedActionOnClickListener(OnClickListener onClickListener) {
|
||||||
|
mDeviceLockedActionOnClickListener = onClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
void hide() {
|
void hide() {
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
}
|
}
|
||||||
@@ -238,6 +243,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
if (isDeviceLocked) {
|
if (isDeviceLocked) {
|
||||||
mActionButton.setVisibility(VISIBLE);
|
mActionButton.setVisibility(VISIBLE);
|
||||||
mActionButton.setText(R.string.wallet_action_button_label_unlock);
|
mActionButton.setText(R.string.wallet_action_button_label_unlock);
|
||||||
|
mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener);
|
||||||
} else if (actionButtonText != null) {
|
} else if (actionButtonText != null) {
|
||||||
mActionButton.setText(actionButtonText);
|
mActionButton.setText(actionButtonText);
|
||||||
mActionButton.setVisibility(VISIBLE);
|
mActionButton.setVisibility(VISIBLE);
|
||||||
|
|||||||
@@ -842,10 +842,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testStartUdfpsServiceBeginsOnKeyguard() {
|
public void testStartUdfpsServiceBeginsOnKeyguard() {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
// - bouncer isn't showing
|
|
||||||
// - status bar state is on the keyguard
|
// - status bar state is on the keyguard
|
||||||
// - user has authenticated since boot
|
// - user has authenticated since boot
|
||||||
setKeyguardBouncerVisibility(false /* isVisible */);
|
|
||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
||||||
|
|
||||||
@@ -853,12 +851,45 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOccludingAppFingerprintListeningState() {
|
||||||
|
// GIVEN keyguard isn't visible (app occluding)
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
|
||||||
|
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
|
||||||
|
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false);
|
||||||
|
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
||||||
|
|
||||||
|
// THEN we shouldn't listen for fingerprints
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
|
||||||
|
|
||||||
|
// THEN we should listen for udfps (hiding of mechanism to actually auth is
|
||||||
|
// controlled by UdfpsKeyguardViewController)
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOccludingAppRequestsFingerprint() {
|
||||||
|
// GIVEN keyguard isn't visible (app occluding)
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
|
||||||
|
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
|
||||||
|
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false);
|
||||||
|
|
||||||
|
// WHEN an occluding app requests fp
|
||||||
|
mKeyguardUpdateMonitor.requestFingerprintAuthOnOccludingApp(true);
|
||||||
|
|
||||||
|
// THEN we should listen for fingerprints
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(true);
|
||||||
|
|
||||||
|
// WHEN an occluding app stops requesting fp
|
||||||
|
mKeyguardUpdateMonitor.requestFingerprintAuthOnOccludingApp(false);
|
||||||
|
|
||||||
|
// THEN we shouldn't listen for fingeprints
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
|
public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
|
||||||
// GIVEN
|
// GIVEN status bar state is on the keyguard
|
||||||
// - bouncer isn't showing
|
|
||||||
// - status bar state is on the keyguard
|
|
||||||
setKeyguardBouncerVisibility(false /* isVisible */);
|
|
||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
|
|
||||||
// WHEN user hasn't authenticated since last boot
|
// WHEN user hasn't authenticated since last boot
|
||||||
@@ -871,7 +902,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testShouldNotListenForUdfps_whenTrustEnabled() {
|
public void testShouldNotListenForUdfps_whenTrustEnabled() {
|
||||||
// GIVEN a "we should listen for udfps" state
|
// GIVEN a "we should listen for udfps" state
|
||||||
setKeyguardBouncerVisibility(false /* isVisible */);
|
|
||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
||||||
|
|
||||||
@@ -886,7 +916,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testShouldNotListenForUdfps_whenFaceAuthenticated() {
|
public void testShouldNotListenForUdfps_whenFaceAuthenticated() {
|
||||||
// GIVEN a "we should listen for udfps" state
|
// GIVEN a "we should listen for udfps" state
|
||||||
setKeyguardBouncerVisibility(false /* isVisible */);
|
|
||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
||||||
|
|
||||||
|
|||||||
@@ -325,7 +325,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
|||||||
assertThat(dismiss.isEnabled).isEqualTo(true)
|
assertThat(dismiss.isEnabled).isEqualTo(true)
|
||||||
dismiss.callOnClick()
|
dismiss.callOnClick()
|
||||||
val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java)
|
val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java)
|
||||||
verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean())
|
verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean(),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
captor.value.onDismiss()
|
captor.value.onDismiss()
|
||||||
verify(mediaDataManager).dismissMediaData(eq(mediaKey), anyLong())
|
verify(mediaDataManager).dismissMediaData(eq(mediaKey), anyLong())
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
|||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||||
|
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||||
|
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
import com.android.systemui.statusbar.NotificationMediaManager;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
@@ -90,6 +92,12 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
private DozeParameters mDozeParameters;
|
private DozeParameters mDozeParameters;
|
||||||
@Mock
|
@Mock
|
||||||
private MetricsLogger mMetricsLogger;
|
private MetricsLogger mMetricsLogger;
|
||||||
|
@Mock
|
||||||
|
private NotificationMediaManager mNotificationMediaManager;
|
||||||
|
@Mock
|
||||||
|
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||||
|
@Mock
|
||||||
|
private ScreenLifecycle mScreenLifecycle;
|
||||||
private BiometricUnlockController mBiometricUnlockController;
|
private BiometricUnlockController mBiometricUnlockController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -109,7 +117,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
mKeyguardViewMediator, mScrimController, mShadeController,
|
mKeyguardViewMediator, mScrimController, mShadeController,
|
||||||
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
|
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
|
||||||
mUpdateMonitor, res.getResources(), mKeyguardBypassController, mDozeParameters,
|
mUpdateMonitor, res.getResources(), mKeyguardBypassController, mDozeParameters,
|
||||||
mMetricsLogger, mDumpManager);
|
mMetricsLogger, mDumpManager, mPowerManager,
|
||||||
|
mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle);
|
||||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||||
mBiometricUnlockController.setBiometricModeListener(mBiometricModeListener);
|
mBiometricUnlockController.setBiometricModeListener(mBiometricModeListener);
|
||||||
}
|
}
|
||||||
@@ -121,8 +130,6 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
|
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
|
||||||
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
|
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
|
||||||
verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
|
verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
|
||||||
verify(mShadeController).animateCollapsePanels(anyInt(), anyBoolean(), anyBoolean(),
|
|
||||||
anyFloat());
|
|
||||||
verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
|
verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
|
||||||
assertThat(mBiometricUnlockController.getMode())
|
assertThat(mBiometricUnlockController.getMode())
|
||||||
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
|
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
|
||||||
@@ -161,7 +168,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBiometricAuthenticated_whenFingerprint_dismissKeyguard() {
|
public void onBiometricAuthenticated_whenFingerprint_notifyKeyguardAuthenticated() {
|
||||||
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||||
// the value of isStrongBiometric doesn't matter here since we only care about the returned
|
// the value of isStrongBiometric doesn't matter here since we only care about the returned
|
||||||
// value of isUnlockingWithBiometricAllowed()
|
// value of isUnlockingWithBiometricAllowed()
|
||||||
@@ -169,8 +176,6 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
|
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
|
||||||
|
|
||||||
verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
|
verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
|
||||||
verify(mShadeController).animateCollapsePanels(anyInt(), anyBoolean(), anyBoolean(),
|
|
||||||
anyFloat());
|
|
||||||
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
|
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
|
||||||
assertThat(mBiometricUnlockController.getMode())
|
assertThat(mBiometricUnlockController.getMode())
|
||||||
.isEqualTo(BiometricUnlockController.MODE_UNLOCK_COLLAPSING);
|
.isEqualTo(BiometricUnlockController.MODE_UNLOCK_COLLAPSING);
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mReceiver = new BlockingQueueIntentReceiver();
|
mReceiver = new BlockingQueueIntentReceiver();
|
||||||
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
|
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
|
||||||
mKeyguardDismissUtil.setDismissHandler((action, unused) -> action.onDismiss());
|
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> action.onDismiss());
|
||||||
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
|
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
|
||||||
mDependency.injectMockDependency(ShadeController.class);
|
mDependency.injectMockDependency(ShadeController.class);
|
||||||
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
|
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
|
||||||
@@ -183,7 +183,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
|
public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
|
||||||
mKeyguardDismissUtil.setDismissHandler((action, unused) -> { });
|
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> { });
|
||||||
setSmartReplies(TEST_CHOICES);
|
setSmartReplies(TEST_CHOICES);
|
||||||
|
|
||||||
mView.getChildAt(2).performClick();
|
mView.getChildAt(2).performClick();
|
||||||
@@ -195,7 +195,8 @@ public class SmartReplyViewTest extends SysuiTestCase {
|
|||||||
public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
|
public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
|
||||||
AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
|
AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
|
||||||
|
|
||||||
mKeyguardDismissUtil.setDismissHandler((action, unused) -> actionRef.set(action));
|
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone)
|
||||||
|
-> actionRef.set(action));
|
||||||
setSmartReplies(TEST_CHOICES);
|
setSmartReplies(TEST_CHOICES);
|
||||||
|
|
||||||
mView.getChildAt(2).performClick();
|
mView.getChildAt(2).performClick();
|
||||||
|
|||||||
Reference in New Issue
Block a user