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