Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 1 | |
| 2 | /* |
| 3 | * Copyright (C) 2014 The Android Open Source Project |
| 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
Maurice Lam | 2eb170c | 2017-04-28 16:18:47 -0700 | [diff] [blame] | 18 | package com.android.settings.password; |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 19 | |
Fan Zhang | c3fd289 | 2019-01-29 16:00:19 -0800 | [diff] [blame] | 20 | import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; |
| 21 | |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 22 | import android.app.Activity; |
Jim Miller | 75fe9e0 | 2014-08-13 14:52:52 -0700 | [diff] [blame] | 23 | import android.app.KeyguardManager; |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 24 | import android.app.admin.DevicePolicyManager; |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 25 | import android.app.trust.TrustManager; |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 26 | import android.content.Context; |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 27 | import android.content.Intent; |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 28 | import android.hardware.biometrics.BiometricConstants; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 29 | import android.hardware.biometrics.BiometricManager; |
| 30 | import android.hardware.biometrics.BiometricPrompt; |
| 31 | import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback; |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 32 | import android.os.Bundle; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 33 | import android.os.Handler; |
| 34 | import android.os.Looper; |
Pavel Grafov | f20e341 | 2018-08-09 16:51:55 +0100 | [diff] [blame] | 35 | import android.os.UserHandle; |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 36 | import android.os.UserManager; |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 37 | import android.util.Log; |
| 38 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 39 | import androidx.annotation.NonNull; |
| 40 | import androidx.fragment.app.FragmentActivity; |
| 41 | |
Ricky Wai | b4d52ec | 2016-04-18 15:32:39 +0100 | [diff] [blame] | 42 | import com.android.internal.widget.LockPatternUtils; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 43 | import com.android.settings.R; |
Maurice Lam | 2eb170c | 2017-04-28 16:18:47 -0700 | [diff] [blame] | 44 | import com.android.settings.Utils; |
Ricky Wai | b4d52ec | 2016-04-18 15:32:39 +0100 | [diff] [blame] | 45 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 46 | import java.util.concurrent.Executor; |
| 47 | |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 48 | /** |
| 49 | * Launch this when you want to confirm the user is present by asking them to enter their |
| 50 | * PIN/password/pattern. |
| 51 | */ |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 52 | public class ConfirmDeviceCredentialActivity extends FragmentActivity { |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 53 | public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName(); |
| 54 | |
joshmccloskey | 9be0899 | 2019-10-14 17:45:57 -0700 | [diff] [blame] | 55 | /** |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 56 | * If the intent is sent from {@link com.android.systemui.keyguard.WorkLockActivityController} |
| 57 | * then check for device policy management flags. |
joshmccloskey | 9be0899 | 2019-10-14 17:45:57 -0700 | [diff] [blame] | 58 | */ |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 59 | public static final String EXTRA_FROM_WORK_LOCK_ACTIVITY_CONTROLLER = |
| 60 | "from_work_lock_activity_controller"; |
joshmccloskey | 9be0899 | 2019-10-14 17:45:57 -0700 | [diff] [blame] | 61 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 62 | // The normal flow that apps go through |
| 63 | private static final int CREDENTIAL_NORMAL = 1; |
| 64 | // Unlocks the managed profile when the primary profile is unlocked |
| 65 | private static final int CREDENTIAL_MANAGED = 2; |
| 66 | |
| 67 | private static final String TAG_BIOMETRIC_FRAGMENT = "fragment"; |
| 68 | |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 69 | public static class InternalActivity extends ConfirmDeviceCredentialActivity { |
| 70 | } |
| 71 | |
Svetoslav | 3ea423a | 2014-10-16 14:44:25 -0700 | [diff] [blame] | 72 | public static Intent createIntent(CharSequence title, CharSequence details) { |
| 73 | Intent intent = new Intent(); |
Fan Zhang | c3fd289 | 2019-01-29 16:00:19 -0800 | [diff] [blame] | 74 | intent.setClassName(SETTINGS_PACKAGE_NAME, |
Svetoslav | 3ea423a | 2014-10-16 14:44:25 -0700 | [diff] [blame] | 75 | ConfirmDeviceCredentialActivity.class.getName()); |
| 76 | intent.putExtra(KeyguardManager.EXTRA_TITLE, title); |
| 77 | intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details); |
| 78 | return intent; |
| 79 | } |
| 80 | |
Andres Morales | 6609b0c | 2015-04-12 15:38:25 -0700 | [diff] [blame] | 81 | public static Intent createIntent(CharSequence title, CharSequence details, long challenge) { |
| 82 | Intent intent = new Intent(); |
Fan Zhang | c3fd289 | 2019-01-29 16:00:19 -0800 | [diff] [blame] | 83 | intent.setClassName(SETTINGS_PACKAGE_NAME, |
Andres Morales | 6609b0c | 2015-04-12 15:38:25 -0700 | [diff] [blame] | 84 | ConfirmDeviceCredentialActivity.class.getName()); |
| 85 | intent.putExtra(KeyguardManager.EXTRA_TITLE, title); |
| 86 | intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details); |
| 87 | intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); |
| 88 | intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); |
| 89 | return intent; |
| 90 | } |
| 91 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 92 | private BiometricManager mBiometricManager; |
| 93 | private BiometricFragment mBiometricFragment; |
| 94 | private DevicePolicyManager mDevicePolicyManager; |
| 95 | private LockPatternUtils mLockPatternUtils; |
| 96 | private UserManager mUserManager; |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 97 | private TrustManager mTrustManager; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 98 | private ChooseLockSettingsHelper mChooseLockSettingsHelper; |
| 99 | private Handler mHandler = new Handler(Looper.getMainLooper()); |
joshmccloskey | 9be0899 | 2019-10-14 17:45:57 -0700 | [diff] [blame] | 100 | private Context mContext; |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 101 | private boolean mCheckDevicePolicyManager; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 102 | |
| 103 | private String mTitle; |
| 104 | private String mDetails; |
| 105 | private int mUserId; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 106 | private int mCredentialMode; |
| 107 | private boolean mGoingToBackground; |
| 108 | |
| 109 | private Executor mExecutor = (runnable -> { |
| 110 | mHandler.post(runnable); |
| 111 | }); |
| 112 | |
| 113 | private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() { |
| 114 | public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { |
| 115 | if (!mGoingToBackground) { |
Kevin Chyn | eeca918 | 2019-03-25 18:15:57 -0700 | [diff] [blame] | 116 | if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED |
| 117 | || errorCode == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 118 | finish(); |
| 119 | } else { |
| 120 | // All other errors go to some version of CC |
| 121 | showConfirmCredentials(); |
| 122 | } |
| 123 | } |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) { |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 127 | mTrustManager.setDeviceLockedForUser(mUserId, false); |
| 128 | |
| 129 | ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils, mUserManager, |
| 130 | mUserId); |
| 131 | ConfirmDeviceCredentialUtils.checkForPendingIntent( |
| 132 | ConfirmDeviceCredentialActivity.this); |
| 133 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 134 | setResult(Activity.RESULT_OK); |
| 135 | finish(); |
| 136 | } |
| 137 | }; |
| 138 | |
Kevin Chyn | eeca918 | 2019-03-25 18:15:57 -0700 | [diff] [blame] | 139 | private String getStringForError(int errorCode) { |
| 140 | switch (errorCode) { |
| 141 | case BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED: |
| 142 | return getString(com.android.internal.R.string.biometric_error_user_canceled); |
| 143 | case BiometricConstants.BIOMETRIC_ERROR_CANCELED: |
| 144 | return getString(com.android.internal.R.string.biometric_error_canceled); |
| 145 | default: |
| 146 | return null; |
| 147 | } |
| 148 | } |
| 149 | |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 150 | @Override |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 151 | protected void onCreate(Bundle savedInstanceState) { |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 152 | super.onCreate(savedInstanceState); |
| 153 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 154 | mBiometricManager = getSystemService(BiometricManager.class); |
| 155 | mDevicePolicyManager = getSystemService(DevicePolicyManager.class); |
| 156 | mUserManager = UserManager.get(this); |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 157 | mTrustManager = getSystemService(TrustManager.class); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 158 | mLockPatternUtils = new LockPatternUtils(this); |
| 159 | |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 160 | Intent intent = getIntent(); |
joshmccloskey | 9be0899 | 2019-10-14 17:45:57 -0700 | [diff] [blame] | 161 | mContext = this; |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 162 | mCheckDevicePolicyManager = intent |
| 163 | .getBooleanExtra(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 164 | mTitle = intent.getStringExtra(KeyguardManager.EXTRA_TITLE); |
| 165 | mDetails = intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION); |
Adrian Roos | 5a9a3cd | 2017-03-30 18:02:25 -0700 | [diff] [blame] | 166 | String alternateButton = intent.getStringExtra( |
| 167 | KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL); |
| 168 | boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction()); |
| 169 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 170 | mUserId = UserHandle.myUserId(); |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 171 | if (isInternalActivity()) { |
Benjamin Franz | 194300d | 2016-01-13 12:16:25 +0000 | [diff] [blame] | 172 | try { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 173 | mUserId = Utils.getUserIdFromBundle(this, intent.getExtras()); |
Benjamin Franz | 194300d | 2016-01-13 12:16:25 +0000 | [diff] [blame] | 174 | } catch (SecurityException se) { |
| 175 | Log.e(TAG, "Invalid intent extra", se); |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 176 | } |
| 177 | } |
Kevin Chyn | e264bf3 | 2019-02-05 18:55:52 -0800 | [diff] [blame] | 178 | final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 179 | final boolean isManagedProfile = UserManager.get(this).isManagedProfile(mUserId); |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 180 | // if the client app did not hand in a title and we are about to show the work challenge, |
| 181 | // check whether there is a policy setting the organization name and use that as title |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 182 | if ((mTitle == null) && isManagedProfile) { |
| 183 | mTitle = getTitleFromOrganizationName(mUserId); |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 184 | } |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 185 | mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this); |
Ricky Wai | b4d52ec | 2016-04-18 15:32:39 +0100 | [diff] [blame] | 186 | final LockPatternUtils lockPatternUtils = new LockPatternUtils(this); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 187 | |
joshmccloskey | 3786016 | 2019-09-17 14:05:51 -0700 | [diff] [blame] | 188 | final Bundle bpBundle = new Bundle(); |
joshmccloskey | 3786016 | 2019-09-17 14:05:51 -0700 | [diff] [blame] | 189 | bpBundle.putString(BiometricPrompt.KEY_TITLE, mTitle); |
| 190 | bpBundle.putString(BiometricPrompt.KEY_DESCRIPTION, mDetails); |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 191 | bpBundle.putBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, |
| 192 | mCheckDevicePolicyManager); |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 193 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 194 | boolean launchedBiometric = false; |
| 195 | boolean launchedCDC = false; |
Ricky Wai | b4d52ec | 2016-04-18 15:32:39 +0100 | [diff] [blame] | 196 | // If the target is a managed user and user key not unlocked yet, we will force unlock |
| 197 | // tied profile so it will enable work mode and unlock managed profile, when personal |
| 198 | // challenge is unlocked. |
Adrian Roos | 5a9a3cd | 2017-03-30 18:02:25 -0700 | [diff] [blame] | 199 | if (frp) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 200 | launchedCDC = mChooseLockSettingsHelper.launchFrpConfirmationActivity( |
| 201 | 0, mTitle, mDetails, alternateButton); |
Adrian Roos | 5a9a3cd | 2017-03-30 18:02:25 -0700 | [diff] [blame] | 202 | } else if (isManagedProfile && isInternalActivity() |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 203 | && !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) { |
| 204 | mCredentialMode = CREDENTIAL_MANAGED; |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 205 | if (isBiometricAllowed(effectiveUserId, mUserId)) { |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 206 | showBiometricPrompt(bpBundle); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 207 | launchedBiometric = true; |
| 208 | } else { |
| 209 | showConfirmCredentials(); |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 210 | launchedCDC = true; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 211 | } |
| 212 | } else { |
| 213 | mCredentialMode = CREDENTIAL_NORMAL; |
Rubin Xu | e0efe27 | 2019-03-18 14:58:53 +0000 | [diff] [blame] | 214 | if (isBiometricAllowed(effectiveUserId, mUserId)) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 215 | // Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to |
| 216 | // onAuthenticationError and do the right thing automatically. |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 217 | showBiometricPrompt(bpBundle); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 218 | launchedBiometric = true; |
| 219 | } else { |
| 220 | showConfirmCredentials(); |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 221 | launchedCDC = true; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 222 | } |
| 223 | } |
| 224 | |
| 225 | if (launchedCDC) { |
| 226 | finish(); |
| 227 | } else if (launchedBiometric) { |
| 228 | // Keep this activity alive until BiometricPrompt goes away |
| 229 | } else { |
| 230 | Log.d(TAG, "No pattern, password or PIN set."); |
| 231 | setResult(Activity.RESULT_OK); |
| 232 | finish(); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | @Override |
| 237 | protected void onStart() { |
| 238 | super.onStart(); |
| 239 | // Translucent activity that is "visible", so it doesn't complain about finish() |
| 240 | // not being called before onResume(). |
| 241 | setVisible(true); |
| 242 | } |
| 243 | |
| 244 | @Override |
| 245 | public void onPause() { |
| 246 | super.onPause(); |
| 247 | if (!isChangingConfigurations()) { |
| 248 | mGoingToBackground = true; |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 249 | finish(); |
| 250 | } else { |
| 251 | mGoingToBackground = false; |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | // User could be locked while Effective user is unlocked even though the effective owns the |
| 256 | // credential. Otherwise, biometric can't unlock fbe/keystore through |
| 257 | // verifyTiedProfileChallenge. In such case, we also wanna show the user message that |
| 258 | // biometric is disabled due to device restart. |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 259 | private boolean isStrongAuthRequired(int effectiveUserId) { |
| 260 | return !mLockPatternUtils.isBiometricAllowedForUser(effectiveUserId) |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 261 | || !mUserManager.isUserUnlocked(mUserId); |
| 262 | } |
| 263 | |
Rubin Xu | e0efe27 | 2019-03-18 14:58:53 +0000 | [diff] [blame] | 264 | private boolean isBiometricAllowed(int effectiveUserId, int realUserId) { |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 265 | return !isStrongAuthRequired(effectiveUserId) && !mLockPatternUtils |
| 266 | .hasPendingEscrowToken(realUserId); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 267 | } |
| 268 | |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 269 | private void showBiometricPrompt(Bundle bundle) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 270 | mBiometricManager.setActiveUser(mUserId); |
| 271 | |
| 272 | mBiometricFragment = (BiometricFragment) getSupportFragmentManager() |
| 273 | .findFragmentByTag(TAG_BIOMETRIC_FRAGMENT); |
| 274 | boolean newFragment = false; |
| 275 | |
| 276 | if (mBiometricFragment == null) { |
Kevin Chyn | e56df88 | 2019-01-24 19:42:05 -0800 | [diff] [blame] | 277 | mBiometricFragment = BiometricFragment.newInstance(bundle); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 278 | newFragment = true; |
| 279 | } |
| 280 | mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback); |
Kevin Chyn | 127da9c | 2018-11-09 16:13:53 -0800 | [diff] [blame] | 281 | mBiometricFragment.setUser(mUserId); |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 282 | |
| 283 | if (newFragment) { |
| 284 | getSupportFragmentManager().beginTransaction() |
| 285 | .add(mBiometricFragment, TAG_BIOMETRIC_FRAGMENT).commit(); |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | /** |
| 290 | * Shows ConfirmDeviceCredentials for normal apps. |
| 291 | */ |
| 292 | private void showConfirmCredentials() { |
| 293 | boolean launched = false; |
Rubin Xu | e0efe27 | 2019-03-18 14:58:53 +0000 | [diff] [blame] | 294 | // The only difference between CREDENTIAL_MANAGED and CREDENTIAL_NORMAL is that for |
| 295 | // CREDENTIAL_MANAGED, we launch the real confirm credential activity with an explicit |
| 296 | // but dummy challenge value (0L). This will result in ConfirmLockPassword calling |
| 297 | // verifyTiedProfileChallenge() (if it's a profile with unified challenge), due to the |
| 298 | // difference between ConfirmLockPassword.startVerifyPassword() and |
| 299 | // ConfirmLockPassword.startCheckPassword(). Calling verifyTiedProfileChallenge() here is |
| 300 | // necessary when this is part of the turning on work profile flow, because it forces |
| 301 | // unlocking the work profile even before the profile is running. |
| 302 | // TODO: Remove the duplication of checkPassword and verifyPassword in ConfirmLockPassword, |
| 303 | // LockPatternChecker and LockPatternUtils. verifyPassword should be the only API to use, |
| 304 | // which optionally accepts a challenge. |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 305 | if (mCredentialMode == CREDENTIAL_MANAGED) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 306 | launched = mChooseLockSettingsHelper |
| 307 | .launchConfirmationActivityWithExternalAndChallenge( |
| 308 | 0 /* request code */, null /* title */, mTitle, mDetails, |
| 309 | true /* isExternal */, 0L /* challenge */, mUserId); |
joshmccloskey | 53ccc44 | 2019-12-18 16:18:31 -0800 | [diff] [blame] | 310 | } else if (mCredentialMode == CREDENTIAL_NORMAL) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 311 | launched = mChooseLockSettingsHelper.launchConfirmationActivity( |
| 312 | 0 /* request code */, null /* title */, |
| 313 | mTitle, mDetails, false /* returnCredentials */, true /* isExternal */, |
| 314 | mUserId); |
Ricky Wai | b4d52ec | 2016-04-18 15:32:39 +0100 | [diff] [blame] | 315 | } |
| 316 | if (!launched) { |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 317 | Log.d(TAG, "No pin/pattern/pass set"); |
Jorim Jaggi | 74a2283 | 2015-09-10 20:12:19 -0700 | [diff] [blame] | 318 | setResult(Activity.RESULT_OK); |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 319 | } |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 320 | finish(); |
| 321 | } |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 322 | |
Kevin Chyn | b3ee231 | 2018-10-04 15:01:43 -0700 | [diff] [blame] | 323 | @Override |
| 324 | public void finish() { |
| 325 | super.finish(); |
| 326 | // Finish without animation since the activity is just there so we can launch |
| 327 | // BiometricPrompt. |
| 328 | overridePendingTransition(R.anim.confirm_credential_biometric_transition_enter, 0); |
| 329 | } |
| 330 | |
Clara Bayarri | c5cde05 | 2015-10-22 17:24:43 +0100 | [diff] [blame] | 331 | private boolean isInternalActivity() { |
| 332 | return this instanceof ConfirmDeviceCredentialActivity.InternalActivity; |
| 333 | } |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 334 | |
| 335 | private String getTitleFromOrganizationName(int userId) { |
| 336 | DevicePolicyManager dpm = (DevicePolicyManager) getSystemService( |
| 337 | Context.DEVICE_POLICY_SERVICE); |
Michal Karpinski | 435ec6e | 2016-04-12 15:20:08 +0100 | [diff] [blame] | 338 | CharSequence organizationNameForUser = (dpm != null) |
| 339 | ? dpm.getOrganizationNameForUser(userId) : null; |
| 340 | return organizationNameForUser != null ? organizationNameForUser.toString() : null; |
Benjamin Franz | 0e111e6 | 2016-02-01 17:27:17 +0000 | [diff] [blame] | 341 | } |
Jay Civelli | 09b5228 | 2014-07-10 17:27:07 -0700 | [diff] [blame] | 342 | } |