1 /* 2 * Copyright (C) 2020 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 com.android.server.wm.utils; 18 19 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 20 21 import android.app.Activity; 22 import android.app.KeyguardManager; 23 import android.app.UiAutomation; 24 import android.os.RemoteException; 25 import android.os.SystemClock; 26 import android.util.Log; 27 import android.view.IWindowManager; 28 import android.view.KeyEvent; 29 import android.view.WindowManagerGlobal; 30 31 import androidx.test.uiautomator.UiDevice; 32 33 import java.io.IOException; 34 35 /** Provides common utility functions. */ 36 public class CommonUtils { 37 private static final String TAG = "CommonUtils"; 38 private static final long REMOVAL_TIMEOUT_MS = 3000; 39 private static final long TIMEOUT_INTERVAL_MS = 200; 40 getUiAutomation()41 public static UiAutomation getUiAutomation() { 42 return getInstrumentation().getUiAutomation(); 43 } 44 runWithShellPermissionIdentity(Runnable runnable)45 public static void runWithShellPermissionIdentity(Runnable runnable) { 46 getUiAutomation().adoptShellPermissionIdentity(); 47 try { 48 runnable.run(); 49 } finally { 50 getUiAutomation().dropShellPermissionIdentity(); 51 } 52 } 53 getIgnoreOrientationRequest(int displayId)54 public static boolean getIgnoreOrientationRequest(int displayId) { 55 final UiDevice uiDevice = UiDevice.getInstance(getInstrumentation()); 56 final String result; 57 try { 58 result = uiDevice.executeShellCommand("cmd window get-ignore-orientation-request -d " 59 + displayId); 60 } catch (IOException e) { 61 throw new RuntimeException(e); 62 } 63 64 final String[] tokens = result.split(" "); 65 if (tokens.length != 4) { 66 throw new RuntimeException("Expecting a result with 4 tokens, but got " + result); 67 } 68 69 // The output looks like "ignoreOrientationRequest true for displayId=0" 70 return Boolean.parseBoolean(tokens[1]); 71 } 72 setIgnoreOrientationRequest( int displayId, boolean ignoreOrientationRequest)73 public static void setIgnoreOrientationRequest( 74 int displayId, boolean ignoreOrientationRequest) { 75 runWithShellPermissionIdentity(() -> { 76 final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 77 try { 78 wm.setIgnoreOrientationRequest(displayId, ignoreOrientationRequest); 79 } catch (RemoteException e) { 80 e.rethrowFromSystemServer(); 81 } 82 }); 83 } 84 85 /** Dismisses the Keyguard if it is locked. */ dismissKeyguard()86 public static void dismissKeyguard() { 87 final KeyguardManager keyguardManager = getInstrumentation().getContext().getSystemService( 88 KeyguardManager.class); 89 if (keyguardManager == null || !keyguardManager.isKeyguardLocked()) { 90 return; 91 } 92 final UiDevice device = UiDevice.getInstance(getInstrumentation()); 93 device.pressKeyCode(KeyEvent.KEYCODE_WAKEUP); 94 device.pressKeyCode(KeyEvent.KEYCODE_MENU); 95 } 96 waitUntilActivityRemoved(Activity activity)97 public static void waitUntilActivityRemoved(Activity activity) { 98 if (!activity.isFinishing()) { 99 activity.finish(); 100 } 101 final UiDevice uiDevice = UiDevice.getInstance(getInstrumentation()); 102 final String classPattern = activity.getComponentName().flattenToShortString(); 103 final long startTime = SystemClock.uptimeMillis(); 104 while (SystemClock.uptimeMillis() - startTime <= REMOVAL_TIMEOUT_MS) { 105 SystemClock.sleep(TIMEOUT_INTERVAL_MS); 106 final String windowTokenDump; 107 try { 108 windowTokenDump = uiDevice.executeShellCommand("dumpsys window tokens"); 109 } catch (IOException e) { 110 throw new RuntimeException(e); 111 } 112 if (!windowTokenDump.contains(classPattern)) { 113 return; 114 } 115 } 116 Log.i(TAG, "Removal timeout of " + classPattern); 117 } 118 } 119