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 android.platform.helpers;
18 
19 import static android.content.Context.KEYGUARD_SERVICE;
20 import static android.os.SystemClock.sleep;
21 import static android.platform.helpers.CommonUtils.executeShellCommand;
22 import static android.platform.helpers.Constants.SHORT_WAIT_TIME_IN_SECONDS;
23 import static android.platform.helpers.ui.UiAutomatorUtils.getUiDevice;
24 import static android.platform.uiautomator_helpers.DeviceHelpers.getContext;
25 import static android.platform.uiautomator_helpers.WaitUtils.ensureThat;
26 import static android.view.KeyEvent.KEYCODE_ENTER;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.junit.Assert.assertEquals;
31 
32 import static java.lang.String.format;
33 import static java.lang.System.currentTimeMillis;
34 import static java.util.concurrent.TimeUnit.SECONDS;
35 
36 import android.app.KeyguardManager;
37 import android.content.ContentResolver;
38 import android.os.RemoteException;
39 import android.platform.helpers.features.common.HomeLockscreenPage;
40 import android.platform.test.util.HealthTestingUtils;
41 import android.provider.Settings;
42 import android.util.Log;
43 
44 import androidx.test.platform.app.InstrumentationRegistry;
45 
46 /**
47  * All required util for Lockscreen.
48  * @deprecated use classes from the "systemui-tapl" library instead
49  */
50 @Deprecated
51 public class LockscreenUtils {
52     private static final String TAG = "LockscreenUtils";
53     private static final String RESET_LOCKSCREEN_SHELL_COMMAND = "locksettings clear --old";
54     private static final String INPUT_KEYEVENT_COMMAND = "input keyevent";
55     private static final String INPUT_TEXT_COMMAND = "input keyboard text";
56     private static final String SET_PASSWORD_COMMAND = "locksettings set-password";
57     private static final String SET_PIN_COMMAND = "locksettings set-pin";
58     private static final String SET_PATTERN_COMMAND = "locksettings set-pattern";
59     private static final String SET_SWIPE_COMMAND = "locksettings set-disabled false";
60     private static final String SET_LOCK_AS_NONE_COMMAND = "locksettings set-disabled true";
61     private static final int MAX_LOCKSCREEN_TIMEOUT_IN_SEC = 10;
62 
63     public static int sPreviousAodSetting;
64 
LockscreenUtils()65     private LockscreenUtils() {
66     }
67 
68     /**
69      * To get an instance of class that can be used to lock and unlock the keygaurd.
70      *
71      * @return an instance of class that can be used to lock and unlock the screen.
72      */
getKeyguardManager()73     public static final KeyguardManager getKeyguardManager() {
74         return (KeyguardManager) getContext().getSystemService(KEYGUARD_SERVICE);
75     }
76 
77     /**
78      * Different way to set the Lockscreen for Android device. Currently we only support PIN,
79      * PATTERN and PASSWORD
80      *
81      * @param lockscreenType it enum with list of supported lockscreen type
82      * @param lockscreenCode code[PIN or PATTERN or PASSWORD] which needs to be set.
83      * @param expectedResult expected result after setting the lockscreen because for lock type
84      *                       Swipe and None Keygaurd#isKeyguardSecure remain unlocked i.e. false.
85      */
setLockscreen(LockscreenType lockscreenType, String lockscreenCode, boolean expectedResult)86     public static void setLockscreen(LockscreenType lockscreenType, String lockscreenCode,
87             boolean expectedResult) {
88         Log.d(TAG, format("Setting Lockscreen [%s(%s)]", lockscreenType, lockscreenCode));
89         switch (lockscreenType) {
90             case PIN:
91                 executeShellCommand(format("%s %s", SET_PIN_COMMAND, lockscreenCode));
92                 break;
93             case PASSWORD:
94                 executeShellCommand(format("%s %s", SET_PASSWORD_COMMAND, lockscreenCode));
95                 break;
96             case PATTERN:
97                 executeShellCommand(format("%s %s", SET_PATTERN_COMMAND, lockscreenCode));
98                 break;
99             case SWIPE:
100                 executeShellCommand(SET_SWIPE_COMMAND);
101                 break;
102             case NONE:
103                 executeShellCommand(SET_LOCK_AS_NONE_COMMAND);
104                 break;
105             default:
106                 throw new AssertionError("Non-supported Lockscreen Type: " + lockscreenType);
107         }
108         assertKeyguardSecure(expectedResult);
109     }
110 
assertKeyguardSecure(boolean expectedSecure)111     private static void assertKeyguardSecure(boolean expectedSecure) {
112         HealthTestingUtils.waitForCondition(
113                 () -> String.format("Assert that keyguard %s secure, but failed.",
114                         expectedSecure ? "is" : "isn't"),
115                 () -> getKeyguardManager().isKeyguardSecure() == expectedSecure);
116     }
117 
118     /**
119      * Resets the give lockscreen.
120      *
121      * @param lockscreenCode old code which is currently set.
122      */
resetLockscreen(String lockscreenCode)123     public static void resetLockscreen(String lockscreenCode) {
124         Log.d(TAG, String.format("Re-Setting Lockscreen %s", lockscreenCode));
125         executeShellCommand(
126                 format("%s %s", RESET_LOCKSCREEN_SHELL_COMMAND, lockscreenCode));
127         assertKeyguardSecure(/* expectedSecure= */ false);
128     }
129 
130     /**
131      * Entering the given code on the lockscreen
132      *
133      * @param lockscreenType type of lockscreen set.
134      * @param lockscreenCode valid lockscreen code.
135      */
enterCodeOnLockscreen(LockscreenType lockscreenType, String lockscreenCode)136     public static void enterCodeOnLockscreen(LockscreenType lockscreenType,
137             String lockscreenCode) {
138         Log.d(TAG,
139                 format("Entering Lockscreen code: %s(%s)", lockscreenType, lockscreenCode));
140         assertEquals("Lockscreen was not set", true,
141                 getKeyguardManager().isKeyguardSecure());
142         switch (lockscreenType) {
143             case PIN:
144             case PASSWORD:
145                 // Entering the lockscreen code in text box.
146                 executeShellCommand(format("%s %s", INPUT_TEXT_COMMAND, lockscreenCode));
147                 // Pressing the ENTER button after entering the code.
148                 executeShellCommand(format("%s %s", INPUT_KEYEVENT_COMMAND, KEYCODE_ENTER));
149                 break;
150             default:
151                 throw new AssertionError("Non-supported Lockscreen Type: " + lockscreenType);
152         }
153     }
154 
155     /**
156      * Check if the device is locked as per the user expectation.
157      *
158      * @param expectedLockStatus expected device lock status.
159      */
checkDeviceLock(boolean expectedLockStatus)160     public static void checkDeviceLock(boolean expectedLockStatus) {
161         Log.d(TAG, format("Checking device lock status: %s", expectedLockStatus));
162         long endTime = currentTimeMillis() + SECONDS.toMillis(MAX_LOCKSCREEN_TIMEOUT_IN_SEC);
163         while (currentTimeMillis() <= endTime) {
164             if (getKeyguardManager().isDeviceLocked() == expectedLockStatus) {
165                 break;
166             }
167             try {
168                 Thread.sleep(100);
169             } catch (InterruptedException e) {
170                 e.printStackTrace();
171             }
172         }
173         assertThat(getKeyguardManager().isDeviceLocked()).isEqualTo(expectedLockStatus);
174     }
175 
176     /**
177      * Goes to the Locked screen page
178      *
179      * @deprecated use Root.goToLockscreen() to improve validation b/322870306
180      */
goToLockScreen()181     public static void goToLockScreen() {
182         try {
183             getUiDevice().sleep();
184             sleep(SHORT_WAIT_TIME_IN_SECONDS * 1000);
185             getUiDevice().wakeUp();
186         } catch (RemoteException e) {
187             throw new RuntimeException(e);
188         }
189     }
190 
191     /** Ensures that the lockscreen is visible. */
ensureLockscreen()192     public static void ensureLockscreen() {
193         HomeLockscreenPage page = new HomeLockscreenPage();
194         HealthTestingUtils.waitForCondition(() -> "Lock screen is not visible", page::isVisible);
195     }
196 
197     /** Ensures that the lockscreen is not visible. */
ensureNoLockscreen()198     public static void ensureNoLockscreen() {
199         HomeLockscreenPage page = new HomeLockscreenPage();
200         ensureThat("Lock screen is invisible", () -> !page.isVisible());
201     }
202 
203     /**
204      * Dismisses the lock screen, by swiping up, if it's visible.
205      * The device shouldn't have a password set.
206      */
dismissLockScreen()207     public static void dismissLockScreen() {
208         checkDeviceLock(false /* expectedLockStatus */);
209 
210         HomeLockscreenPage page = new HomeLockscreenPage();
211         if (page.isVisible()) {
212             page.swipeUp();
213         }
214     }
215 
ensureAoD(boolean enabled)216     public static void ensureAoD(boolean enabled) {
217         final ContentResolver contentResolver =
218                 InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
219         sPreviousAodSetting = Settings.Secure.getInt(
220                 contentResolver, Settings.Secure.DOZE_ALWAYS_ON, 0);
221         final boolean isAodEnabled = sPreviousAodSetting != 0;
222         if (isAodEnabled != enabled) {
223             Settings.Secure.putInt(
224                     contentResolver, Settings.Secure.DOZE_ALWAYS_ON, enabled ? 1 : 0);
225         }
226     }
227 
recoverAoD()228     public static void recoverAoD() {
229         final ContentResolver contentResolver =
230                 InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
231         Settings.Secure.putInt(
232                 contentResolver, Settings.Secure.DOZE_ALWAYS_ON, sPreviousAodSetting);
233     }
234 
235     /**
236      * Enum for different types of Lockscreen, PIN, PATTERN and PASSWORD.
237      */
238     public enum LockscreenType {
239         PIN,
240         PASSWORD,
241         PATTERN,
242         SWIPE,
243         NONE
244     }
245 }
246