UiAutomation supports new flag, FLAG_DO_NOT_USE_ACCESSIBILITY

UiAutomation should have an option not to engage accessibility.
go/uiautomation_not_use_a11y

Bug: 93087044
Test: atest UiAutomationManagerTest, atest CtsUiAutomationTestCases
Change-Id: Icc6c359844817a07869a18345fe44ef3b2813dae
This commit is contained in:
mincheli
2020-03-05 17:42:32 +08:00
parent 7532b2210d
commit 40c9baad6b
6 changed files with 135 additions and 69 deletions

View File

@@ -6532,6 +6532,7 @@ package android.app {
method public android.graphics.Bitmap takeScreenshot();
method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
field public static final int ROTATION_FREEZE_0 = 0; // 0x0
field public static final int ROTATION_FREEZE_180 = 2; // 0x2
field public static final int ROTATION_FREEZE_270 = 3; // 0x3

View File

@@ -97,7 +97,8 @@ public class Instrumentation {
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({0, UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES})
@IntDef({0, UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES,
UiAutomation.FLAG_DONT_USE_ACCESSIBILITY})
public @interface UiAutomationFlags {};
@@ -2170,7 +2171,8 @@ public class Instrumentation {
* </p>
*
* @param flags The flags to be passed to the UiAutomation, for example
* {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES}.
* {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES},
* {@link UiAutomation#FLAG_DONT_USE_ACCESSIBILITY}.
*
* @return The UI automation instance.
*

View File

@@ -56,6 +56,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.pooled.PooledLambda;
import libcore.io.IoUtils;
@@ -142,13 +143,22 @@ public final class UiAutomation {
}
/**
* UiAutomation supresses accessibility services by default. This flag specifies that
* UiAutomation suppresses accessibility services by default. This flag specifies that
* existing accessibility services should continue to run, and that new ones may start.
* This flag is set when obtaining the UiAutomation from
* {@link Instrumentation#getUiAutomation(int)}.
*/
public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 0x00000001;
/**
* UiAutomation uses the accessibility subsystem by default. This flag provides an option to
* eliminate the overhead of engaging the accessibility subsystem for tests that do not need to
* interact with the user interface. Setting this flag disables methods that rely on
* accessibility. This flag is set when obtaining the UiAutomation from
* {@link Instrumentation#getUiAutomation(int)}.
*/
public static final int FLAG_DONT_USE_ACCESSIBILITY = 0x00000002;
private final Object mLock = new Object();
private final ArrayList<AccessibilityEvent> mEventQueue = new ArrayList<AccessibilityEvent>();
@@ -267,11 +277,14 @@ public final class UiAutomation {
/**
* Connects this UiAutomation to the accessibility introspection APIs.
*
* @param flags Any flags to apply to the automation as it gets connected
* @param flags Any flags to apply to the automation as it gets connected while
* {@link UiAutomation#FLAG_DONT_USE_ACCESSIBILITY} would keep the
* connection disconnected and not to register UiAutomation service.
* @param timeoutMillis The wait timeout in milliseconds
*
* @throws IllegalStateException If the connection to the accessibility subsystem is already
* established.
* @throws TimeoutException If not connected within the timeout
*
* @hide
*/
public void connectWithTimeout(int flags, long timeoutMillis) throws TimeoutException {
@@ -292,6 +305,12 @@ public final class UiAutomation {
// Calling out without a lock held.
mUiAutomationConnection.connect(mClient, flags);
mFlags = flags;
// If UiAutomation is not allowed to use the accessibility subsystem, the
// connection state should keep disconnected and not to start the client connection.
if (!useAccessibility()) {
mConnectionState = ConnectionState.DISCONNECTED;
return;
}
} catch (RemoteException re) {
throw new RuntimeException("Error while connecting " + this, re);
}
@@ -340,7 +359,7 @@ public final class UiAutomation {
throw new IllegalStateException(
"Cannot call disconnect() while connecting " + this);
}
if (mConnectionState == ConnectionState.DISCONNECTED) {
if (useAccessibility() && mConnectionState == ConnectionState.DISCONNECTED) {
return;
}
mConnectionState = ConnectionState.DISCONNECTED;
@@ -354,8 +373,10 @@ public final class UiAutomation {
} catch (RemoteException re) {
throw new RuntimeException("Error while disconnecting " + this, re);
} finally {
mRemoteCallbackThread.quit();
mRemoteCallbackThread = null;
if (mRemoteCallbackThread != null) {
mRemoteCallbackThread.quit();
mRemoteCallbackThread = null;
}
}
}
@@ -389,9 +410,13 @@ public final class UiAutomation {
* The callbacks are delivered on the main application thread.
*
* @param listener The callback.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
synchronized (mLock) {
throwIfNotConnectedLocked();
mOnAccessibilityEventListener = listener;
}
}
@@ -423,9 +448,6 @@ public final class UiAutomation {
* @see #dropShellPermissionIdentity()
*/
public void adoptShellPermissionIdentity() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
// Calling out without a lock held.
mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), null);
@@ -451,9 +473,6 @@ public final class UiAutomation {
* @see #dropShellPermissionIdentity()
*/
public void adoptShellPermissionIdentity(@Nullable String... permissions) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
// Calling out without a lock held.
mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), permissions);
@@ -470,9 +489,6 @@ public final class UiAutomation {
* @see #adoptShellPermissionIdentity()
*/
public void dropShellPermissionIdentity() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
// Calling out without a lock held.
mUiAutomationConnection.dropShellPermissionIdentity();
@@ -489,6 +505,8 @@ public final class UiAutomation {
* @param action The action to perform.
* @return Whether the action was successfully performed.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_HOME
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
@@ -523,13 +541,18 @@ public final class UiAutomation {
* </p>
*
* @param focus The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
* {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
* {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
* @return The node info of the focused view or null.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see AccessibilityNodeInfo#FOCUS_INPUT
* @see AccessibilityNodeInfo#FOCUS_ACCESSIBILITY
*/
public AccessibilityNodeInfo findFocus(int focus) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
}
@@ -541,6 +564,8 @@ public final class UiAutomation {
*
* @return The accessibility service info.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see AccessibilityServiceInfo
*/
public final AccessibilityServiceInfo getServiceInfo() {
@@ -567,6 +592,8 @@ public final class UiAutomation {
*
* @param info The info.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see AccessibilityServiceInfo
*/
public final void setServiceInfo(AccessibilityServiceInfo info) {
@@ -602,6 +629,8 @@ public final class UiAutomation {
* </p>
*
* @return The windows if there are windows such, otherwise an empty list.
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
public List<AccessibilityWindowInfo> getWindows() {
final int connectionId;
@@ -630,6 +659,8 @@ public final class UiAutomation {
*
* @return The windows of all displays if there are windows and the service is can retrieve
* them, otherwise an empty list. The key of SparseArray is display ID.
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
@NonNull
public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
@@ -647,6 +678,8 @@ public final class UiAutomation {
* Gets the root {@link AccessibilityNodeInfo} in the active window.
*
* @return The root info.
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
public AccessibilityNodeInfo getRootInActiveWindow() {
final int connectionId;
@@ -664,14 +697,12 @@ public final class UiAutomation {
* <p>
* <strong>Note:</strong> It is caller's responsibility to recycle the event.
* </p>
*
* @param event The event to inject.
* @param sync Whether to inject the event synchronously.
* @return Whether event injection succeeded.
*/
public boolean injectInputEvent(InputEvent event, boolean sync) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
@@ -692,9 +723,6 @@ public final class UiAutomation {
*/
@TestApi
public void syncInputTransactions() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
// Calling out without a lock held.
mUiAutomationConnection.syncInputTransactions();
@@ -720,9 +748,6 @@ public final class UiAutomation {
* @see #ROTATION_UNFREEZE
*/
public boolean setRotation(int rotation) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
switch (rotation) {
case ROTATION_FREEZE_0:
case ROTATION_FREEZE_90:
@@ -752,11 +777,14 @@ public final class UiAutomation {
* <p>
* <strong>Note:</strong> It is caller's responsibility to recycle the returned event.
* </p>
*
* @param command The command to execute.
* @param filter Filter that recognizes the expected event.
* @param timeoutMillis The wait timeout in milliseconds.
*
* @throws TimeoutException If the expected event is not received within the timeout.
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
public AccessibilityEvent executeAndWaitForEvent(Runnable command,
AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
@@ -845,6 +873,8 @@ public final class UiAutomation {
*
* @throws TimeoutException If no idle state was detected within
* <code>globalTimeoutMillis.</code>
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
*/
public void waitForIdle(long idleTimeoutMillis, long globalTimeoutMillis)
throws TimeoutException {
@@ -874,9 +904,9 @@ public final class UiAutomation {
return;
}
try {
mLock.wait(remainingIdleTimeMillis);
mLock.wait(remainingIdleTimeMillis);
} catch (InterruptedException ie) {
/* ignore */
/* ignore */
}
}
}
@@ -888,9 +918,6 @@ public final class UiAutomation {
* @return The screenshot bitmap on success, null otherwise.
*/
public Bitmap takeScreenshot() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
Display display = DisplayManagerGlobal.getInstance()
.getRealDisplay(Display.DEFAULT_DISPLAY);
Point displaySize = new Point();
@@ -927,9 +954,6 @@ public final class UiAutomation {
* @see ActivityManager#isUserAMonkey()
*/
public void setRunAsMonkey(boolean enable) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
ActivityManager.getService().setUserIsMonkey(enable);
} catch (RemoteException re) {
@@ -946,6 +970,8 @@ public final class UiAutomation {
* @return Whether the window is present and its frame statistics
* were cleared.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see android.view.WindowContentFrameStats
* @see #getWindowContentFrameStats(int)
* @see #getWindows()
@@ -991,6 +1017,8 @@ public final class UiAutomation {
* @param windowId The window id.
* @return The window frame statistics, or null if the window is not present.
*
* @throws IllegalStateException If the connection to the accessibility subsystem is not
* established.
* @see android.view.WindowContentFrameStats
* @see #clearWindowContentFrameStats(int)
* @see #getWindows()
@@ -1022,9 +1050,6 @@ public final class UiAutomation {
* @see android.R.styleable#WindowAnimation
*/
public void clearWindowAnimationFrameStats() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Clearing window animation frame stats");
@@ -1064,9 +1089,6 @@ public final class UiAutomation {
* @see android.R.styleable#WindowAnimation
*/
public WindowAnimationFrameStats getWindowAnimationFrameStats() {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Getting window animation frame stats");
@@ -1081,6 +1103,7 @@ public final class UiAutomation {
/**
* Grants a runtime permission to a package.
*
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to grant the permission.
@@ -1104,15 +1127,13 @@ public final class UiAutomation {
/**
* Grants a runtime permission to a package for a user.
*
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to grant the permission.
*/
public void grantRuntimePermissionAsUser(String packageName, String permission,
UserHandle userHandle) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Granting runtime permission");
@@ -1127,6 +1148,7 @@ public final class UiAutomation {
/**
* Revokes a runtime permission from a package.
*
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to revoke the permission.
@@ -1150,15 +1172,13 @@ public final class UiAutomation {
/**
* Revokes a runtime permission from a package.
*
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to revoke the permission.
*/
public void revokeRuntimePermissionAsUser(String packageName, String permission,
UserHandle userHandle) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Revoking runtime permission");
@@ -1186,9 +1206,6 @@ public final class UiAutomation {
* @see #adoptShellPermissionIdentity()
*/
public ParcelFileDescriptor executeShellCommand(String command) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
warnIfBetterCommand(command);
ParcelFileDescriptor source = null;
@@ -1229,9 +1246,6 @@ public final class UiAutomation {
*/
@TestApi
public ParcelFileDescriptor[] executeShellCommandRw(String command) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
warnIfBetterCommand(command);
ParcelFileDescriptor source_read = null;
@@ -1276,15 +1290,21 @@ public final class UiAutomation {
return stringBuilder.toString();
}
@GuardedBy("mLock")
private void throwIfConnectedLocked() {
if (mConnectionState == ConnectionState.CONNECTED) {
throw new IllegalStateException("UiAutomation connected, " + this);
}
}
@GuardedBy("mLock")
private void throwIfNotConnectedLocked() {
if (mConnectionState != ConnectionState.CONNECTED) {
throw new IllegalStateException("UiAutomation not connected, " + this);
final String msg = useAccessibility()
? "UiAutomation not connected, "
: "UiAutomation not connected: Accessibility-dependent method called with "
+ "FLAG_DONT_USE_ACCESSIBILITY set, ";
throw new IllegalStateException(msg + this);
}
}
@@ -1298,11 +1318,16 @@ public final class UiAutomation {
}
}
private boolean useAccessibility() {
return (mFlags & UiAutomation.FLAG_DONT_USE_ACCESSIBILITY) == 0;
}
private class IAccessibilityServiceClientImpl extends IAccessibilityServiceClientWrapper {
public IAccessibilityServiceClientImpl(Looper looper, int generationId) {
super(null, looper, new Callbacks() {
private final int mGenerationId = generationId;
/**
* True if UiAutomation doesn't interact with this client anymore.
* Used by methods below to stop sending notifications or changing members

View File

@@ -6532,6 +6532,7 @@ package android.app {
method public android.graphics.Bitmap takeScreenshot();
method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
field public static final int ROTATION_FREEZE_0 = 0; // 0x0
field public static final int ROTATION_FREEZE_180 = 2; // 0x2
field public static final int ROTATION_FREEZE_270 = 3; // 0x3

View File

@@ -72,7 +72,8 @@ class UiAutomationManager {
};
/**
* Register a UiAutomation. Only one may be registered at a time.
* Register a UiAutomation if it uses the accessibility subsystem. Only one may be registered
* at a time.
*
* @param owner A binder object owned by the process that owns the UiAutomation to be
* registered.
@@ -80,6 +81,7 @@ class UiAutomationManager {
* @param accessibilityServiceInfo The UiAutomation's service info
* @param flags The UiAutomation's flags
* @param id The id for the service connection
* @see UiAutomation#FLAG_DONT_USE_ACCESSIBILITY
*/
void registerUiTestAutomationServiceLocked(IBinder owner,
IAccessibilityServiceClient serviceClient,
@@ -88,14 +90,15 @@ class UiAutomationManager {
AccessibilitySecurityPolicy securityPolicy,
AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
WindowManagerInternal windowManagerInternal,
SystemActionPerformer systemActionPerfomer,
SystemActionPerformer systemActionPerformer,
AccessibilityWindowManager awm, int flags) {
synchronized (mLock) {
accessibilityServiceInfo.setComponentName(COMPONENT_NAME);
if (mUiAutomationService != null) {
throw new IllegalStateException("UiAutomationService " + serviceClient
+ "already registered!");
throw new IllegalStateException(
"UiAutomationService " + mUiAutomationService.mServiceInterface
+ "already registered!");
}
try {
@@ -106,12 +109,17 @@ class UiAutomationManager {
return;
}
mUiAutomationFlags = flags;
mSystemSupport = systemSupport;
// Ignore registering UiAutomation if it is not allowed to use the accessibility
// subsystem.
if (!useAccessibility()) {
return;
}
mUiAutomationService = new UiAutomationService(context, accessibilityServiceInfo, id,
mainHandler, mLock, securityPolicy, systemSupport, windowManagerInternal,
systemActionPerfomer, awm);
systemActionPerformer, awm);
mUiAutomationServiceOwner = owner;
mUiAutomationFlags = flags;
mUiAutomationServiceInfo = accessibilityServiceInfo;
mUiAutomationService.mServiceInterface = serviceClient;
mUiAutomationService.onAdded();
@@ -130,15 +138,15 @@ class UiAutomationManager {
void unregisterUiTestAutomationServiceLocked(IAccessibilityServiceClient serviceClient) {
synchronized (mLock) {
if ((mUiAutomationService == null)
if (useAccessibility()
&& ((mUiAutomationService == null)
|| (serviceClient == null)
|| (mUiAutomationService.mServiceInterface == null)
|| (serviceClient.asBinder()
!= mUiAutomationService.mServiceInterface.asBinder())) {
!= mUiAutomationService.mServiceInterface.asBinder()))) {
throw new IllegalStateException("UiAutomationService " + serviceClient
+ " not registered!");
}
destroyUiAutomationService();
}
}
@@ -150,14 +158,19 @@ class UiAutomationManager {
}
boolean isUiAutomationRunningLocked() {
return (mUiAutomationService != null);
return (mUiAutomationService != null || !useAccessibility());
}
boolean suppressingAccessibilityServicesLocked() {
return (mUiAutomationService != null) && ((mUiAutomationFlags
return (mUiAutomationService != null || !useAccessibility())
&& ((mUiAutomationFlags
& UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0);
}
boolean useAccessibility() {
return ((mUiAutomationFlags & UiAutomation.FLAG_DONT_USE_ACCESSIBILITY) == 0);
}
boolean isTouchExplorationEnabledLocked() {
return (mUiAutomationService != null)
&& mUiAutomationService.mRequestTouchExplorationMode;
@@ -209,14 +222,14 @@ class UiAutomationManager {
mUiAutomationService.onRemoved();
mUiAutomationService.resetLocked();
mUiAutomationService = null;
mUiAutomationFlags = 0;
if (mUiAutomationServiceOwner != null) {
mUiAutomationServiceOwner.unlinkToDeath(
mUiAutomationServiceOwnerDeathRecipient, 0);
mUiAutomationServiceOwner = null;
}
mSystemSupport.onClientChangeLocked(false);
}
mUiAutomationFlags = 0;
mSystemSupport.onClientChangeLocked(false);
}
}
@@ -227,9 +240,9 @@ class UiAutomationManager {
int id, Handler mainHandler, Object lock,
AccessibilitySecurityPolicy securityPolicy,
SystemSupport systemSupport, WindowManagerInternal windowManagerInternal,
SystemActionPerformer systemActionPerfomer, AccessibilityWindowManager awm) {
SystemActionPerformer systemActionPerformer, AccessibilityWindowManager awm) {
super(context, COMPONENT_NAME, accessibilityServiceInfo, id, mainHandler, lock,
securityPolicy, systemSupport, windowManagerInternal, systemActionPerfomer,
securityPolicy, systemSupport, windowManagerInternal, systemActionPerformer,
awm);
mMainHandler = mainHandler;
}

View File

@@ -170,6 +170,30 @@ public class UiAutomationManagerTest {
verify(mMockSystemSupport).onClientChangeLocked(false);
}
@Test
public void uiAutomationWithDontUseAccessibilityFlagAfterUnregistering_notifiesSystem()
throws Exception {
register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
unregister();
verify(mMockSystemSupport).onClientChangeLocked(false);
}
@Test
public void uiAutomationWithDontUseAccessibilityFlag_disableAccessibilityFunctions()
throws Exception {
register(0);
assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
unregister();
assertFalse(mUiAutomationManager.isUiAutomationRunningLocked());
register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
assertFalse(mUiAutomationManager.useAccessibility());
assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
assertEquals(0, mUiAutomationManager.getRelevantEventTypes());
assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked());
}
private void register(int flags) {
mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner,
mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID,