• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.app.cts.wallpapers;
18 
19 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
20 
21 import android.app.UiAutomation;
22 import android.content.Context;
23 import android.hardware.display.DisplayManager;
24 import android.os.ParcelFileDescriptor;
25 import android.server.wm.UiDeviceUtils;
26 import android.server.wm.WindowManagerState;
27 import android.server.wm.WindowManagerStateHelper;
28 import android.view.Display;
29 
30 import androidx.test.platform.app.InstrumentationRegistry;
31 
32 import com.android.compatibility.common.util.TestUtils;
33 
34 import org.junit.Assume;
35 
36 import java.io.BufferedReader;
37 import java.io.FileDescriptor;
38 import java.io.FileReader;
39 import java.util.ArrayList;
40 import java.util.List;
41 
42 /**
43  * Utility class to check the status of the wallpaper windows.
44  * Includes tool to handle the keyguard state to check both home and lock screen wallpapers.
45  */
46 public class WallpaperWindowsTestUtils {
47     private static Context sContext;
48     private static DisplayManager sDisplayManager;
49     private static UiAutomation sUiAutomation;
50 
setContext(Context context)51     public static void setContext(Context context) {
52         sContext = context;
53         sDisplayManager = context.getSystemService(DisplayManager.class);
54         sUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
55     }
56 
57     public static class WallpaperWindowsHelper {
58         private final WindowManagerStateHelper mWmState;
59         private List<WindowManagerState.WindowState> mWallpaperWindows = new ArrayList<>();
60         private List<String> mPackageNames = new ArrayList<>();
61 
WallpaperWindowsHelper(WindowManagerStateHelper windowManagerStateHelper)62         public WallpaperWindowsHelper(WindowManagerStateHelper windowManagerStateHelper) {
63             mWmState = windowManagerStateHelper;
64         }
65 
showHomeScreenAndUpdate()66         public void showHomeScreenAndUpdate() throws Exception {
67             showHomeScreen(mWmState);
68             updateWindows();
69         }
70 
showLockScreenAndUpdate()71         public void showLockScreenAndUpdate() throws Exception {
72             showLockScreen();
73             updateWindows();
74         }
75 
dumpWindows()76         public String dumpWindows() {
77             StringBuilder msgWindows = new StringBuilder();
78             mWallpaperWindows.forEach(w -> msgWindows.append(w.toLongString()).append(", "));
79             return "[" + msgWindows + "]";
80         }
81 
dumpPackages()82         public String dumpPackages() {
83             StringBuilder msgWindows = new StringBuilder();
84             mPackageNames.forEach(p -> msgWindows.append(p).append(", "));
85             return "[" + msgWindows + "]";
86         }
87 
getAllWallpaperPackages()88         public List<String> getAllWallpaperPackages() {
89             return mPackageNames;
90         }
91 
92         /**
93          * Wait until the visibility of the window is the one expected,
94          * and return false if it does not happen within N iterations
95          */
waitForMatchingWindowVisibility(String name, boolean expectedVisibility)96         public boolean waitForMatchingWindowVisibility(String name,
97                 boolean expectedVisibility) {
98             return mWmState.waitFor(
99                     (wmState) -> checkMatchingWindowVisibility(name, expectedVisibility),
100                     "Visibility of " + name + " is not " + expectedVisibility);
101         }
102 
103         /**
104          * Wait until the packages of the wallpapers match exactly the expected ones,
105          * and return false if it does not happen within N iterations
106          */
waitForMatchingPackages(List<String> expected)107         public boolean waitForMatchingPackages(List<String> expected) {
108             return mWmState.waitFor(
109                     (wmState) -> checkMatchingPackages(expected),
110                     "Provided packages and observed ones do not match");
111         }
112 
checkMatchingWindowVisibility(String name, boolean expectedVisibility)113         private boolean checkMatchingWindowVisibility(String name, boolean expectedVisibility) {
114             updateWindows();
115             return mWallpaperWindows.stream().anyMatch(
116                     w -> w.getName().equals(name) && w.isSurfaceShown() == expectedVisibility);
117         }
118 
checkMatchingPackages(List<String> expected)119         private boolean checkMatchingPackages(List<String> expected) {
120             updateWindows();
121             if (expected.size() != mPackageNames.size()) {
122                 return false;
123             }
124             for (int i = 0; i < expected.size(); i++) {
125                 if (!expected.get(i).equals(mPackageNames.get(i))) {
126                     return false;
127                 }
128             }
129             return true;
130         }
131 
updateWindows()132         private void updateWindows() {
133             mWmState.waitForAppTransitionIdleOnDisplay(sContext.getDisplayId());
134             mWmState.computeState();
135             mWallpaperWindows = mWmState.getMatchingWindowType(TYPE_WALLPAPER);
136             mPackageNames = new ArrayList<>();
137             mWallpaperWindows.forEach(w -> mPackageNames.add(w.getPackageName()));
138         }
139     }
140 
runWithKeyguardEnabled(WindowManagerStateHelper wmState, Runnable runnable)141     public static void runWithKeyguardEnabled(WindowManagerStateHelper wmState,
142             Runnable runnable) throws Exception {
143         boolean isDisabled;
144         try (ParcelFileDescriptor parcelFileDescriptor = sUiAutomation.executeShellCommand(
145                 "locksettings get-disabled")) {
146             FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
147             BufferedReader reader = new BufferedReader(new FileReader(fileDescriptor));
148             isDisabled = "true".equals(reader.readLine());
149         }
150         try {
151             if (isDisabled) setKeyguardUnlockMethod(wmState, false);
152             runnable.run();
153         } finally {
154             if (isDisabled) setKeyguardUnlockMethod(wmState, true);
155         }
156     }
157 
setKeyguardUnlockMethod( WindowManagerStateHelper wmState, boolean setDisabled)158     private static void setKeyguardUnlockMethod(
159             WindowManagerStateHelper wmState, boolean setDisabled) throws Exception {
160         try {
161             sUiAutomation.executeShellCommand("locksettings clear");
162             sUiAutomation.executeShellCommand("locksettings set-disabled " + setDisabled);
163         } catch (IllegalArgumentException e) {
164             Assume.assumeNoException(e);
165         }
166         // Unlock device to make the changes effective from the next unlock
167         showHomeScreen(wmState);
168     }
169 
showLockScreen()170     private static void showLockScreen() throws Exception {
171         if (sDisplayManager == null) throw new Exception("No display");
172         Display display = sDisplayManager.getDisplay(sContext.getDisplayId());
173 
174         UiDeviceUtils.pressSleepButton();
175         TestUtils.waitUntil("display does not turn off", 5, () -> !isDisplayOn(display));
176         UiDeviceUtils.pressWakeupButton();
177         TestUtils.waitUntil("display does not turn on", 5, () -> isDisplayOn(display));
178     }
179 
showHomeScreen(WindowManagerStateHelper wmSH)180     private static void showHomeScreen(WindowManagerStateHelper wmSH) throws Exception {
181         showLockScreen();
182         UiDeviceUtils.pressUnlockButton();
183         wmSH.waitForKeyguardGone();
184     }
185 
isDisplayOn(Display display)186     private static boolean isDisplayOn(Display display) {
187         return display != null && display.getState() == Display.STATE_ON;
188     }
189 }
190