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:
Kevin Chyn
2020-01-17 16:07:00 -08:00
parent a847a03c7d
commit b54bdfc172
6 changed files with 72 additions and 15 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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,

View File

@@ -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;
}
}
}