1 /*
2  * Copyright (C) 2017 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.testutils.shadow;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.app.admin.PasswordMetrics;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.pm.UserInfo;
24 import android.os.UserHandle;
25 
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 
29 import com.android.internal.widget.LockPatternUtils;
30 import com.android.internal.widget.LockscreenCredential;
31 
32 import org.robolectric.annotation.Implementation;
33 import org.robolectric.annotation.Implements;
34 import org.robolectric.annotation.Resetter;
35 
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 
40 @Implements(LockPatternUtils.class)
41 public class ShadowLockPatternUtils {
42 
43     private static boolean sDeviceEncryptionEnabled;
44     private static Map<Integer, Integer> sUserToActivePasswordQualityMap = new HashMap<>();
45     private static Map<Integer, Integer> sUserToComplexityMap = new HashMap<>();
46     private static Map<Integer, Integer> sUserToProfileComplexityMap = new HashMap<>();
47     private static Map<Integer, PasswordMetrics> sUserToMetricsMap = new HashMap<>();
48     private static Map<Integer, PasswordMetrics> sUserToProfileMetricsMap = new HashMap<>();
49     private static Map<Integer, Boolean> sUserToIsSecureMap = new HashMap<>();
50     private static Map<Integer, Boolean> sUserToVisiblePatternEnabledMap = new HashMap<>();
51     private static Map<Integer, Boolean> sUserToBiometricAllowedMap = new HashMap<>();
52     private static Map<Integer, Boolean> sUserToLockPatternEnabledMap = new HashMap<>();
53     private static Map<Integer, Integer> sKeyguardStoredPasswordQualityMap = new HashMap<>();
54 
55     private static boolean sIsUserOwnsFrpCredential;
56 
57     @Resetter
reset()58     public static void reset() {
59         sUserToActivePasswordQualityMap.clear();
60         sUserToComplexityMap.clear();
61         sUserToProfileComplexityMap.clear();
62         sUserToMetricsMap.clear();
63         sUserToProfileMetricsMap.clear();
64         sUserToIsSecureMap.clear();
65         sUserToVisiblePatternEnabledMap.clear();
66         sUserToBiometricAllowedMap.clear();
67         sUserToLockPatternEnabledMap.clear();
68         sDeviceEncryptionEnabled = false;
69         sIsUserOwnsFrpCredential = false;
70         sKeyguardStoredPasswordQualityMap.clear();
71     }
72 
73     @Implementation
hasSecureLockScreen()74     protected boolean hasSecureLockScreen() {
75         return true;
76     }
77 
78     @Implementation
isSecure(int userId)79     protected boolean isSecure(int userId) {
80         Boolean isSecure = sUserToIsSecureMap.get(userId);
81         if (isSecure == null) {
82             return true;
83         }
84         return isSecure;
85     }
86 
setIsSecure(int userId, boolean isSecure)87     public static void setIsSecure(int userId, boolean isSecure) {
88         sUserToIsSecureMap.put(userId, isSecure);
89     }
90 
91     @Implementation
getActivePasswordQuality(int userId)92     protected int getActivePasswordQuality(int userId) {
93         final Integer activePasswordQuality = sUserToActivePasswordQualityMap.get(userId);
94         if (activePasswordQuality == null) {
95             return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
96         }
97         return activePasswordQuality;
98     }
99 
100     @Implementation
getKeyguardStoredPasswordQuality(int userHandle)101     protected int getKeyguardStoredPasswordQuality(int userHandle) {
102         return sKeyguardStoredPasswordQualityMap.getOrDefault(userHandle, /* defaultValue= */ 1);
103     }
104 
105     @Implementation
isDeviceEncryptionEnabled()106     protected static boolean isDeviceEncryptionEnabled() {
107         return sDeviceEncryptionEnabled;
108     }
109 
110     @Implementation
getEnabledTrustAgents(int userId)111     protected List<ComponentName> getEnabledTrustAgents(int userId) {
112         return null;
113     }
114 
setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled)115     public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
116         sDeviceEncryptionEnabled = deviceEncryptionEnabled;
117     }
118 
119     @Implementation
getPasswordHistoryHashFactor( LockscreenCredential currentPassword, int userId)120     protected byte[] getPasswordHistoryHashFactor(
121             LockscreenCredential currentPassword, int userId) {
122         return null;
123     }
124 
125     @Implementation
checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId)126     protected boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) {
127         return false;
128     }
129 
130     @Implementation
getRequestedPasswordComplexity(int userId)131     public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId) {
132         return getRequestedPasswordComplexity(userId, false);
133     }
134 
135     @Implementation
136     @DevicePolicyManager.PasswordComplexity
getRequestedPasswordComplexity(int userId, boolean deviceWideOnly)137     public int getRequestedPasswordComplexity(int userId, boolean deviceWideOnly) {
138         int complexity = sUserToComplexityMap.getOrDefault(userId,
139                 DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
140         if (!deviceWideOnly) {
141             complexity = Math.max(complexity, sUserToProfileComplexityMap.getOrDefault(userId,
142                     DevicePolicyManager.PASSWORD_COMPLEXITY_NONE));
143         }
144         return complexity;
145     }
146 
147     @Implementation
userOwnsFrpCredential(Context context, UserInfo info)148     public static boolean userOwnsFrpCredential(Context context, UserInfo info) {
149         return sIsUserOwnsFrpCredential;
150     }
151 
setUserOwnsFrpCredential(boolean isUserOwnsFrpCredential)152     public static void setUserOwnsFrpCredential(boolean isUserOwnsFrpCredential) {
153         sIsUserOwnsFrpCredential = isUserOwnsFrpCredential;
154     }
155 
156     @Implementation
isVisiblePatternEnabled(int userId)157     public boolean isVisiblePatternEnabled(int userId) {
158         return sUserToVisiblePatternEnabledMap.getOrDefault(userId, false);
159     }
160 
setIsVisiblePatternEnabled(int userId, boolean isVisiblePatternEnabled)161     public static void setIsVisiblePatternEnabled(int userId, boolean isVisiblePatternEnabled) {
162         sUserToVisiblePatternEnabledMap.put(userId, isVisiblePatternEnabled);
163     }
164 
165     @Implementation
isBiometricAllowedForUser(int userId)166     public boolean isBiometricAllowedForUser(int userId) {
167         return sUserToBiometricAllowedMap.getOrDefault(userId, false);
168     }
169 
setIsBiometricAllowedForUser(int userId, boolean isBiometricAllowed)170     public static void setIsBiometricAllowedForUser(int userId, boolean isBiometricAllowed) {
171         sUserToBiometricAllowedMap.put(userId, isBiometricAllowed);
172     }
173 
174     @Implementation
isLockPatternEnabled(int userId)175     public boolean isLockPatternEnabled(int userId) {
176         return sUserToLockPatternEnabledMap.getOrDefault(userId, false);
177     }
178 
setIsLockPatternEnabled(int userId, boolean isLockPatternEnabled)179     public static void setIsLockPatternEnabled(int userId, boolean isLockPatternEnabled) {
180         sUserToLockPatternEnabledMap.put(userId, isLockPatternEnabled);
181     }
182 
183     @Implementation
setLockCredential( @onNull LockscreenCredential newCredential, @NonNull LockscreenCredential savedCredential, int userHandle)184     public boolean setLockCredential(
185             @NonNull LockscreenCredential newCredential,
186             @NonNull LockscreenCredential savedCredential, int userHandle) {
187         setIsSecure(userHandle, true);
188         return true;
189     }
190 
191     @Implementation
checkCredential( @onNull LockscreenCredential credential, int userId, @Nullable LockPatternUtils.CheckCredentialProgressCallback progressCallback)192     public boolean checkCredential(
193             @NonNull LockscreenCredential credential, int userId,
194             @Nullable LockPatternUtils.CheckCredentialProgressCallback progressCallback)
195             throws LockPatternUtils.RequestThrottledException {
196         return true;
197     }
198 
setRequiredPasswordComplexity(int userHandle, int complexity)199     public static void setRequiredPasswordComplexity(int userHandle, int complexity) {
200         sUserToComplexityMap.put(userHandle, complexity);
201     }
202 
setRequiredPasswordComplexity(int complexity)203     public static void setRequiredPasswordComplexity(int complexity) {
204         sUserToComplexityMap.put(UserHandle.myUserId(), complexity);
205     }
206 
setRequiredProfilePasswordComplexity(int complexity)207     public static void setRequiredProfilePasswordComplexity(int complexity) {
208         sUserToProfileComplexityMap.put(UserHandle.myUserId(), complexity);
209     }
210 
211     @Implementation
getRequestedPasswordMetrics(int userId, boolean deviceWideOnly)212     public PasswordMetrics getRequestedPasswordMetrics(int userId, boolean deviceWideOnly) {
213         PasswordMetrics metrics = sUserToMetricsMap.getOrDefault(userId,
214                 new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE));
215         if (!deviceWideOnly) {
216             metrics.maxWith(sUserToProfileMetricsMap.getOrDefault(userId,
217                     new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE)));
218         }
219         return metrics;
220     }
221 
setRequestedPasswordMetrics(PasswordMetrics metrics)222     public static void setRequestedPasswordMetrics(PasswordMetrics metrics) {
223         sUserToMetricsMap.put(UserHandle.myUserId(), metrics);
224     }
225 
setRequestedProfilePasswordMetrics(PasswordMetrics metrics)226     public static void setRequestedProfilePasswordMetrics(PasswordMetrics metrics) {
227         sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics);
228     }
229 
setActivePasswordQuality(int quality)230     public static void setActivePasswordQuality(int quality) {
231         sUserToActivePasswordQualityMap.put(UserHandle.myUserId(), quality);
232     }
233 
234     @Implementation
isLockScreenDisabled(int userId)235     public boolean isLockScreenDisabled(int userId) {
236         return false;
237     }
238 
239     @Implementation
isSeparateProfileChallengeEnabled(int userHandle)240     public boolean isSeparateProfileChallengeEnabled(int userHandle) {
241         return false;
242     }
243 
setKeyguardStoredPasswordQuality(int quality)244     public static void setKeyguardStoredPasswordQuality(int quality) {
245         sKeyguardStoredPasswordQualityMap.put(UserHandle.myUserId(), quality);
246     }
247 }
248