Merge "Fix BiometricPrompt cannot detect when press the notification in LS" into tm-qpr-dev
This commit is contained in:
@@ -249,13 +249,13 @@ public class AuthContainerView extends LinearLayout
|
||||
break;
|
||||
case AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN:
|
||||
mFailedModalities.clear();
|
||||
mConfig.mCallback.onTryAgainPressed();
|
||||
mConfig.mCallback.onTryAgainPressed(getRequestId());
|
||||
break;
|
||||
case AuthBiometricView.Callback.ACTION_ERROR:
|
||||
animateAway(AuthDialogCallback.DISMISSED_ERROR);
|
||||
break;
|
||||
case AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL:
|
||||
mConfig.mCallback.onDeviceCredentialPressed();
|
||||
mConfig.mCallback.onDeviceCredentialPressed(getRequestId());
|
||||
mHandler.postDelayed(() -> {
|
||||
addCredentialView(false /* animatePanel */, true /* animateContents */);
|
||||
}, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS);
|
||||
@@ -373,7 +373,7 @@ public class AuthContainerView extends LinearLayout
|
||||
|
||||
void sendEarlyUserCanceled() {
|
||||
mConfig.mCallback.onSystemEvent(
|
||||
BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL);
|
||||
BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL, getRequestId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -774,7 +774,8 @@ public class AuthContainerView extends LinearLayout
|
||||
private void sendPendingCallbackIfNotNull() {
|
||||
Log.d(TAG, "pendingCallback: " + mPendingCallbackReason);
|
||||
if (mPendingCallbackReason != null) {
|
||||
mConfig.mCallback.onDismissed(mPendingCallbackReason, mCredentialAttestation);
|
||||
mConfig.mCallback.onDismissed(mPendingCallbackReason,
|
||||
mCredentialAttestation, getRequestId());
|
||||
mPendingCallbackReason = null;
|
||||
}
|
||||
}
|
||||
@@ -804,7 +805,7 @@ public class AuthContainerView extends LinearLayout
|
||||
}
|
||||
mContainerState = STATE_SHOWING;
|
||||
if (mBiometricView != null) {
|
||||
mConfig.mCallback.onDialogAnimatedIn();
|
||||
mConfig.mCallback.onDialogAnimatedIn(getRequestId());
|
||||
mBiometricView.onDialogAnimatedIn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,11 +340,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTryAgainPressed() {
|
||||
public void onTryAgainPressed(long requestId) {
|
||||
if (mReceiver == null) {
|
||||
Log.e(TAG, "onTryAgainPressed: Receiver is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestId != mCurrentDialog.getRequestId()) {
|
||||
Log.w(TAG, "requestId doesn't match, skip onTryAgainPressed");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mReceiver.onTryAgainPressed();
|
||||
} catch (RemoteException e) {
|
||||
@@ -353,11 +359,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceCredentialPressed() {
|
||||
public void onDeviceCredentialPressed(long requestId) {
|
||||
if (mReceiver == null) {
|
||||
Log.e(TAG, "onDeviceCredentialPressed: Receiver is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestId != mCurrentDialog.getRequestId()) {
|
||||
Log.w(TAG, "requestId doesn't match, skip onDeviceCredentialPressed");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mReceiver.onDeviceCredentialPressed();
|
||||
} catch (RemoteException e) {
|
||||
@@ -366,11 +378,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemEvent(int event) {
|
||||
public void onSystemEvent(int event, long requestId) {
|
||||
if (mReceiver == null) {
|
||||
Log.e(TAG, "onSystemEvent(" + event + "): Receiver is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestId != mCurrentDialog.getRequestId()) {
|
||||
Log.w(TAG, "requestId doesn't match, skip onSystemEvent");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mReceiver.onSystemEvent(event);
|
||||
} catch (RemoteException e) {
|
||||
@@ -379,12 +397,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogAnimatedIn() {
|
||||
public void onDialogAnimatedIn(long requestId) {
|
||||
if (mReceiver == null) {
|
||||
Log.e(TAG, "onDialogAnimatedIn: Receiver is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestId != mCurrentDialog.getRequestId()) {
|
||||
Log.w(TAG, "requestId doesn't match, skip onDialogAnimatedIn");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mReceiver.onDialogAnimatedIn();
|
||||
} catch (RemoteException e) {
|
||||
@@ -393,7 +416,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) {
|
||||
public void onDismissed(@DismissedReason int reason,
|
||||
@Nullable byte[] credentialAttestation, long requestId) {
|
||||
|
||||
if (mCurrentDialog != null && requestId != mCurrentDialog.getRequestId()) {
|
||||
Log.w(TAG, "requestId doesn't match, skip onDismissed");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (reason) {
|
||||
case AuthDialogCallback.DISMISSED_USER_CANCELED:
|
||||
sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
|
||||
|
||||
@@ -47,27 +47,28 @@ public interface AuthDialogCallback {
|
||||
* @param reason
|
||||
* @param credentialAttestation the HAT received from LockSettingsService upon verification
|
||||
*/
|
||||
void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation);
|
||||
void onDismissed(@DismissedReason int reason,
|
||||
@Nullable byte[] credentialAttestation, long requestId);
|
||||
|
||||
/**
|
||||
* Invoked when the "try again" button is clicked
|
||||
*/
|
||||
void onTryAgainPressed();
|
||||
void onTryAgainPressed(long requestId);
|
||||
|
||||
/**
|
||||
* Invoked when the "use password" button is clicked
|
||||
*/
|
||||
void onDeviceCredentialPressed();
|
||||
void onDeviceCredentialPressed(long requestId);
|
||||
|
||||
/**
|
||||
* See {@link android.hardware.biometrics.BiometricPrompt.Builder
|
||||
* #setReceiveSystemEvents(boolean)}
|
||||
* @param event
|
||||
*/
|
||||
void onSystemEvent(int event);
|
||||
void onSystemEvent(int event, long requestId);
|
||||
|
||||
/**
|
||||
* Notifies when the dialog has finished animating.
|
||||
*/
|
||||
void onDialogAnimatedIn();
|
||||
void onDialogAnimatedIn(long requestId);
|
||||
}
|
||||
|
||||
@@ -48,11 +48,12 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.anyLong
|
||||
import org.mockito.Mockito.eq
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@RunWithLooper(setAsMainLooper = true)
|
||||
@@ -87,7 +88,7 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testNotifiesAnimatedIn() {
|
||||
initializeFingerprintContainer()
|
||||
verify(callback).onDialogAnimatedIn()
|
||||
verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -96,13 +97,13 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
container.dismissFromSystemServer()
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback, never()).onDialogAnimatedIn()
|
||||
verify(callback, never()).onDialogAnimatedIn(anyLong())
|
||||
|
||||
container.addToView()
|
||||
waitForIdleSync()
|
||||
|
||||
// attaching the view resets the state and allows this to happen again
|
||||
verify(callback).onDialogAnimatedIn()
|
||||
verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -110,14 +111,17 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
val container = initializeFingerprintContainer()
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDialogAnimatedIn()
|
||||
val requestID = authContainer?.requestId ?: 0L
|
||||
|
||||
verify(callback).onDialogAnimatedIn(requestID)
|
||||
|
||||
container.onWindowFocusChanged(false)
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
|
||||
eq<ByteArray?>(null) /* credentialAttestation */
|
||||
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
|
||||
eq<ByteArray?>(null), /* credentialAttestation */
|
||||
eq(requestID)
|
||||
)
|
||||
assertThat(container.parent).isNull()
|
||||
}
|
||||
@@ -131,8 +135,9 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
|
||||
eq<ByteArray?>(null) /* credentialAttestation */
|
||||
eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
|
||||
eq<ByteArray?>(null), /* credentialAttestation */
|
||||
eq(authContainer?.requestId ?: 0L)
|
||||
)
|
||||
assertThat(container.parent).isNull()
|
||||
}
|
||||
@@ -146,11 +151,13 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onSystemEvent(
|
||||
eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL)
|
||||
eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
|
||||
eq(authContainer?.requestId ?: 0L)
|
||||
)
|
||||
verify(callback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
|
||||
eq<ByteArray?>(null) /* credentialAttestation */
|
||||
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
|
||||
eq<ByteArray?>(null), /* credentialAttestation */
|
||||
eq(authContainer?.requestId ?: 0L)
|
||||
)
|
||||
assertThat(container.parent).isNull()
|
||||
}
|
||||
@@ -164,8 +171,9 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
|
||||
eq<ByteArray?>(null) /* credentialAttestation */
|
||||
eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
|
||||
eq<ByteArray?>(null), /* credentialAttestation */
|
||||
eq(authContainer?.requestId ?: 0L)
|
||||
)
|
||||
assertThat(container.parent).isNull()
|
||||
}
|
||||
@@ -180,7 +188,7 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
)
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onTryAgainPressed()
|
||||
verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -192,8 +200,9 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_ERROR),
|
||||
eq<ByteArray?>(null) /* credentialAttestation */
|
||||
eq(AuthDialogCallback.DISMISSED_ERROR),
|
||||
eq<ByteArray?>(null), /* credentialAttestation */
|
||||
eq(authContainer?.requestId ?: 0L)
|
||||
)
|
||||
assertThat(authContainer!!.parent).isNull()
|
||||
}
|
||||
@@ -209,7 +218,7 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
)
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onDeviceCredentialPressed()
|
||||
verify(callback).onDeviceCredentialPressed(authContainer?.requestId ?: 0L)
|
||||
assertThat(container.hasCredentialView()).isTrue()
|
||||
}
|
||||
|
||||
@@ -322,12 +331,12 @@ class AuthContainerViewTest : SysuiTestCase() {
|
||||
container.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, "failed")
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback, never()).onTryAgainPressed()
|
||||
verify(callback, never()).onTryAgainPressed(anyLong())
|
||||
|
||||
container.onPointerDown()
|
||||
waitForIdleSync()
|
||||
|
||||
verify(callback).onTryAgainPressed()
|
||||
verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
|
||||
}
|
||||
|
||||
private fun initializeFingerprintContainer(
|
||||
|
||||
@@ -291,7 +291,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception {
|
||||
showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -301,7 +302,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_NEGATIVE),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -311,7 +313,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -321,7 +324,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -331,7 +335,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonError_whenDismissedByError() throws Exception {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_ERROR),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -341,7 +346,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER,
|
||||
null /* credentialAttestation */);
|
||||
null, /* credentialAttestation */
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED),
|
||||
eq(null) /* credentialAttestation */);
|
||||
@@ -355,7 +361,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
final byte[] credentialAttestation = generateRandomHAT();
|
||||
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
|
||||
credentialAttestation);
|
||||
credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
|
||||
AdditionalMatchers.aryEq(credentialAttestation));
|
||||
@@ -531,7 +537,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
final byte[] credentialAttestation = generateRandomHAT();
|
||||
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
|
||||
credentialAttestation);
|
||||
credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
|
||||
verify(mReceiver).onDialogDismissed(
|
||||
eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
|
||||
AdditionalMatchers.aryEq(credentialAttestation));
|
||||
@@ -640,17 +646,19 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
final long requestID = mAuthController.mCurrentDialog.getRequestId();
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
|
||||
null /* credentialAttestation */);
|
||||
mAuthController.onTryAgainPressed();
|
||||
null, /* credentialAttestation */requestID);
|
||||
mAuthController.onTryAgainPressed(requestID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() {
|
||||
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
|
||||
final long requestID = mAuthController.mCurrentDialog.getRequestId();
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
|
||||
null /* credentialAttestation */);
|
||||
mAuthController.onDeviceCredentialPressed();
|
||||
null /* credentialAttestation */, requestID);
|
||||
mAuthController.onDeviceCredentialPressed(requestID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -708,7 +716,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
// WHEN dialog is shown and then dismissed
|
||||
showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
|
||||
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
|
||||
null /* credentialAttestation */);
|
||||
null /* credentialAttestation */,
|
||||
mAuthController.mCurrentDialog.getRequestId());
|
||||
|
||||
// THEN callback should be received
|
||||
verify(callback).onBiometricPromptDismissed();
|
||||
|
||||
Reference in New Issue
Block a user