Merge "Send "early canceled" to privileged clients" into rvc-dev
This commit is contained in:
@@ -204,4 +204,18 @@ public interface BiometricConstants {
|
||||
* @hide
|
||||
*/
|
||||
int BIOMETRIC_ACQUIRED_VENDOR_BASE = 1000;
|
||||
|
||||
//
|
||||
// Internal messages.
|
||||
//
|
||||
|
||||
/**
|
||||
* See {@link BiometricPrompt.Builder#setReceiveSystemEvents(boolean)}. This message is sent
|
||||
* immediately when the user cancels authentication for example by tapping the back button or
|
||||
* tapping the scrim. This is before {@link #BIOMETRIC_ERROR_USER_CANCELED}, which is sent when
|
||||
* dismissal animation completes.
|
||||
* @hide
|
||||
*/
|
||||
int BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL = 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String KEY_USE_DEFAULT_TITLE = "use_default_title";
|
||||
/**
|
||||
* @hide
|
||||
@@ -75,14 +76,17 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String KEY_DEVICE_CREDENTIAL_TITLE = "device_credential_title";
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String KEY_DEVICE_CREDENTIAL_SUBTITLE = "device_credential_subtitle";
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String KEY_DEVICE_CREDENTIAL_DESCRIPTION = "device_credential_description";
|
||||
/**
|
||||
* @hide
|
||||
@@ -106,7 +110,15 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
* If this is set, check the Device Policy Manager for allowed biometrics.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = "check_dpm";
|
||||
/**
|
||||
* Request to receive system events, such as back gesture/button. See
|
||||
* {@link AuthenticationCallback#onSystemEvent(int)}
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public static final String KEY_RECEIVE_SYSTEM_EVENTS = "receive_system_events";
|
||||
|
||||
/**
|
||||
* Error/help message will show for this amount of time.
|
||||
@@ -383,6 +395,18 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, receive internal events via {@link AuthenticationCallback#onSystemEvent(int)}
|
||||
* @param set
|
||||
* @return This builder.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setReceiveSystemEvents(boolean set) {
|
||||
mBundle.putBoolean(KEY_RECEIVE_SYSTEM_EVENTS, set);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BiometricPrompt}.
|
||||
*
|
||||
@@ -493,6 +517,13 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemEvent(int event) throws RemoteException {
|
||||
mExecutor.execute(() -> {
|
||||
mAuthenticationCallback.onSystemEvent(event);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private BiometricPrompt(Context context, Bundle bundle,
|
||||
@@ -732,6 +763,12 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
*/
|
||||
@Override
|
||||
public void onAuthenticationAcquired(int acquireInfo) {}
|
||||
|
||||
/**
|
||||
* Receiver for internal system events. See {@link Builder#setReceiveSystemEvents(boolean)}
|
||||
* @hide
|
||||
*/
|
||||
public void onSystemEvent(int event) {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,4 +30,6 @@ oneway interface IBiometricServiceReceiver {
|
||||
void onAcquired(int acquiredInfo, String message);
|
||||
// Notifies that the SystemUI dialog has been dismissed.
|
||||
void onDialogDismissed(int reason);
|
||||
// Notifies the client that an internal event, e.g. back button has occurred.
|
||||
void onSystemEvent(int event);
|
||||
}
|
||||
|
||||
@@ -42,4 +42,6 @@ oneway interface IBiometricServiceReceiverInternal {
|
||||
void onTryAgainPressed();
|
||||
// Notifies that the user has pressed the "use password" button on SystemUI
|
||||
void onDeviceCredentialPressed();
|
||||
// Notifies the client that an internal event, e.g. back button has occurred.
|
||||
void onSystemEvent(int event);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -207,6 +208,7 @@ public class AuthContainerView extends LinearLayout
|
||||
animateAway(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED);
|
||||
break;
|
||||
case AuthBiometricView.Callback.ACTION_USER_CANCELED:
|
||||
sendEarlyUserCanceled();
|
||||
animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
|
||||
break;
|
||||
case AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE:
|
||||
@@ -286,11 +288,13 @@ public class AuthContainerView extends LinearLayout
|
||||
|
||||
addView(mFrameLayout);
|
||||
|
||||
// TODO: De-dupe the logic with AuthCredentialPasswordView
|
||||
setOnKeyListener((v, keyCode, event) -> {
|
||||
if (keyCode != KeyEvent.KEYCODE_BACK) {
|
||||
return false;
|
||||
}
|
||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
sendEarlyUserCanceled();
|
||||
animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
|
||||
}
|
||||
return true;
|
||||
@@ -300,6 +304,11 @@ public class AuthContainerView extends LinearLayout
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
void sendEarlyUserCanceled() {
|
||||
mConfig.mCallback.onSystemEvent(
|
||||
BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowDeviceCredentials() {
|
||||
return Utils.isDeviceCredentialAllowed(mConfig.mBiometricPromptBundle);
|
||||
|
||||
@@ -164,6 +164,19 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemEvent(int event) {
|
||||
if (mReceiver == null) {
|
||||
Log.e(TAG, "onSystemEvent(" + event + "): Receiver is null");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mReceiver.onSystemEvent(event);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException when sending system event", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) {
|
||||
switch (reason) {
|
||||
|
||||
@@ -51,11 +51,13 @@ public class AuthCredentialPasswordView extends AuthCredentialView
|
||||
super.onFinishInflate();
|
||||
mPasswordField = findViewById(R.id.lockPassword);
|
||||
mPasswordField.setOnEditorActionListener(this);
|
||||
// TODO: De-dupe the logic with AuthContainerView
|
||||
mPasswordField.setOnKeyListener((v, keyCode, event) -> {
|
||||
if (keyCode != KeyEvent.KEYCODE_BACK) {
|
||||
return false;
|
||||
}
|
||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
mContainerView.sendEarlyUserCanceled();
|
||||
mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -58,4 +58,11 @@ public interface AuthDialogCallback {
|
||||
* Invoked when the "use password" button is clicked
|
||||
*/
|
||||
void onDeviceCredentialPressed();
|
||||
|
||||
/**
|
||||
* See {@link android.hardware.biometrics.BiometricPrompt.Builder
|
||||
* #setReceiveSystemEvents(boolean)}
|
||||
* @param event
|
||||
*/
|
||||
void onSystemEvent(int event);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -89,6 +90,8 @@ public class AuthContainerViewTest extends SysuiTestCase {
|
||||
|
||||
mAuthContainer.mBiometricCallback.onAction(
|
||||
AuthBiometricView.Callback.ACTION_USER_CANCELED);
|
||||
verify(mCallback).onSystemEvent(eq(
|
||||
BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL));
|
||||
verify(mCallback).onDismissed(
|
||||
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
|
||||
eq(null) /* credentialAttestation */);
|
||||
|
||||
@@ -158,7 +158,8 @@ public class AuthService extends SystemService {
|
||||
|| bundle.getCharSequence(
|
||||
BiometricPrompt.KEY_DEVICE_CREDENTIAL_SUBTITLE) != null
|
||||
|| bundle.getCharSequence(
|
||||
BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION) != null) {
|
||||
BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION) != null
|
||||
|| bundle.getBoolean(BiometricPrompt.KEY_RECEIVE_SYSTEM_EVENTS, false)) {
|
||||
checkInternalPermission();
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ public class BiometricService extends SystemService {
|
||||
private static final int MSG_CANCEL_AUTHENTICATION = 10;
|
||||
private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11;
|
||||
private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12;
|
||||
private static final int MSG_ON_SYSTEM_EVENT = 13;
|
||||
|
||||
/**
|
||||
* Authentication either just called and we have not transitioned to the CALLED state, or
|
||||
@@ -360,6 +361,11 @@ public class BiometricService extends SystemService {
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ON_SYSTEM_EVENT: {
|
||||
handleOnSystemEvent((int) msg.obj);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Slog.e(TAG, "Unknown message: " + msg);
|
||||
break;
|
||||
@@ -632,6 +638,11 @@ public class BiometricService extends SystemService {
|
||||
public void onDeviceCredentialPressed() {
|
||||
mHandler.sendEmptyMessage(MSG_ON_DEVICE_CREDENTIAL_PRESSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemEvent(int event) {
|
||||
mHandler.obtainMessage(MSG_ON_SYSTEM_EVENT, event).sendToTarget();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1579,6 +1590,27 @@ public class BiometricService extends SystemService {
|
||||
mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
|
||||
}
|
||||
|
||||
private void handleOnSystemEvent(int event) {
|
||||
final boolean shouldReceive = mCurrentAuthSession.mBundle
|
||||
.getBoolean(BiometricPrompt.KEY_RECEIVE_SYSTEM_EVENTS, false);
|
||||
Slog.d(TAG, "onSystemEvent: " + event + ", shouldReceive: " + shouldReceive);
|
||||
|
||||
if (mCurrentAuthSession == null) {
|
||||
Slog.e(TAG, "Auth session null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shouldReceive) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mCurrentAuthSession.mClientReceiver.onSystemEvent(event);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "RemoteException", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when each service has notified that its client is ready to be started. When
|
||||
* all biometrics are ready, this invokes the SystemUI dialog through StatusBar.
|
||||
|
||||
Reference in New Issue
Block a user