1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.settings.password; 18 19 import android.app.Activity; 20 import android.app.ActivityManager; 21 import android.app.ActivityOptions; 22 import android.app.IActivityManager; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.Intent; 25 import android.content.IntentSender; 26 import android.content.pm.UserInfo; 27 import android.content.pm.UserProperties; 28 import android.os.RemoteException; 29 import android.os.UserManager; 30 import android.view.View; 31 import android.view.WindowInsets; 32 import android.view.WindowInsetsController; 33 34 import androidx.annotation.NonNull; 35 36 import com.android.internal.widget.LockPatternUtils; 37 38 /** Class containing methods shared between CDCA and CDCBA */ 39 public class ConfirmDeviceCredentialUtils { 40 checkForPendingIntent(Activity activity)41 public static void checkForPendingIntent(Activity activity) { 42 // See Change-Id I52c203735fa9b53fd2f7df971824747eeb930f36 for context 43 int taskId = activity.getIntent().getIntExtra(Intent.EXTRA_TASK_ID, -1); 44 if (taskId != -1) { 45 try { 46 IActivityManager activityManager = ActivityManager.getService(); 47 final ActivityOptions options = ActivityOptions.makeBasic(); 48 activityManager.startActivityFromRecents(taskId, options.toBundle()); 49 return; 50 } catch (RemoteException e) { 51 // Do nothing. 52 } 53 } 54 IntentSender intentSender = activity.getIntent().getParcelableExtra(Intent.EXTRA_INTENT); 55 if (intentSender != null) { 56 try { 57 ActivityOptions activityOptions = 58 ActivityOptions.makeBasic() 59 .setPendingIntentBackgroundActivityStartMode( 60 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); 61 activity.startIntentSenderForResult(intentSender, -1, null, 0, 0, 0, 62 activityOptions.toBundle()); 63 } catch (IntentSender.SendIntentException e) { 64 /* ignore */ 65 } 66 } 67 } 68 reportSuccessfulAttempt(LockPatternUtils utils, UserManager userManager, DevicePolicyManager dpm, int userId, boolean isStrongAuth)69 public static void reportSuccessfulAttempt(LockPatternUtils utils, UserManager userManager, 70 DevicePolicyManager dpm, int userId, boolean isStrongAuth) { 71 if (isStrongAuth) { 72 utils.reportSuccessfulPasswordAttempt(userId); 73 if (isBiometricUnlockEnabledForPrivateSpace()) { 74 final UserInfo userInfo = userManager.getUserInfo(userId); 75 if (userInfo != null) { 76 if (isProfileThatAlwaysRequiresAuthToDisableQuietMode(userManager, userInfo) 77 || userInfo.isManagedProfile()) { 78 // Keyguard is responsible to disable StrongAuth for primary user. Disable 79 // StrongAuth for profile challenges only here. 80 utils.userPresent(userId); 81 } 82 } 83 } 84 } else { 85 dpm.reportSuccessfulBiometricAttempt(userId); 86 } 87 if (!isBiometricUnlockEnabledForPrivateSpace()) { 88 if (userManager.isManagedProfile(userId)) { 89 // Disable StrongAuth for work challenge only here. 90 utils.userPresent(userId); 91 } 92 } 93 } 94 95 /** 96 * Returns true if the userInfo passed as the parameter corresponds to a profile that always 97 * requires auth to disable quiet mode and false otherwise 98 */ isProfileThatAlwaysRequiresAuthToDisableQuietMode( UserManager userManager, @NonNull UserInfo userInfo)99 private static boolean isProfileThatAlwaysRequiresAuthToDisableQuietMode( 100 UserManager userManager, @NonNull UserInfo userInfo) { 101 final UserProperties userProperties = 102 userManager.getUserProperties(userInfo.getUserHandle()); 103 return userProperties.isAuthAlwaysRequiredToDisableQuietMode() && userInfo.isProfile(); 104 } 105 isBiometricUnlockEnabledForPrivateSpace()106 private static boolean isBiometricUnlockEnabledForPrivateSpace() { 107 return android.os.Flags.allowPrivateProfile() 108 && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace() 109 && android.multiuser.Flags.enablePrivateSpaceFeatures(); 110 } 111 112 /** 113 * Request hiding soft-keyboard before animating away credential UI, in case IME 114 * insets animation get delayed by dismissing animation. 115 * @param view used to get root {@link WindowInsets} and {@link WindowInsetsController}. 116 */ hideImeImmediately(@onNull View view)117 public static void hideImeImmediately(@NonNull View view) { 118 if (view.isAttachedToWindow() 119 && view.getRootWindowInsets().isVisible(WindowInsets.Type.ime())) { 120 view.getWindowInsetsController().hide(WindowInsets.Type.ime()); 121 } 122 } 123 } 124