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
This commit is contained in:
@@ -1463,7 +1463,7 @@
|
|||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:permission="android.permission.MANAGE_USERS"
|
android:permission="android.permission.MANAGE_USERS"
|
||||||
android:resizeableActivity="false"
|
android:resizeableActivity="false"
|
||||||
android:theme="@android:style/Theme.NoDisplay">
|
android:theme="@android:style/Theme.Translucent.NoTitleBar">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
|
<action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
@@ -50,6 +50,9 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
private Executor mClientExecutor;
|
private Executor mClientExecutor;
|
||||||
private AuthenticationCallback mClientCallback;
|
private AuthenticationCallback mClientCallback;
|
||||||
|
|
||||||
|
// Re-settable by the application.
|
||||||
|
private int mUserId;
|
||||||
|
|
||||||
// Created/Initialized once and retained
|
// Created/Initialized once and retained
|
||||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
private PromptInfo mPromptInfo;
|
private PromptInfo mPromptInfo;
|
||||||
@@ -96,6 +99,10 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
mClientCallback = callback;
|
mClientCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUser(int userId) {
|
||||||
|
mUserId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
if (mCancellationSignal != null) {
|
if (mCancellationSignal != null) {
|
||||||
mCancellationSignal.cancel();
|
mCancellationSignal.cancel();
|
||||||
@@ -126,8 +133,8 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
mCancellationSignal = new CancellationSignal();
|
mCancellationSignal = new CancellationSignal();
|
||||||
|
|
||||||
// TODO: CC doesn't use crypto for now
|
// TODO: CC doesn't use crypto for now
|
||||||
mBiometricPrompt.authenticate(mCancellationSignal, mClientExecutor,
|
mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
|
||||||
mAuthenticationCallback);
|
mAuthenticationCallback, mUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -20,9 +20,9 @@ package com.android.settings.password;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.app.trust.TrustManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.hardware.biometrics.BiometricConstants;
|
|
||||||
import android.hardware.biometrics.BiometricManager;
|
import android.hardware.biometrics.BiometricManager;
|
||||||
import android.hardware.biometrics.BiometricPrompt;
|
import android.hardware.biometrics.BiometricPrompt;
|
||||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
||||||
@@ -84,13 +84,13 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
private DevicePolicyManager mDevicePolicyManager;
|
private DevicePolicyManager mDevicePolicyManager;
|
||||||
private LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
|
private TrustManager mTrustManager;
|
||||||
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
||||||
private Handler mHandler = new Handler(Looper.getMainLooper());
|
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
private String mTitle;
|
private String mTitle;
|
||||||
private String mDetails;
|
private String mDetails;
|
||||||
private int mUserId;
|
private int mUserId;
|
||||||
private int mEffectiveUserId;
|
|
||||||
private int mCredentialMode;
|
private int mCredentialMode;
|
||||||
private boolean mGoingToBackground;
|
private boolean mGoingToBackground;
|
||||||
|
|
||||||
@@ -108,10 +108,16 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
showConfirmCredentials();
|
showConfirmCredentials();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||||
|
mTrustManager.setDeviceLockedForUser(mUserId, false);
|
||||||
|
|
||||||
|
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils, mUserManager,
|
||||||
|
mUserId);
|
||||||
|
ConfirmDeviceCredentialUtils.checkForPendingIntent(
|
||||||
|
ConfirmDeviceCredentialActivity.this);
|
||||||
|
|
||||||
setResult(Activity.RESULT_OK);
|
setResult(Activity.RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
@@ -124,6 +130,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
mBiometricManager = getSystemService(BiometricManager.class);
|
mBiometricManager = getSystemService(BiometricManager.class);
|
||||||
mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
|
mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
|
||||||
mUserManager = UserManager.get(this);
|
mUserManager = UserManager.get(this);
|
||||||
|
mTrustManager = getSystemService(TrustManager.class);
|
||||||
mLockPatternUtils = new LockPatternUtils(this);
|
mLockPatternUtils = new LockPatternUtils(this);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
@@ -134,7 +141,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
|
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
|
||||||
|
|
||||||
mUserId = UserHandle.myUserId();
|
mUserId = UserHandle.myUserId();
|
||||||
mEffectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
final int effectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
||||||
if (isInternalActivity()) {
|
if (isInternalActivity()) {
|
||||||
try {
|
try {
|
||||||
mUserId = Utils.getUserIdFromBundle(this, intent.getExtras());
|
mUserId = Utils.getUserIdFromBundle(this, intent.getExtras());
|
||||||
@@ -162,21 +169,23 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
} else if (isManagedProfile && isInternalActivity()
|
} else if (isManagedProfile && isInternalActivity()
|
||||||
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
|
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
|
||||||
mCredentialMode = CREDENTIAL_MANAGED;
|
mCredentialMode = CREDENTIAL_MANAGED;
|
||||||
if (isBiometricAllowed()) {
|
if (isBiometricAllowed(effectiveUserId)) {
|
||||||
showBiometricPrompt();
|
showBiometricPrompt();
|
||||||
launchedBiometric = true;
|
launchedBiometric = true;
|
||||||
} else {
|
} else {
|
||||||
showConfirmCredentials();
|
showConfirmCredentials();
|
||||||
|
launchedCDC = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mCredentialMode = CREDENTIAL_NORMAL;
|
mCredentialMode = CREDENTIAL_NORMAL;
|
||||||
if (isBiometricAllowed()) {
|
if (isBiometricAllowed(effectiveUserId)) {
|
||||||
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
|
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
|
||||||
// onAuthenticationError and do the right thing automatically.
|
// onAuthenticationError and do the right thing automatically.
|
||||||
showBiometricPrompt();
|
showBiometricPrompt();
|
||||||
launchedBiometric = true;
|
launchedBiometric = true;
|
||||||
} else {
|
} else {
|
||||||
showConfirmCredentials();
|
showConfirmCredentials();
|
||||||
|
launchedCDC = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,19 +226,20 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
// credential. Otherwise, biometric can't unlock fbe/keystore through
|
// credential. Otherwise, biometric can't unlock fbe/keystore through
|
||||||
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
|
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
|
||||||
// biometric is disabled due to device restart.
|
// biometric is disabled due to device restart.
|
||||||
private boolean isStrongAuthRequired() {
|
private boolean isStrongAuthRequired(int effectiveUserId) {
|
||||||
return !mLockPatternUtils.isBiometricAllowedForUser(mEffectiveUserId)
|
return !mLockPatternUtils.isBiometricAllowedForUser(effectiveUserId)
|
||||||
|| !mUserManager.isUserUnlocked(mUserId);
|
|| !mUserManager.isUserUnlocked(mUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBiometricDisabledByAdmin() {
|
private boolean isBiometricDisabledByAdmin(int effectiveUserId) {
|
||||||
final int disabledFeatures =
|
final int disabledFeatures =
|
||||||
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mEffectiveUserId);
|
mDevicePolicyManager.getKeyguardDisabledFeatures(null, effectiveUserId);
|
||||||
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS) != 0;
|
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBiometricAllowed() {
|
private boolean isBiometricAllowed(int effectiveUserId) {
|
||||||
return !isStrongAuthRequired() && !isBiometricDisabledByAdmin();
|
return !isStrongAuthRequired(effectiveUserId)
|
||||||
|
&& !isBiometricDisabledByAdmin(effectiveUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showBiometricPrompt() {
|
private void showBiometricPrompt() {
|
||||||
@@ -250,6 +260,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
newFragment = true;
|
newFragment = true;
|
||||||
}
|
}
|
||||||
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
|
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
|
||||||
|
mBiometricFragment.setUser(mUserId);
|
||||||
|
|
||||||
if (newFragment) {
|
if (newFragment) {
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
@@ -18,17 +18,12 @@
|
|||||||
package com.android.settings.password;
|
package com.android.settings.password;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.ActivityOptions;
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.IActivityManager;
|
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.trust.TrustManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
@@ -36,7 +31,6 @@ import android.graphics.drawable.ColorDrawable;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -199,29 +193,6 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
|||||||
public void startEnterAnimation() {
|
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) {
|
private void setWorkChallengeBackground(View baseView, int userId) {
|
||||||
View mainContent = getActivity().findViewById(com.android.settings.R.id.main_content);
|
View mainContent = getActivity().findViewById(com.android.settings.R.id.main_content);
|
||||||
if (mainContent != null) {
|
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() {
|
protected void reportFailedAttempt() {
|
||||||
updateErrorMessage(
|
updateErrorMessage(
|
||||||
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
|
mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId) + 1);
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -434,10 +434,11 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mPasswordEntryInputDisabler.setInputEnabled(true);
|
mPasswordEntryInputDisabler.setInputEnabled(true);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
if (newResult) {
|
if (newResult) {
|
||||||
reportSuccessfulAttempt();
|
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
|
||||||
|
mUserManager, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
startDisappearAnimation(intent);
|
startDisappearAnimation(intent);
|
||||||
checkForPendingIntent();
|
ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
|
||||||
} else {
|
} else {
|
||||||
if (timeoutMs > 0) {
|
if (timeoutMs > 0) {
|
||||||
refreshLockScreen();
|
refreshLockScreen();
|
||||||
|
@@ -487,10 +487,11 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
|||||||
mLockPatternView.setEnabled(true);
|
mLockPatternView.setEnabled(true);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
if (newResult) {
|
if (newResult) {
|
||||||
reportSuccessfulAttempt();
|
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
|
||||||
|
mUserManager, mEffectiveUserId);
|
||||||
}
|
}
|
||||||
startDisappearAnimation(intent);
|
startDisappearAnimation(intent);
|
||||||
checkForPendingIntent();
|
ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
|
||||||
} else {
|
} else {
|
||||||
if (timeoutMs > 0) {
|
if (timeoutMs > 0) {
|
||||||
refreshLockScreen();
|
refreshLockScreen();
|
||||||
|
Reference in New Issue
Block a user