1 package com.android.uiautomator.core; 2 3 import android.accessibilityservice.AccessibilityServiceInfo; 4 import android.app.ActivityManager; 5 import android.app.IActivityController; 6 import android.app.IActivityManager; 7 import android.app.UiAutomation; 8 import android.app.UiAutomationConnection; 9 import android.content.Intent; 10 import android.os.HandlerThread; 11 import android.os.RemoteException; 12 13 /** 14 * @hide 15 */ 16 public class UiAutomationShellWrapper { 17 18 private static final String HANDLER_THREAD_NAME = "UiAutomatorHandlerThread"; 19 20 private final HandlerThread mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME); 21 22 private UiAutomation mUiAutomation; 23 24 public void connect() { 25 if (mHandlerThread.isAlive()) { 26 throw new IllegalStateException("Already connected!"); 27 } 28 mHandlerThread.start(); 29 mUiAutomation = new UiAutomation(mHandlerThread.getLooper(), 30 new UiAutomationConnection()); 31 mUiAutomation.connect(); 32 } 33 34 /** 35 * Enable or disable monkey test mode. 36 * 37 * Setting test as "monkey" indicates to some applications that a test framework is 38 * running as a "monkey" type. Such applications may choose not to perform actions that 39 * do submits so to avoid allowing monkey tests from doing harm or performing annoying 40 * actions such as dialing 911 or posting messages to public forums, etc. 41 * 42 * @param isSet True to set as monkey test. False to set as regular functional test (default). 43 * @see ActivityManager#isUserAMonkey() 44 */ 45 public void setRunAsMonkey(boolean isSet) { 46 IActivityManager am = ActivityManager.getService(); 47 if (am == null) { 48 throw new RuntimeException("Can't manage monkey status; is the system running?"); 49 } 50 try { 51 if (isSet) { 52 am.setActivityController(new DummyActivityController(), true); 53 } else { 54 am.setActivityController(null, true); 55 } 56 } catch (RemoteException e) { 57 throw new RuntimeException(e); 58 } 59 } 60 61 public void disconnect() { 62 if (!mHandlerThread.isAlive()) { 63 throw new IllegalStateException("Already disconnected!"); 64 } 65 mUiAutomation.disconnect(); 66 mHandlerThread.quit(); 67 } 68 69 public UiAutomation getUiAutomation() { 70 return mUiAutomation; 71 } 72 73 public void setCompressedLayoutHierarchy(boolean compressed) { 74 AccessibilityServiceInfo info = mUiAutomation.getServiceInfo(); 75 if (compressed) 76 info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; 77 else 78 info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; 79 mUiAutomation.setServiceInfo(info); 80 } 81 82 /** 83 * Dummy, no interference, activity controller. 84 */ 85 private class DummyActivityController extends IActivityController.Stub { 86 @Override 87 public boolean activityStarting(Intent intent, String pkg) throws RemoteException { 88 /* do nothing and let activity proceed normally */ 89 return true; 90 } 91 92 @Override 93 public boolean activityResuming(String pkg) throws RemoteException { 94 /* do nothing and let activity proceed normally */ 95 return true; 96 } 97 98 @Override 99 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, 100 long timeMillis, String stackTrace) throws RemoteException { 101 /* do nothing and let activity proceed normally */ 102 return true; 103 } 104 105 @Override 106 public int appEarlyNotResponding(String processName, int pid, String annotation) 107 throws RemoteException { 108 /* do nothing and let activity proceed normally */ 109 return 0; 110 } 111 112 @Override 113 public int appNotResponding(String processName, int pid, String processStats) 114 throws RemoteException { 115 /* do nothing and let activity proceed normally */ 116 return 0; 117 } 118 119 @Override 120 public int systemNotResponding(String message) 121 throws RemoteException { 122 /* do nothing and let system proceed normally */ 123 return 0; 124 } 125 } 126 } 127