Fix ConfirmDeviceCredentials for work profiles
1) Fixed the theme for CDCA$InternalActivity to be transparent
2) CDCA only cares about biometrics, which are tied to userId
3) Moved shared methods to a util class
Fixes: 119296586
Test: Followed the steps in comment#1 of the bug linked above
Change-Id: Ie47fc7c3a53dfb7780087937e1ca83287cc52d71
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index eb3be0e..6ffc3b2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1463,7 +1463,7 @@
android:exported="false"
android:permission="android.permission.MANAGE_USERS"
android:resizeableActivity="false"
- android:theme="@android:style/Theme.NoDisplay">
+ android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter android:priority="1">
<action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index 6e1ae10..3a12bac 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -50,6 +50,9 @@
private Executor mClientExecutor;
private AuthenticationCallback mClientCallback;
+ // Re-settable by the application.
+ private int mUserId;
+
// Created/Initialized once and retained
private final Handler mHandler = new Handler(Looper.getMainLooper());
private PromptInfo mPromptInfo;
@@ -96,6 +99,10 @@
mClientCallback = callback;
}
+ public void setUser(int userId) {
+ mUserId = userId;
+ }
+
public void cancel() {
if (mCancellationSignal != null) {
mCancellationSignal.cancel();
@@ -126,8 +133,8 @@
mCancellationSignal = new CancellationSignal();
// TODO: CC doesn't use crypto for now
- mBiometricPrompt.authenticate(mCancellationSignal, mClientExecutor,
- mAuthenticationCallback);
+ mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
+ mAuthenticationCallback, mUserId);
}
@Override
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index f68c04a..5eb1f32 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -20,9 +20,9 @@
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
+import android.app.trust.TrustManager;
import android.content.Context;
import android.content.Intent;
-import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
@@ -84,13 +84,13 @@
private DevicePolicyManager mDevicePolicyManager;
private LockPatternUtils mLockPatternUtils;
private UserManager mUserManager;
+ private TrustManager mTrustManager;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private Handler mHandler = new Handler(Looper.getMainLooper());
private String mTitle;
private String mDetails;
private int mUserId;
- private int mEffectiveUserId;
private int mCredentialMode;
private boolean mGoingToBackground;
@@ -108,10 +108,16 @@
showConfirmCredentials();
}
}
-
}
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
+ mTrustManager.setDeviceLockedForUser(mUserId, false);
+
+ ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils, mUserManager,
+ mUserId);
+ ConfirmDeviceCredentialUtils.checkForPendingIntent(
+ ConfirmDeviceCredentialActivity.this);
+
setResult(Activity.RESULT_OK);
finish();
}
@@ -124,6 +130,7 @@
mBiometricManager = getSystemService(BiometricManager.class);
mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
mUserManager = UserManager.get(this);
+ mTrustManager = getSystemService(TrustManager.class);
mLockPatternUtils = new LockPatternUtils(this);
Intent intent = getIntent();
@@ -134,7 +141,7 @@
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
mUserId = UserHandle.myUserId();
- mEffectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
+ final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
if (isInternalActivity()) {
try {
mUserId = Utils.getUserIdFromBundle(this, intent.getExtras());
@@ -162,21 +169,23 @@
} else if (isManagedProfile && isInternalActivity()
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
mCredentialMode = CREDENTIAL_MANAGED;
- if (isBiometricAllowed()) {
+ if (isBiometricAllowed(effectiveUserId)) {
showBiometricPrompt();
launchedBiometric = true;
} else {
showConfirmCredentials();
+ launchedCDC = true;
}
} else {
mCredentialMode = CREDENTIAL_NORMAL;
- if (isBiometricAllowed()) {
+ if (isBiometricAllowed(effectiveUserId)) {
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
// onAuthenticationError and do the right thing automatically.
showBiometricPrompt();
launchedBiometric = true;
} else {
showConfirmCredentials();
+ launchedCDC = true;
}
}
@@ -217,19 +226,20 @@
// credential. Otherwise, biometric can't unlock fbe/keystore through
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
// biometric is disabled due to device restart.
- private boolean isStrongAuthRequired() {
- return !mLockPatternUtils.isBiometricAllowedForUser(mEffectiveUserId)
+ private boolean isStrongAuthRequired(int effectiveUserId) {
+ return !mLockPatternUtils.isBiometricAllowedForUser(effectiveUserId)
|| !mUserManager.isUserUnlocked(mUserId);
}
- private boolean isBiometricDisabledByAdmin() {
+ private boolean isBiometricDisabledByAdmin(int effectiveUserId) {
final int disabledFeatures =
- mDevicePolicyManager.getKeyguardDisabledFeatures(null, mEffectiveUserId);
+ mDevicePolicyManager.getKeyguardDisabledFeatures(null, effectiveUserId);
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS) != 0;
}
- private boolean isBiometricAllowed() {
- return !isStrongAuthRequired() && !isBiometricDisabledByAdmin();
+ private boolean isBiometricAllowed(int effectiveUserId) {
+ return !isStrongAuthRequired(effectiveUserId)
+ && !isBiometricDisabledByAdmin(effectiveUserId);
}
private void showBiometricPrompt() {
@@ -250,6 +260,7 @@
newFragment = true;
}
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
+ mBiometricFragment.setUser(mUserId);
if (newFragment) {
getSupportFragmentManager().beginTransaction()
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
index 9b677aa..2de7625 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
@@ -18,17 +18,12 @@
package com.android.settings.password;
import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
import android.app.Dialog;
-import android.app.IActivityManager;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
-import android.app.trust.TrustManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentSender;
import android.content.pm.UserInfo;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -36,7 +31,6 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.UserManager;
import android.text.TextUtils;
import android.view.View;
@@ -199,29 +193,6 @@
public void startEnterAnimation() {
}
- protected void checkForPendingIntent() {
- int taskId = getActivity().getIntent().getIntExtra(Intent.EXTRA_TASK_ID, -1);
- if (taskId != -1) {
- try {
- IActivityManager activityManager = ActivityManager.getService();
- final ActivityOptions options = ActivityOptions.makeBasic();
- activityManager.startActivityFromRecents(taskId, options.toBundle());
- return;
- } catch (RemoteException e) {
- // Do nothing.
- }
- }
- IntentSender intentSender = getActivity().getIntent()
- .getParcelableExtra(Intent.EXTRA_INTENT);
- if (intentSender != null) {
- try {
- getActivity().startIntentSenderForResult(intentSender, -1, null, 0, 0, 0);
- } catch (IntentSender.SendIntentException e) {
- /* ignore */
- }
- }
- }
-
private void setWorkChallengeBackground(View baseView, int userId) {
View mainContent = getActivity().findViewById(com.android.settings.R.id.main_content);
if (mainContent != null) {
@@ -246,15 +217,6 @@
}
}
- protected void reportSuccessfulAttempt() {
- mLockPatternUtils.reportSuccessfulPasswordAttempt(mEffectiveUserId);
- if (mUserManager.isManagedProfile(mEffectiveUserId)) {
- // Keyguard is responsible to disable StrongAuth for primary user. Disable StrongAuth
- // for work challenge only here.
- mLockPatternUtils.userPresent(mEffectiveUserId);
- }
- }
-
protected void reportFailedAttempt() {
updateErrorMessage(
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java b/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java
new file mode 100644
index 0000000..11d6924
--- /dev/null
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.password;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.IActivityManager;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.RemoteException;
+import android.os.UserManager;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/** Class containing methods shared between CDCA and CDCBA */
+public class ConfirmDeviceCredentialUtils {
+
+ public static void checkForPendingIntent(Activity activity) {
+ // See Change-Id I52c203735fa9b53fd2f7df971824747eeb930f36 for context
+ int taskId = activity.getIntent().getIntExtra(Intent.EXTRA_TASK_ID, -1);
+ if (taskId != -1) {
+ try {
+ IActivityManager activityManager = ActivityManager.getService();
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ activityManager.startActivityFromRecents(taskId, options.toBundle());
+ return;
+ } catch (RemoteException e) {
+ // Do nothing.
+ }
+ }
+ IntentSender intentSender = activity.getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
+ if (intentSender != null) {
+ try {
+ activity.startIntentSenderForResult(intentSender, -1, null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ /* ignore */
+ }
+ }
+ }
+
+ public static void reportSuccessfulAttempt(LockPatternUtils utils, UserManager userManager,
+ int userId) {
+ utils.reportSuccessfulPasswordAttempt(userId);
+ if (userManager.isManagedProfile(userId)) {
+ // Keyguard is responsible to disable StrongAuth for primary user. Disable StrongAuth
+ // for work challenge only here.
+ utils.userPresent(userId);
+ }
+ }
+}
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index d380fc9..45b8129 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -434,10 +434,11 @@
mPasswordEntryInputDisabler.setInputEnabled(true);
if (matched) {
if (newResult) {
- reportSuccessfulAttempt();
+ ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
+ mUserManager, mEffectiveUserId);
}
startDisappearAnimation(intent);
- checkForPendingIntent();
+ ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
} else {
if (timeoutMs > 0) {
refreshLockScreen();
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index 95a0aca..83141ea 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -487,10 +487,11 @@
mLockPatternView.setEnabled(true);
if (matched) {
if (newResult) {
- reportSuccessfulAttempt();
+ ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
+ mUserManager, mEffectiveUserId);
}
startDisappearAnimation(intent);
- checkForPendingIntent();
+ ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
} else {
if (timeoutMs > 0) {
refreshLockScreen();