OSDN Git Service

Fix unbind a11y service fail
authorRhed Jao <rhedjao@google.com>
Tue, 2 Apr 2019 08:16:36 +0000 (16:16 +0800)
committerRhed Jao <rhedjao@google.com>
Tue, 2 Apr 2019 13:52:40 +0000 (21:52 +0800)
Bug: 128422953
Test: all a11y cts & framework tests
Change-Id: I391c81b97f73805f375fd3ab36759dfc826847ec

services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java

index 47cd917..d7e56c3 100644 (file)
@@ -4085,6 +4085,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
             return mBindingServices;
         }
 
+        /**
+         * Returns enabled service list.
+         */
+        public Set<ComponentName> getEnabledServicesLocked() {
+            return mEnabledServices;
+        }
+
         public int getSoftKeyboardShowMode() {
             return mSoftKeyboardShowMode;
         }
index 3bd6220..b66caa5 100644 (file)
@@ -123,12 +123,12 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
         synchronized (mLock) {
             UserState userState = mUserStateWeakReference.get();
             if (userState == null) return;
-            if (userState.mEnabledServices.remove(mComponentName)) {
+            if (userState.getEnabledServicesLocked().remove(mComponentName)) {
                 final long identity = Binder.clearCallingIdentity();
                 try {
                     mSystemSupport.persistComponentNamesToSettingLocked(
                             Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                            userState.mEnabledServices, userState.mUserId);
+                            userState.getEnabledServicesLocked(), userState.mUserId);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
@@ -183,6 +183,14 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
                 mWasConnectedAndDied = false;
                 serviceInterface = mServiceInterface;
             }
+            // There's a chance that service is removed from enabled_accessibility_services setting
+            // key, but skip unbinding because of it's in binding state. Unbinds it if it's
+            // not in enabled service list.
+            if (serviceInterface != null
+                    && !userState.getEnabledServicesLocked().contains(mComponentName)) {
+                mSystemSupport.onClientChangeLocked(false);
+                return;
+            }
         }
         if (serviceInterface == null) {
             binderDied();
index 2ed25ea..f336497 100644 (file)
@@ -23,10 +23,12 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceClient;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -46,6 +48,7 @@ import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 
 
@@ -149,4 +152,21 @@ public class AccessibilityServiceConnectionTest {
         assertTrue(mConnection.getServiceInfo().crashed);
         verify(mMockKeyEventDispatcher).flush(mConnection);
     }
+
+    @Test
+    public void connectedService_notInEnabledServiceList_doNotInitClient()
+            throws RemoteException {
+        IBinder mockBinder = mock(IBinder.class);
+        IAccessibilityServiceClient mockClient = mock(IAccessibilityServiceClient.class);
+        when(mockBinder.queryLocalInterface(any())).thenReturn(mockClient);
+        when(mMockUserState.getEnabledServicesLocked())
+                .thenReturn(Collections.emptySet());
+        setServiceBinding(COMPONENT_NAME);
+
+        mConnection.bindLocked();
+        mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+        mHandler.sendAllMessages();
+        verify(mMockSystemSupport, times(2)).onClientChangeLocked(false);
+        verify(mockClient, times(0)).init(any(), anyInt(), any());
+    }
 }