1 /* 2 * Copyright (C) 2024 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.systemui_tapl.controller; 18 19 import static android.content.Context.KEYGUARD_SERVICE; 20 import static android.platform.helpers.LockscreenUtils.LockscreenType.NONE; 21 import static android.platform.helpers.LockscreenUtils.LockscreenType.PASSWORD; 22 import static android.platform.helpers.LockscreenUtils.LockscreenType.PATTERN; 23 import static android.platform.helpers.LockscreenUtils.LockscreenType.PIN; 24 import static android.platform.helpers.LockscreenUtils.LockscreenType.SWIPE; 25 import static android.platform.test.util.HealthTestingUtils.waitForCondition; 26 import static android.platform.uiautomatorhelpers.DeviceHelpers.getContext; 27 import static android.platform.uiautomatorhelpers.DeviceHelpers.getUiDevice; 28 import static android.platform.uiautomatorhelpers.DeviceHelpers.isScreenOnSettled; 29 import static android.platform.uiautomatorhelpers.WaitUtils.ensureThat; 30 31 import static com.google.common.truth.Truth.assertThat; 32 33 import android.app.KeyguardManager; 34 import android.content.ContentResolver; 35 import android.hardware.display.AmbientDisplayConfiguration; 36 import android.os.RemoteException; 37 import android.os.SystemClock; 38 import android.os.Trace; 39 import android.platform.helpers.LockscreenUtils; 40 import android.provider.Settings; 41 42 import org.junit.Assume; 43 44 import java.io.IOException; 45 46 /** Controller for manipulating lockscreen states. */ 47 public class LockscreenController { 48 private static final int SLEEP_INTERVAL_MS = 500; 49 50 private static final String FACE_WAKE_FAKE_COMMAND = 51 "am broadcast -a " 52 + "com.android.systemui.latency.ACTION_FACE_WAKE" 53 + " --user 0"; // Making sure broadcast receiver will receive the action 54 // if current user is different than System. 55 private static final String FINGERPRINT_WAKE_FAKE_COMMAND = 56 "am broadcast -a " 57 + "com.android.systemui.latency.ACTION_FINGERPRINT_WAKE" 58 + " --user 0"; // Making sure broadcast receiver will receive the action 59 60 // if current user is different than System. 61 62 /** Returns an instance of LockscreenController. */ get()63 public static LockscreenController get() { 64 return new LockscreenController(); 65 } 66 LockscreenController()67 private LockscreenController() {} 68 69 /** Enables unlocking via swipe */ setUnlockSwipe()70 public void setUnlockSwipe() { 71 LockscreenUtils.setLockscreen( 72 /* lockscreenType= */ SWIPE, /* lockscreenCode= */ "", /* expectedResult= */ false); 73 } 74 75 /** Enables no-lockscreen mode */ setNoLockScreenMode()76 public void setNoLockScreenMode() { 77 LockscreenUtils.setLockscreen( 78 /* lockscreenType= */ NONE, /* lockscreenCode= */ "", /* expectedResult= */ false); 79 } 80 81 /** Enables pin unlock */ setLockscreenPin(String pin)82 public void setLockscreenPin(String pin) { 83 LockscreenUtils.setLockscreen( 84 /* lockscreenType= */ PIN, /* lockscreenCode= */ pin, /* expectedResult= */ true); 85 } 86 87 /** Enables password unlock */ setLockscreenPassword(String password)88 public void setLockscreenPassword(String password) { 89 LockscreenUtils.setLockscreen( 90 /* lockscreenType= */ PASSWORD, 91 /* lockscreenCode= */ password, 92 /* expectedResult= */ true); 93 } 94 95 /** Enables pattern unlock */ setLockscreenPattern(String pattern)96 public void setLockscreenPattern(String pattern) { 97 LockscreenUtils.setLockscreen( 98 /* lockscreenType= */ PATTERN, 99 /* lockscreenCode= */ pattern, 100 /* expectedResult= */ true); 101 } 102 103 /** 104 * Enables or disables always-on display. 105 * 106 * @param enableAod Enable AOD? 107 * @return whether AOD was enabled. 108 */ setAodEnabled(boolean enableAod)109 public boolean setAodEnabled(boolean enableAod) { 110 return setSecureSetting( 111 Settings.Secure.DOZE_ALWAYS_ON, enableAod, false); 112 } 113 114 /** 115 * Enables or disables glanceale hub. 116 * 117 * @param enableHub Whether to enable glanceable hub? 118 * @return whether the hub was previously enabled before calling this method. 119 */ setGlanceableHubEnabled(boolean enableHub)120 public boolean setGlanceableHubEnabled(boolean enableHub) { 121 return setSecureSetting( 122 Settings.Secure.GLANCEABLE_HUB_ENABLED, enableHub, true); 123 } 124 setSecureSetting(String key, boolean value, boolean defaultValue)125 private boolean setSecureSetting(String key, boolean value, boolean defaultValue) { 126 final ContentResolver contentResolver = getContext().getContentResolver(); 127 final boolean previousValue = 128 Settings.Secure.getInt(contentResolver, key, defaultValue ? 1 : 0) == 1; 129 130 if (value != previousValue) { 131 assertThat( 132 Settings.Secure.putInt( 133 contentResolver, 134 key, 135 value ? 1 : 0)) 136 .isTrue(); 137 } 138 139 return previousValue; 140 } 141 142 /** Turns screen off by going to sleep. */ turnScreenOff()143 public void turnScreenOff() { 144 try { 145 getUiDevice().sleep(); 146 147 if (getUiDevice().isScreenOn()) { 148 SystemClock.sleep(SLEEP_INTERVAL_MS * 4); 149 waitForCondition(() -> "Screen didn't turn off", () -> !getUiDevice().isScreenOn()); 150 } 151 } catch (RemoteException e) { 152 throw new RuntimeException(e); 153 } 154 } 155 156 /** Turns screen on by waking up from sleep. */ turnScreenOn()157 public void turnScreenOn() { 158 Trace.beginSection("LockscreenController#turnScreenOn"); 159 try { 160 try { 161 getUiDevice().wakeUp(); 162 163 if (!getUiDevice().isScreenOn()) { 164 SystemClock.sleep(SLEEP_INTERVAL_MS * 4); 165 ensureThat("Screen is on", () -> isScreenOnSettled(getUiDevice())); 166 } 167 } catch (RemoteException e) { 168 throw new RuntimeException(e); 169 } 170 } finally { 171 Trace.endSection(); 172 } 173 } 174 175 /** Goes to the Locked screen page */ lockScreen()176 public void lockScreen() { 177 LockscreenUtils.goToLockScreen(); 178 } 179 180 /** 181 * Clears the lock credentials. 182 * 183 * @param currentLockscreenCode old code which is currently set. 184 */ clearLockCredentials(String currentLockscreenCode)185 public void clearLockCredentials(String currentLockscreenCode) { 186 LockscreenUtils.resetLockscreen(currentLockscreenCode); 187 } 188 189 /** Fake face unlock. */ fakeFaceUnlock()190 public void fakeFaceUnlock() { 191 try { 192 getUiDevice().executeShellCommand(FACE_WAKE_FAKE_COMMAND); 193 } catch (IOException e) { 194 throw new RuntimeException(e); 195 } 196 } 197 198 /** Fake fingerprint unlock. */ fakeFingerprintUnlock()199 public void fakeFingerprintUnlock() { 200 try { 201 getUiDevice().executeShellCommand(FINGERPRINT_WAKE_FAKE_COMMAND); 202 } catch (IOException e) { 203 throw new RuntimeException(e); 204 } 205 } 206 getKeyguardManager()207 private static KeyguardManager getKeyguardManager() { 208 return (KeyguardManager) getContext().getSystemService(KEYGUARD_SERVICE); 209 } 210 211 /** Checks whether the device supports AlwaysOnDisplay feature. */ skipIfDeviceDoesNotSupportAod()212 public static void skipIfDeviceDoesNotSupportAod() { 213 AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(getContext()); 214 Assume.assumeTrue( 215 "Device dose not support AOD, skipped test.", 216 config.alwaysOnAvailable() || getUiDevice().getProductName().startsWith("cf_x86")); 217 } 218 219 /** 220 * Returns whether the device is currently locked and requires a PIN, pattern or password to 221 * unlock. see [KeyguardManager.isDeviceLocked]. 222 */ isDeviceLocked()223 public boolean isDeviceLocked() { 224 return getKeyguardManager().isDeviceLocked(); 225 } 226 227 /** 228 * Returns whether the device is currently secured by a PIN, pattern or password. see 229 * [KeyguardManager.isDeviceSecure]. 230 */ isDeviceSecure()231 public boolean isDeviceSecure() { 232 return getKeyguardManager().isDeviceSecure(); 233 } 234 235 /** 236 * Returns whether the keyguard is currently locked. See [KeyguardManager.isKeyguardLocked]. 237 * Experimental. 238 */ isKeyguardLocked()239 public boolean isKeyguardLocked() { 240 return getKeyguardManager().isKeyguardLocked(); 241 } 242 } 243