Use effectiveUserId for credentials
Credential-related stuff should use effectiveUserId instead of userId.
Otherwise, authenticating for work profile will not work when one-lock
is enabled.
Fixes: 147653255
Test: Comment1 and Comment2 in the bug linked above
Test: atest com.android.systemui.biometrics
Change-Id: Icd9ad3fc69695cec509e3532b2b54d93833b94b5
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 84a592d..7b4816f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -28,6 +28,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -162,6 +163,7 @@
private Bundle mBiometricPromptBundle;
private boolean mRequireConfirmation;
private int mUserId;
+ private int mEffectiveUserId;
@AuthDialog.DialogSize int mSize = AuthDialog.SIZE_UNKNOWN;
private TextView mTitleView;
@@ -280,6 +282,10 @@
mUserId = userId;
}
+ public void setEffectiveUserId(int effectiveUserId) {
+ mEffectiveUserId = effectiveUserId;
+ }
+
public void setRequireConfirmation(boolean requireConfirmation) {
mRequireConfirmation = requireConfirmation;
}
@@ -650,8 +656,9 @@
if (isDeviceCredentialAllowed()) {
final @Utils.CredentialType int credentialType =
- Utils.getCredentialType(mContext, mUserId);
- switch(credentialType) {
+ Utils.getCredentialType(mContext, mEffectiveUserId);
+
+ switch (credentialType) {
case Utils.CREDENTIAL_PIN:
negativeText = getResources().getString(R.string.biometric_dialog_use_pin);
break;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 36c89fd..4312a52 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -30,6 +30,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.UserManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -75,6 +76,7 @@
@interface ContainerState {}
final Config mConfig;
+ final int mEffectiveUserId;
private final Handler mHandler;
private final Injector mInjector;
private final IBinder mWindowToken = new Binder();
@@ -182,6 +184,14 @@
int getAnimateCredentialStartDelayMs() {
return AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS;
}
+
+ UserManager getUserManager(Context context) {
+ return UserManager.get(context);
+ }
+
+ int getCredentialType(Context context, int effectiveUserId) {
+ return Utils.getCredentialType(context, effectiveUserId);
+ }
}
@VisibleForTesting
@@ -230,6 +240,9 @@
mConfig = config;
mInjector = injector;
+ mEffectiveUserId = mInjector.getUserManager(mContext)
+ .getCredentialOwnerProfile(mConfig.mUserId);
+
mHandler = new Handler(Looper.getMainLooper());
mWindowManager = mContext.getSystemService(WindowManager.class);
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
@@ -268,7 +281,6 @@
mBiometricScrollView = mInjector.getBiometricScrollView(mFrameLayout);
mBackgroundView = mInjector.getBackgroundView(mFrameLayout);
-
if (isManagedProfile) {
final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
mContext.getTheme());
@@ -307,6 +319,7 @@
mBiometricView.setCallback(mBiometricCallback);
mBiometricView.setBackgroundView(mBackgroundView);
mBiometricView.setUserId(mConfig.mUserId);
+ mBiometricView.setEffectiveUserId(mEffectiveUserId);
mBiometricScrollView.addView(mBiometricView);
}
@@ -318,7 +331,10 @@
*/
private void addCredentialView(boolean animatePanel, boolean animateContents) {
final LayoutInflater factory = LayoutInflater.from(mContext);
- final int credentialType = Utils.getCredentialType(mContext, mConfig.mUserId);
+
+ final @Utils.CredentialType int credentialType = mInjector.getCredentialType(
+ mContext, mEffectiveUserId);
+
switch (credentialType) {
case Utils.CREDENTIAL_PATTERN:
mCredentialView = (AuthCredentialView) factory.inflate(
@@ -334,7 +350,8 @@
}
mCredentialView.setContainerView(this);
- mCredentialView.setUser(mConfig.mUserId);
+ mCredentialView.setEffectiveUserId(mEffectiveUserId);
+ mCredentialView.setCredentialType(credentialType);
mCredentialView.setCallback(mCredentialCallback);
mCredentialView.setBiometricPromptBundle(mConfig.mBiometricPromptBundle);
mCredentialView.setPanelController(mPanelController, animatePanel);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
index bebaa4b..ccfd3a5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
@@ -96,7 +96,7 @@
}
private void checkPasswordAndUnlock() {
- try (LockscreenCredential password = mCredentialType == Utils.CREDENTIAL_PIN
+ try (LockscreenCredential password = mCredentialType == Utils.CREDENTIAL_PIN
? LockscreenCredential.createPinOrNone(mPasswordField.getText())
: LockscreenCredential.createPasswordOrNone(mPasswordField.getText())) {
if (password.isNone()) {
@@ -104,7 +104,7 @@
}
mPendingLockCheck = LockPatternChecker.checkCredential(mLockPatternUtils,
- password, mUserId, this::onCredentialChecked);
+ password, mEffectiveUserId, this::onCredentialChecked);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
index 14414a4..1cb532b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
@@ -69,7 +69,7 @@
mPendingLockCheck = LockPatternChecker.checkCredential(
mLockPatternUtils,
credential,
- mUserId,
+ mEffectiveUserId,
this::onPatternChecked);
}
}
@@ -99,7 +99,8 @@
super.onFinishInflate();
mLockPatternView = findViewById(R.id.lockPattern);
mLockPatternView.setOnPatternListener(new UnlockPatternListener());
- mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(mUserId));
+ mLockPatternView.setInStealthMode(
+ !mLockPatternUtils.isVisiblePatternEnabled(mEffectiveUserId));
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
index 8c8611e..8f2cf70 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -63,7 +63,7 @@
protected AuthContainerView mContainerView;
protected Callback mCallback;
protected AsyncTask<?, ?, ?> mPendingLockCheck;
- protected int mUserId;
+ protected int mEffectiveUserId;
protected ErrorTimer mErrorTimer;
interface Callback {
@@ -137,8 +137,12 @@
view.setText(string);
}
- void setUser(int user) {
- mUserId = user;
+ void setEffectiveUserId(int effectiveUserId) {
+ mEffectiveUserId = effectiveUserId;
+ }
+
+ void setCredentialType(@Utils.CredentialType int credentialType) {
+ mCredentialType = credentialType;
}
void setCallback(Callback callback) {
@@ -166,8 +170,6 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- mCredentialType = Utils.getCredentialType(mContext, mUserId);
-
setText(mTitleView, mBiometricPromptBundle.getString(BiometricPrompt.KEY_TITLE));
setTextOrHide(mSubtitleView,
mBiometricPromptBundle.getString(BiometricPrompt.KEY_SUBTITLE));
@@ -230,7 +232,8 @@
} else {
if (timeoutMs > 0) {
mHandler.removeCallbacks(mClearErrorRunnable);
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline(mUserId, timeoutMs);
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ mEffectiveUserId, timeoutMs);
mErrorTimer = new ErrorTimer(mContext,
deadline - SystemClock.elapsedRealtime(),
LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index 162b16e..25bcb54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -18,19 +18,25 @@
import static android.hardware.biometrics.BiometricManager.Authenticators;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Bundle;
+import android.os.UserManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -57,6 +63,7 @@
private TestableAuthContainer mAuthContainer;
private @Mock AuthDialogCallback mCallback;
+ private @Mock UserManager mUserManager;
@Before
public void setup() {
@@ -156,6 +163,18 @@
verify(mAuthContainer.mFrameLayout).addView(mAuthContainer.mCredentialView);
}
+ @Test
+ public void testCredentialViewUsesEffectiveUserId() {
+ final int dummyEffectiveUserId = 200;
+ when(mUserManager.getCredentialOwnerProfile(anyInt())).thenReturn(dummyEffectiveUserId);
+
+ initializeContainer(Authenticators.DEVICE_CREDENTIAL);
+ mAuthContainer.onAttachedToWindowInternal();
+ assertTrue(mAuthContainer.mCredentialView instanceof AuthCredentialPatternView);
+ assertEquals(dummyEffectiveUserId, mAuthContainer.mCredentialView.mEffectiveUserId);
+ assertEquals(Utils.CREDENTIAL_PATTERN, mAuthContainer.mCredentialView.mCredentialType);
+ }
+
private void initializeContainer(int authenticators) {
AuthContainerView.Config config = new AuthContainerView.Config();
config.mContext = mContext;
@@ -211,5 +230,15 @@
public int getAnimateCredentialStartDelayMs() {
return 0;
}
+
+ @Override
+ public UserManager getUserManager(Context context) {
+ return mUserManager;
+ }
+
+ @Override
+ public @Utils.CredentialType int getCredentialType(Context context, int effectiveUserId) {
+ return Utils.CREDENTIAL_PATTERN;
+ }
}
}