• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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