diff --git a/AndroidManifest.xml b/AndroidManifest.xml index eb3be0e37d1..6ffc3b2823b 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"> diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java index 6e1ae10d841..3a12bacfd8a 100644 --- a/src/com/android/settings/password/BiometricFragment.java +++ b/src/com/android/settings/password/BiometricFragment.java @@ -50,6 +50,9 @@ public class BiometricFragment extends InstrumentedFragment { 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 @@ public class BiometricFragment extends InstrumentedFragment { mClientCallback = callback; } + public void setUser(int userId) { + mUserId = userId; + } + public void cancel() { if (mCancellationSignal != null) { mCancellationSignal.cancel(); @@ -126,8 +133,8 @@ public class BiometricFragment extends InstrumentedFragment { 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 f68c04ad298..5eb1f322c27 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java @@ -20,9 +20,9 @@ package com.android.settings.password; 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { } 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { // 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 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { 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 9b677aa4ace..2de7625b9ed 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.ColorDrawable; 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 abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr 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 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr } } - 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 00000000000..11d69246206 --- /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 d380fc966ab..45b8129e31f 100644 --- a/src/com/android/settings/password/ConfirmLockPassword.java +++ b/src/com/android/settings/password/ConfirmLockPassword.java @@ -434,10 +434,11 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { 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 95a0aca4fdd..83141ea3d68 100644 --- a/src/com/android/settings/password/ConfirmLockPattern.java +++ b/src/com/android/settings/password/ConfirmLockPattern.java @@ -487,10 +487,11 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { mLockPatternView.setEnabled(true); if (matched) { if (newResult) { - reportSuccessfulAttempt(); + ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils, + mUserManager, mEffectiveUserId); } startDisappearAnimation(intent); - checkForPendingIntent(); + ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity()); } else { if (timeoutMs > 0) { refreshLockScreen();