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
This commit is contained in:
@@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricPrompt;
|
||||
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 @@ public abstract class AuthBiometricView extends LinearLayout {
|
||||
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 @@ public abstract class AuthBiometricView extends LinearLayout {
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
public void setEffectiveUserId(int effectiveUserId) {
|
||||
mEffectiveUserId = effectiveUserId;
|
||||
}
|
||||
|
||||
public void setRequireConfirmation(boolean requireConfirmation) {
|
||||
mRequireConfirmation = requireConfirmation;
|
||||
}
|
||||
@@ -650,8 +656,9 @@ public abstract class AuthBiometricView extends LinearLayout {
|
||||
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;
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.Bundle;
|
||||
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 @@ public class AuthContainerView extends LinearLayout
|
||||
@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 @@ public class AuthContainerView extends LinearLayout
|
||||
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 @@ public class AuthContainerView extends LinearLayout
|
||||
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 @@ public class AuthContainerView extends LinearLayout
|
||||
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 @@ public class AuthContainerView extends LinearLayout
|
||||
mBiometricView.setCallback(mBiometricCallback);
|
||||
mBiometricView.setBackgroundView(mBackgroundView);
|
||||
mBiometricView.setUserId(mConfig.mUserId);
|
||||
mBiometricView.setEffectiveUserId(mEffectiveUserId);
|
||||
mBiometricScrollView.addView(mBiometricView);
|
||||
}
|
||||
|
||||
@@ -318,7 +331,10 @@ public class AuthContainerView extends LinearLayout
|
||||
*/
|
||||
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 @@ public class AuthContainerView extends LinearLayout
|
||||
}
|
||||
|
||||
mCredentialView.setContainerView(this);
|
||||
mCredentialView.setUser(mConfig.mUserId);
|
||||
mCredentialView.setEffectiveUserId(mEffectiveUserId);
|
||||
mCredentialView.setCredentialType(credentialType);
|
||||
mCredentialView.setCallback(mCredentialCallback);
|
||||
mCredentialView.setBiometricPromptBundle(mConfig.mBiometricPromptBundle);
|
||||
mCredentialView.setPanelController(mPanelController, animatePanel);
|
||||
|
||||
@@ -96,7 +96,7 @@ public class AuthCredentialPasswordView extends AuthCredentialView
|
||||
}
|
||||
|
||||
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 @@ public class AuthCredentialPasswordView extends AuthCredentialView
|
||||
}
|
||||
|
||||
mPendingLockCheck = LockPatternChecker.checkCredential(mLockPatternUtils,
|
||||
password, mUserId, this::onCredentialChecked);
|
||||
password, mEffectiveUserId, this::onCredentialChecked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class AuthCredentialPatternView extends AuthCredentialView {
|
||||
mPendingLockCheck = LockPatternChecker.checkCredential(
|
||||
mLockPatternUtils,
|
||||
credential,
|
||||
mUserId,
|
||||
mEffectiveUserId,
|
||||
this::onPatternChecked);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,8 @@ public class AuthCredentialPatternView extends AuthCredentialView {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class AuthCredentialView extends LinearLayout {
|
||||
protected AuthContainerView mContainerView;
|
||||
protected Callback mCallback;
|
||||
protected AsyncTask<?, ?, ?> mPendingLockCheck;
|
||||
protected int mUserId;
|
||||
protected int mEffectiveUserId;
|
||||
protected ErrorTimer mErrorTimer;
|
||||
|
||||
interface Callback {
|
||||
@@ -137,8 +137,12 @@ public abstract class AuthCredentialView extends LinearLayout {
|
||||
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 @@ public abstract class AuthCredentialView extends LinearLayout {
|
||||
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 @@ public abstract class AuthCredentialView extends LinearLayout {
|
||||
} 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,
|
||||
|
||||
@@ -18,19 +18,25 @@ package com.android.systemui.biometrics;
|
||||
|
||||
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 @@ public class AuthContainerViewTest extends SysuiTestCase {
|
||||
private TestableAuthContainer mAuthContainer;
|
||||
|
||||
private @Mock AuthDialogCallback mCallback;
|
||||
private @Mock UserManager mUserManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -156,6 +163,18 @@ public class AuthContainerViewTest extends SysuiTestCase {
|
||||
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 class AuthContainerViewTest extends SysuiTestCase {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user