1 /*
2  * Copyright (C) 2022 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.security;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.UserHandle;
23 import android.os.UserManager;
24 import android.os.storage.StorageManager;
25 
26 import androidx.annotation.StringRes;
27 
28 import com.android.internal.app.UnlaunchableAppActivity;
29 import com.android.internal.widget.LockPatternUtils;
30 import com.android.settings.R;
31 import com.android.settings.Utils;
32 import com.android.settings.core.SubSettingLauncher;
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
35 import com.android.settings.security.screenlock.ScreenLockSettings;
36 import com.android.settingslib.RestrictedLockUtils;
37 import com.android.settingslib.transition.SettingsTransitionHelper;
38 
39 /**
40  * Utilities for screen lock details shared between Security Settings and Safety Center.
41  */
42 public class ScreenLockPreferenceDetailsUtils {
43 
44     private final int mUserId = UserHandle.myUserId();
45     private final Context mContext;
46     private final LockPatternUtils mLockPatternUtils;
47     private final int mProfileChallengeUserId;
48     private final UserManager mUm;
49 
ScreenLockPreferenceDetailsUtils(Context context)50     public ScreenLockPreferenceDetailsUtils(Context context) {
51         mContext = context;
52         mUm = context.getSystemService(UserManager.class);
53         mLockPatternUtils = FeatureFactory.getFeatureFactory()
54                 .getSecurityFeatureProvider()
55                 .getLockPatternUtils(context);
56         mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
57     }
58 
59     /**
60      * Returns whether the screen lock settings entity should be shown.
61      */
isAvailable()62     public boolean isAvailable() {
63         return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
64     }
65 
66     /**
67      * Returns the summary of screen lock settings entity.
68      */
getSummary(int userId)69     public String getSummary(int userId) {
70         final Integer summaryResId = getSummaryResId(userId);
71         return summaryResId != null ? mContext.getResources().getString(summaryResId) : null;
72     }
73 
74     /**
75      * Returns whether the password quality is managed by device admin.
76      */
isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin)77     public boolean isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin) {
78         final DevicePolicyManager dpm = (DevicePolicyManager) mContext
79                 .getSystemService(Context.DEVICE_POLICY_SERVICE);
80         return admin != null && dpm.getPasswordQuality(admin.component, userId)
81                 == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
82     }
83 
84     /**
85      * Returns whether the lock pattern is secure.
86      */
isLockPatternSecure()87     public boolean isLockPatternSecure() {
88         return mLockPatternUtils.isSecure(mUserId);
89     }
90 
91     /**
92      * Returns whether the Gear Menu should be shown.
93      */
shouldShowGearMenu()94     public boolean shouldShowGearMenu() {
95         return isLockPatternSecure();
96     }
97 
98     /**
99      * Launches the {@link ScreenLockSettings}.
100      */
openScreenLockSettings(int sourceMetricsCategory)101     public void openScreenLockSettings(int sourceMetricsCategory) {
102         mContext.startActivity(getLaunchScreenLockSettingsIntent(sourceMetricsCategory));
103     }
104 
105     /**
106      * Returns {@link Intent} to launch the {@link ScreenLockSettings}.
107      */
getLaunchScreenLockSettingsIntent(int sourceMetricsCategory)108     public Intent getLaunchScreenLockSettingsIntent(int sourceMetricsCategory) {
109         return new SubSettingLauncher(mContext)
110                 .setDestination(ScreenLockSettings.class.getName())
111                 .setSourceMetricsCategory(sourceMetricsCategory)
112                 .toIntent();
113     }
114 
115     /**
116      * Tries to launch the {@link ChooseLockGenericFragment} if Quiet Mode is not enabled
117      * for managed profile, otherwise shows a dialog to disable the Quiet Mode.
118      *
119      * @return true if the {@link ChooseLockGenericFragment} is launching.
120      */
openChooseLockGenericFragment(int sourceMetricsCategory)121     public boolean openChooseLockGenericFragment(int sourceMetricsCategory) {
122         final Intent quietModeDialogIntent = getQuietModeDialogIntent();
123         if (quietModeDialogIntent != null) {
124             mContext.startActivity(quietModeDialogIntent);
125             return false;
126         }
127         mContext.startActivity(getChooseLockGenericFragmentIntent(sourceMetricsCategory));
128         return true;
129     }
130 
131     /**
132      * Returns {@link Intent} to launch an appropriate Settings screen.
133      *
134      * <p>If Quiet Mode is enabled for managed profile, returns {@link Intent} to launch a dialog
135      * to disable the Quiet Mode, otherwise returns {@link Intent} to launch
136      * {@link ChooseLockGenericFragment}.
137      */
getLaunchChooseLockGenericFragmentIntent(int sourceMetricsCategory)138     public Intent getLaunchChooseLockGenericFragmentIntent(int sourceMetricsCategory) {
139         final Intent quietModeDialogIntent = getQuietModeDialogIntent();
140         return quietModeDialogIntent != null ? quietModeDialogIntent
141                 : getChooseLockGenericFragmentIntent(sourceMetricsCategory);
142     }
143 
getQuietModeDialogIntent()144     private Intent getQuietModeDialogIntent() {
145         // TODO(b/35930129): Remove once existing password can be passed into vold directly.
146         // Currently we need this logic to ensure that the QUIET_MODE is off for any work
147         // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
148         // able to complete the operation due to the lack of (old) encryption key.
149         if (mProfileChallengeUserId != UserHandle.USER_NULL
150                 && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
151                 && StorageManager.isFileEncrypted()) {
152             if (mUm.isQuietModeEnabled(UserHandle.of(mProfileChallengeUserId))) {
153                 return UnlaunchableAppActivity.createInQuietModeDialogIntent(
154                         mProfileChallengeUserId);
155             }
156         }
157         return null;
158     }
159 
getChooseLockGenericFragmentIntent(int sourceMetricsCategory)160     private Intent getChooseLockGenericFragmentIntent(int sourceMetricsCategory) {
161         return new SubSettingLauncher(mContext)
162                 .setDestination(ChooseLockGenericFragment.class.getName())
163                 .setSourceMetricsCategory(sourceMetricsCategory)
164                 .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
165                 .toIntent();
166     }
167 
168     @StringRes
getSummaryResId(int userId)169     private Integer getSummaryResId(int userId) {
170         if (!mLockPatternUtils.isSecure(userId)) {
171             if (userId == mProfileChallengeUserId
172                     || mLockPatternUtils.isLockScreenDisabled(userId)) {
173                 return R.string.unlock_set_unlock_mode_off;
174             } else {
175                 return R.string.unlock_set_unlock_mode_none;
176             }
177         } else {
178             int keyguardStoredPasswordQuality =
179                     mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
180             switch (keyguardStoredPasswordQuality) {
181                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
182                     return R.string.unlock_set_unlock_mode_pattern;
183                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
184                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
185                     return R.string.unlock_set_unlock_mode_pin;
186                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
187                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
188                 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
189                 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
190                     return R.string.unlock_set_unlock_mode_password;
191                 default:
192                     return null;
193             }
194         }
195     }
196 }
197