1 package com.android.cts.passwordcomplexity;
2 
3 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
4 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
5 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
6 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
7 
8 import static junit.framework.Assert.assertEquals;
9 import static junit.framework.Assert.fail;
10 
11 import android.app.admin.DevicePolicyManager;
12 import android.content.Context;
13 import android.support.test.uiautomator.UiDevice;
14 import android.text.TextUtils;
15 
16 import androidx.test.InstrumentationRegistry;
17 import androidx.test.filters.SmallTest;
18 
19 import org.junit.After;
20 import org.junit.Before;
21 import org.junit.Test;
22 
23 /** Tests for {@link DevicePolicyManager#getPasswordComplexity()}. */
24 @SmallTest
25 public class GetPasswordComplexityTest {
26 
27     private DevicePolicyManager mDpm;
28     private UiDevice mDevice;
29     private String mScreenLock;
30 
31     @Before
setUp()32     public void setUp() throws Exception {
33         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
34         if (!mDevice.executeShellCommand("cmd lock_settings verify")
35                 .startsWith("Lock credential verified successfully")) {
36             fail("Please remove the device screen lock before running this test");
37         }
38 
39         mDpm = (DevicePolicyManager) InstrumentationRegistry
40                 .getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
41     }
42 
43     @After
tearDown()44     public void tearDown() throws Exception {
45         clearScreenLock();
46     }
47 
48     @Test
getPasswordComplexity_none()49     public void getPasswordComplexity_none() {
50         assertPasswordComplexity(PASSWORD_COMPLEXITY_NONE);
51     }
52 
53     @Test
getPasswordComplexity_alphanumeric6_high()54     public void getPasswordComplexity_alphanumeric6_high() throws Exception {
55         setPassword("abc!23");
56         assertPasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
57     }
58 
59     @Test
getPasswordComplexity_alphanumeric5_medium()60     public void getPasswordComplexity_alphanumeric5_medium() throws Exception {
61         setPassword("bc!23");
62         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
63     }
64 
65     @Test
getPasswordComplexity_alphanumeric4_medium()66     public void getPasswordComplexity_alphanumeric4_medium() throws Exception {
67         setPassword("c!23");
68         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
69     }
70 
71     @Test
getPasswordComplexity_alphabetic6_high()72     public void getPasswordComplexity_alphabetic6_high() throws Exception {
73         setPassword("abc!qw");
74         assertPasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
75     }
76 
77     @Test
getPasswordComplexity_alphabetic5_medium()78     public void getPasswordComplexity_alphabetic5_medium() throws Exception {
79         setPassword("bc!qw");
80         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
81     }
82 
83     @Test
getPasswordComplexity_alphabetic4_medium()84     public void getPasswordComplexity_alphabetic4_medium() throws Exception {
85         setPassword("c!qw");
86         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
87     }
88 
89     @Test
getPasswordComplexity_numericComplex8_high()90     public void getPasswordComplexity_numericComplex8_high() throws Exception {
91         setPin("12389647");
92         assertPasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
93     }
94 
95     @Test
getPasswordComplexity_numericComplex7_medium()96     public void getPasswordComplexity_numericComplex7_medium() throws Exception {
97         setPin("1238964");
98         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
99     }
100 
101     @Test
getPasswordComplexity_numericComplex4_medium()102     public void getPasswordComplexity_numericComplex4_medium() throws Exception {
103         setPin("1238");
104         assertPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
105     }
106 
107     @Test
getPasswordComplexity_numeric16_low()108     public void getPasswordComplexity_numeric16_low() throws Exception {
109         setPin("1234567898765432");
110         assertPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
111     }
112 
113     @Test
getPasswordComplexity_numeric4_low()114     public void getPasswordComplexity_numeric4_low() throws Exception {
115         setPin("1234");
116         assertPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
117     }
118 
119     @Test
getPasswordComplexity_pattern9_low()120     public void getPasswordComplexity_pattern9_low() throws Exception {
121         setPattern("123456789");
122         assertPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
123     }
124 
125     @Test
getPasswordComplexity_pattern4_low()126     public void getPasswordComplexity_pattern4_low() throws Exception {
127         setPattern("1234");
128         assertPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
129     }
130 
setPattern(String pattern)131     private void setPattern(String pattern) throws Exception {
132         String out = mDevice.executeShellCommand("cmd lock_settings set-pattern " + pattern);
133         if (!out.startsWith("Pattern set to")) {
134             fail("Failed to set pattern: " + out);
135         }
136         mScreenLock = pattern;
137     }
138 
setPin(String pin)139     private void setPin(String pin) throws Exception {
140         String out = mDevice.executeShellCommand("cmd lock_settings set-pin " + pin);
141         if (!out.startsWith("Pin set to")) {
142             fail("Failed to set pin: " + out);
143         }
144         mScreenLock = pin;
145     }
146 
setPassword(String password)147     private void setPassword(String password) throws Exception {
148         String out =
149                 mDevice.executeShellCommand("cmd lock_settings set-password " + password);
150         if (!out.startsWith("Password set to")) {
151             fail("Failed to set password: " + out);
152         }
153         mScreenLock = password;
154     }
155 
clearScreenLock()156     private void clearScreenLock() throws Exception {
157         if (TextUtils.isEmpty(mScreenLock)) {
158             return;
159         }
160         String out =
161                 mDevice.executeShellCommand("cmd lock_settings clear --old " + mScreenLock);
162         if (!out.startsWith("Lock credential cleared")) {
163             fail("Failed to clear user credential: " + out);
164         }
165         mScreenLock = null;
166     }
167 
assertPasswordComplexity(int expectedComplexity)168     private void assertPasswordComplexity(int expectedComplexity) {
169         // password metrics is updated asynchronously so let's be lenient here and retry a few times
170         final int maxRetries = 15;
171         int retry = 0;
172         while (retry < maxRetries && mDpm.getPasswordComplexity() != expectedComplexity) {
173             retry++;
174             try {
175                 Thread.sleep(200);
176             } catch (InterruptedException e) {
177                 break;
178             }
179         }
180         assertEquals(expectedComplexity, mDpm.getPasswordComplexity());
181     }
182 }
183