diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 38f5f3279c8e3..8c5fdf5822e84 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -137,7 +137,7 @@ oneway interface IStatusBar // Used to show the authentication dialog (Biometrics, Device Credential) void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId); + long operationId, int sysUiSessionId); // Used to notify the authentication dialog that a biometric has been authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 24fe0638b0910..c32082418bc59 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -106,7 +106,7 @@ interface IStatusBarService // Used to show the authentication dialog (Biometrics, Device Credential) void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId); + long operationId, int sysUiSessionId); // Used to notify the authentication dialog that a biometric has been authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java index 7dea7f83f0c6f..7c25d28117939 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java @@ -432,7 +432,7 @@ public abstract class AuthBiometricView extends LinearLayout { Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this); } - public void updateState(@BiometricState int newState) { + void updateState(@BiometricState int newState) { Log.v(TAG, "newState: " + newState); switch (newState) { @@ -453,8 +453,10 @@ public abstract class AuthBiometricView extends LinearLayout { } announceForAccessibility(getResources() .getString(R.string.biometric_dialog_authenticated)); - mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED), - getDelayAfterAuthenticatedDurationMs()); + mHandler.postDelayed(() -> { + Log.d(TAG, "Sending ACTION_AUTHENTICATED"); + mCallback.onAction(Callback.ACTION_AUTHENTICATED); + }, getDelayAfterAuthenticatedDurationMs()); break; case STATE_PENDING_CONFIRMATION: diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index b736b4df8abf3..86087668604e9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -113,6 +113,7 @@ public class AuthContainerView extends LinearLayout int mModalityMask; boolean mSkipIntro; long mOperationId; + int mSysUiSessionId; } public static class Builder { @@ -158,6 +159,11 @@ public class AuthContainerView extends LinearLayout return this; } + public Builder setSysUiSessionId(int sysUiSessionId) { + mConfig.mSysUiSessionId = sysUiSessionId; + return this; + } + public AuthContainerView build(int modalityMask) { mConfig.mModalityMask = modalityMask; return new AuthContainerView(mConfig, new Injector()); @@ -203,6 +209,9 @@ public class AuthContainerView extends LinearLayout final class BiometricCallback implements AuthBiometricView.Callback { @Override public void onAction(int action) { + Log.d(TAG, "onAction: " + action + + ", sysUiSessionId: " + mConfig.mSysUiSessionId + + ", state: " + mContainerState); switch (action) { case AuthBiometricView.Callback.ACTION_AUTHENTICATED: animateAway(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED); @@ -461,13 +470,13 @@ public class AuthContainerView extends LinearLayout if (animate) { animateAway(false /* sendReason */, 0 /* reason */); } else { - removeWindowIfAttached(); + removeWindowIfAttached(false /* sendReason */); } } @Override public void dismissFromSystemServer() { - removeWindowIfAttached(); + removeWindowIfAttached(true /* sendReason */); } @Override @@ -540,7 +549,7 @@ public class AuthContainerView extends LinearLayout final Runnable endActionRunnable = () -> { setVisibility(View.INVISIBLE); - removeWindowIfAttached(); + removeWindowIfAttached(true /* sendReason */); }; postOnAnimation(() -> { @@ -575,19 +584,24 @@ public class AuthContainerView extends LinearLayout } private void sendPendingCallbackIfNotNull() { - Log.d(TAG, "pendingCallback: " + mPendingCallbackReason); + Log.d(TAG, "pendingCallback: " + mPendingCallbackReason + + " sysUISessionId: " + mConfig.mSysUiSessionId); if (mPendingCallbackReason != null) { mConfig.mCallback.onDismissed(mPendingCallbackReason, mCredentialAttestation); mPendingCallbackReason = null; } } - private void removeWindowIfAttached() { - sendPendingCallbackIfNotNull(); + private void removeWindowIfAttached(boolean sendReason) { + if (sendReason) { + sendPendingCallbackIfNotNull(); + } if (mContainerState == STATE_GONE) { + Log.w(TAG, "Container already STATE_GONE, mSysUiSessionId: " + mConfig.mSysUiSessionId); return; } + Log.d(TAG, "Removing container, mSysUiSessionId: " + mConfig.mSysUiSessionId); mContainerState = STATE_GONE; mWindowManager.removeView(this); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 0c6794c2ab858..9f0ea3ee46ff7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -276,14 +276,15 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, @Override public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId) { + long operationId, int sysUiSessionId) { final int authenticators = Utils.getAuthenticators(bundle); if (DEBUG) { Log.d(TAG, "showAuthenticationDialog, authenticators: " + authenticators + ", biometricModality: " + biometricModality + ", requireConfirmation: " + requireConfirmation - + ", operationId: " + operationId); + + ", operationId: " + operationId + + ", sysUiSessionId: " + sysUiSessionId); } SomeArgs args = SomeArgs.obtain(); args.arg1 = bundle; @@ -293,6 +294,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, args.argi2 = userId; args.arg4 = opPackageName; args.arg5 = operationId; + args.argi3 = sysUiSessionId; boolean skipAnimation = false; if (mCurrentDialog != null) { @@ -382,6 +384,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, final int userId = args.argi2; final String opPackageName = (String) args.arg4; final long operationId = (long) args.arg5; + final int sysUiSessionId = args.argi3; // Create a new dialog but do not replace the current one yet. final AuthDialog newDialog = buildDialog( @@ -391,7 +394,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, type, opPackageName, skipAnimation, - operationId); + operationId, + sysUiSessionId); if (newDialog == null) { Log.e(TAG, "Unsupported type: " + type); @@ -403,7 +407,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, + " savedState: " + savedState + " mCurrentDialog: " + mCurrentDialog + " newDialog: " + newDialog - + " type: " + type); + + " type: " + type + + " sysUiSessionId: " + sysUiSessionId); } if (mCurrentDialog != null) { @@ -458,7 +463,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } protected AuthDialog buildDialog(Bundle biometricPromptBundle, boolean requireConfirmation, - int userId, int type, String opPackageName, boolean skipIntro, long operationId) { + int userId, int type, String opPackageName, boolean skipIntro, long operationId, + int sysUiSessionId) { return new AuthContainerView.Builder(mContext) .setCallback(this) .setBiometricPromptBundle(biometricPromptBundle) @@ -467,6 +473,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, .setOpPackageName(opPackageName) .setSkipIntro(skipIntro) .setOperationId(operationId) + .setSysUiSessionId(sysUiSessionId) .build(type); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 24195156d8cf6..96d6ecbcc07fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -263,7 +263,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< default void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId) { } + long operationId, int sysUiSessionId) { } default void onBiometricAuthenticated() { } default void onBiometricHelp(String message) { } default void onBiometricError(int modality, int error, int vendorCode) { } @@ -782,7 +782,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< @Override public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId) { + long operationId, int sysUiSessionId) { synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.arg1 = bundle; @@ -792,6 +792,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< args.argi2 = userId; args.arg4 = opPackageName; args.arg5 = operationId; + args.argi3 = sysUiSessionId; mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args) .sendToTarget(); } @@ -1169,7 +1170,8 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< (boolean) someArgs.arg3 /* requireConfirmation */, someArgs.argi2 /* userId */, (String) someArgs.arg4 /* opPackageName */, - (long) someArgs.arg5 /* operationId */); + (long) someArgs.arg5 /* operationId */, + someArgs.argi3 /* sysUiSessionId */); } someArgs.recycle(); break; diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index fc1ddf74a448c..821b8504e5f74 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -470,7 +470,8 @@ public class AuthControllerTest extends SysuiTestCase { true /* requireConfirmation */, 0 /* userId */, "testPackage", - 0 /* operationId */); + 0 /* operationId */, + 0 /* sysUiSessionId */); } private Bundle createTestDialogBundle(int authenticators) { @@ -508,7 +509,7 @@ public class AuthControllerTest extends SysuiTestCase { @Override protected AuthDialog buildDialog(Bundle biometricPromptBundle, boolean requireConfirmation, int userId, int type, String opPackageName, - boolean skipIntro, long operationId) { + boolean skipIntro, long operationId, int sysUiSessionId) { mLastBiometricPromptBundle = biometricPromptBundle; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index cffcabb55e144..63e6e8cba628b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -410,11 +410,12 @@ public class CommandQueueTest extends SysuiTestCase { Bundle bundle = new Bundle(); String packageName = "test"; final long operationId = 1; + final int sysUiSessionId = 2; mCommandQueue.showAuthenticationDialog(bundle, null /* receiver */, 1, true, 3, - packageName, operationId); + packageName, operationId, sysUiSessionId); waitForIdleSync(); verify(mCallbacks).showAuthenticationDialog(eq(bundle), eq(null), eq(1), eq(true), eq(3), - eq(packageName), eq(operationId)); + eq(packageName), eq(operationId), eq(sysUiSessionId)); } @Test diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 70fbca5b47986..7e28e94a17bba 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -170,6 +170,8 @@ public class BiometricService extends SystemService { final String mOpPackageName; // Info to be shown on BiometricDialog when all cookies are returned. final Bundle mBundle; + // Random id associated to this AuthSession + final int mSysUiSessionId; final int mCallingUid; final int mCallingPid; final int mCallingUserId; @@ -203,11 +205,13 @@ public class BiometricService extends SystemService { mClientReceiver = receiver; mOpPackageName = opPackageName; mBundle = bundle; + mSysUiSessionId = mRandom.nextInt(); mCallingUid = callingUid; mCallingPid = callingPid; mCallingUserId = callingUserId; mModality = modality; mRequireConfirmation = requireConfirmation; + Slog.d(TAG, "New AuthSession, mSysUiSessionId: " + mSysUiSessionId); } boolean isCrypto() { @@ -1457,7 +1461,8 @@ public class BiometricService extends SystemService { false /* requireConfirmation */, mCurrentAuthSession.mUserId, mCurrentAuthSession.mOpPackageName, - mCurrentAuthSession.mSessionId); + mCurrentAuthSession.mSessionId, + mCurrentAuthSession.mSysUiSessionId); } else { mPendingAuthSession.mClientReceiver.onError(modality, error, vendorCode); mPendingAuthSession = null; @@ -1680,7 +1685,8 @@ public class BiometricService extends SystemService { mStatusBarService.showAuthenticationDialog(mCurrentAuthSession.mBundle, mInternalReceiver, modality, requireConfirmation, userId, mCurrentAuthSession.mOpPackageName, - mCurrentAuthSession.mSessionId); + mCurrentAuthSession.mSessionId, + mCurrentAuthSession.mSysUiSessionId); } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); } @@ -1766,7 +1772,8 @@ public class BiometricService extends SystemService { false /* requireConfirmation */, mCurrentAuthSession.mUserId, mCurrentAuthSession.mOpPackageName, - sessionId); + sessionId, + mCurrentAuthSession.mSysUiSessionId); } else { mPendingAuthSession.mState = STATE_AUTH_CALLED; for (AuthenticatorWrapper authenticator : mAuthenticators) { diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 289bf66e1add1..4ba58bd259fcd 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -665,12 +665,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId) { + long operationId, int sysUiSessionId) { enforceBiometricDialog(); if (mBar != null) { try { mBar.showAuthenticationDialog(bundle, receiver, biometricModality, - requireConfirmation, userId, opPackageName, operationId); + requireConfirmation, userId, opPackageName, operationId, sysUiSessionId); } catch (RemoteException ex) { } } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index d2925263125d5..285caf34ae67f 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -186,7 +186,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test @@ -269,7 +270,8 @@ public class BiometricServiceTest { eq(false) /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test @@ -407,7 +409,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); // Hardware authenticated final byte[] HAT = generateRandomHAT(); @@ -462,7 +465,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test @@ -610,7 +614,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, anyString(), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test @@ -711,7 +716,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test @@ -1207,7 +1213,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); // Requesting strong and credential, when credential is setup resetReceiver(); @@ -1227,7 +1234,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); // Un-downgrading the authenticator allows successful strong auth for (BiometricService.AuthenticatorWrapper wrapper : mBiometricService.mAuthenticators) { @@ -1250,7 +1258,8 @@ public class BiometricServiceTest { anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), - anyLong() /* sessionId */); + anyLong() /* sessionId */, + anyInt() /* sysUiSessionId */); } @Test(expected = IllegalStateException.class)