OSDN Git Service

Fake accessibility service used by UiAutomation not destroyed.
authorSvetoslav <svetoslavganov@google.com>
Thu, 28 Feb 2013 02:24:28 +0000 (18:24 -0800)
committerSvetoslav <svetoslavganov@google.com>
Thu, 28 Feb 2013 02:32:17 +0000 (18:32 -0800)
UiAutomation registers a fake accessibility service to introspect
the screen. Upon the death of the shell process that started an
instrumentation in which a UiAutomation resides the connection
between the UiAutomation and the system is kept alive allowing
the instrumentation to introspect the screen even after the death
of the shell process.

bug:8285905

Change-Id: I1a16d78abbea032116c4baed175cfc0d5dedbf0c

core/java/android/app/UiAutomationConnection.java
core/java/android/view/accessibility/IAccessibilityManager.aidl
services/java/com/android/server/accessibility/AccessibilityManagerService.java

index 06ef472..97c7ff3 100644 (file)
@@ -49,6 +49,8 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
 
     private final Object mLock = new Object();
 
+    private final Binder mToken = new Binder();
+
     private int mInitialFrozenRotation = INITIAL_FROZEN_ROTATION_UNSPECIFIED;
 
     private IAccessibilityServiceClient mClient;
@@ -164,7 +166,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
         try {
             // Calling out with a lock held is fine since if the system
             // process is gone the client calling in will be killed.
-            manager.registerUiTestAutomationService(client, info);
+            manager.registerUiTestAutomationService(mToken, client, info);
             mClient = client;
         } catch (RemoteException re) {
             throw new IllegalStateException("Error while registering UiTestAutomationService.", re);
index c3ef54c..fe3e5c6 100644 (file)
@@ -50,7 +50,7 @@ interface IAccessibilityManager {
 
     void removeAccessibilityInteractionConnection(IWindow windowToken);
 
-    void registerUiTestAutomationService(IAccessibilityServiceClient client,
+    void registerUiTestAutomationService(IBinder owner, IAccessibilityServiceClient client,
         in AccessibilityServiceInfo info);
 
     void unregisterUiTestAutomationService(IAccessibilityServiceClient client);
index fd5e79a..0121f7a 100644 (file)
@@ -528,7 +528,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
         return -1;
     }
 
-    public void registerUiTestAutomationService(IAccessibilityServiceClient serviceClient,
+    public void registerUiTestAutomationService(IBinder owner, IAccessibilityServiceClient serviceClient,
             AccessibilityServiceInfo accessibilityServiceInfo) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
                 FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
@@ -543,6 +543,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
                         + "already registered!");
             }
 
+            try {
+                owner.linkToDeath(userState.mUiAutomationSerivceOnwerDeathRecipient, 0);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Couldn't register for the death of a"
+                        + " UiTestAutomationService!", re);
+                return;
+            }
+
+            userState.mUiAutomationServiceOwner = owner;
             userState.mUiAutomationServiceClient = serviceClient;
 
             // Set the temporary state.
@@ -1697,8 +1706,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
             if (!mIsAutomation) {
                 mContext.unbindService(this);
             } else {
-                userState.mUiAutomationService = null;
-                userState.mUiAutomationServiceClient = null;
+                userState.destroyUiAutomationService();
             }
             removeServiceLocked(this, userState);
             dispose();
@@ -2112,8 +2120,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
                     // the state based on values in the settings database.
                     userState.mInstalledServices.remove(mAccessibilityServiceInfo);
                     userState.mEnabledServices.remove(mComponentName);
-                    userState.mUiAutomationService = null;
-                    userState.mUiAutomationServiceClient = null;
+                    userState.destroyUiAutomationService();
                 }
                 onUserStateChangedLocked(userState);
             }
@@ -2606,6 +2613,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
         private Service mUiAutomationService;
         private IAccessibilityServiceClient mUiAutomationServiceClient;
 
+        private IBinder mUiAutomationServiceOwner;
+        private final DeathRecipient mUiAutomationSerivceOnwerDeathRecipient =
+                new DeathRecipient() {
+            @Override
+            public void binderDied() {
+                mUiAutomationServiceOwner.unlinkToDeath(
+                        mUiAutomationSerivceOnwerDeathRecipient, 0);
+                mUiAutomationServiceOwner = null;
+                if (mUiAutomationService != null) {
+                    mUiAutomationService.binderDied();
+                }
+            }
+        };
+
         public UserState(int userId) {
             mUserId = userId;
         }
@@ -2626,8 +2647,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
             // Clear UI test automation state.
             if (mUiAutomationService != null) {
                 mUiAutomationService.binderDied();
-                mUiAutomationService = null;
-                mUiAutomationServiceClient = null;
             }
 
             // Unbind all services.
@@ -2649,6 +2668,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
             mIsEnhancedWebAccessibilityEnabled = false;
             mIsDisplayMagnificationEnabled = false;
         }
+
+        public void destroyUiAutomationService() {
+            mUiAutomationService = null;
+            mUiAutomationServiceClient = null;
+            if (mUiAutomationServiceOwner != null) {
+                mUiAutomationServiceOwner.unlinkToDeath(
+                        mUiAutomationSerivceOnwerDeathRecipient, 0);
+                mUiAutomationServiceOwner = null;
+            }
+        }
     }
 
     private final class AccessibilityContentObserver extends ContentObserver {