diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index fc9e5e2ef04e0..f9cdbd322c260 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -516,6 +516,25 @@ public final class AccessibilityManager { return mClient; } + /** + * Unregisters the IAccessibilityManagerClient from the backing service + * @hide + */ + public boolean removeClient() { + synchronized (mLock) { + IAccessibilityManager service = getServiceLocked(); + if (service == null) { + return false; + } + try { + return service.removeClient(mClient, mUserId); + } catch (RemoteException re) { + Log.e(LOG_TAG, "AccessibilityManagerService is dead", re); + } + } + return false; + } + /** * @hide */ diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index c71ea53c414d9..078ab25e8b6c8 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -42,6 +42,8 @@ interface IAccessibilityManager { long addClient(IAccessibilityManagerClient client, int userId); + boolean removeClient(IAccessibilityManagerClient client, int userId); + List getInstalledAccessibilityServiceList(int userId); @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java index 115c266aaae6d..212fdcace6ac8 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java @@ -115,6 +115,13 @@ public class AccessibilityManagerTest { return manager; } + @Test + public void testRemoveManager() throws Exception { + AccessibilityManager manager = createManager(WITH_A11Y_ENABLED); + manager.removeClient(); + verify(mMockService).removeClient(manager.getClient(), UserHandle.USER_CURRENT); + } + @Test public void testGetAccessibilityServiceList() throws Exception { // create a list of installed accessibility services the mock service returns diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 9abe00fba98c2..7eecc453a8ce8 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -709,6 +709,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } + @Override + public boolean removeClient(IAccessibilityManagerClient callback, int userId) { + // TODO(b/190216606): Add tracing for removeClient when implementation is the same in master + + synchronized (mLock) { + final int resolvedUserId = mSecurityPolicy + .resolveCallingUserIdEnforcingPermissionsLocked(userId); + + AccessibilityUserState userState = getUserStateLocked(resolvedUserId); + if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { + boolean unregistered = mGlobalClients.unregister(callback); + if (DEBUG) { + Slog.i(LOG_TAG, + "Removed global client for pid:" + Binder.getCallingPid() + "state: " + + unregistered); + } + return unregistered; + } else { + boolean unregistered = userState.mUserClients.unregister(callback); + if (DEBUG) { + Slog.i(LOG_TAG, "Removed user client for pid:" + Binder.getCallingPid() + + " and userId:" + resolvedUserId + "state: " + unregistered); + } + return unregistered; + } + } + } + @Override public void sendAccessibilityEvent(AccessibilityEvent event, int userId) { if (mTraceManager.isA11yTracingEnabled()) { @@ -3271,6 +3299,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub pw.println(); } mA11yWindowManager.dump(fd, pw, args); + pw.println("Global client list info:{"); + mGlobalClients.dump(pw, " Client list "); + pw.println(" Registered clients:{"); + for (int i = 0; i < mGlobalClients.getRegisteredCallbackCount(); i++) { + AccessibilityManagerService.Client client = (AccessibilityManagerService.Client) + mGlobalClients.getRegisteredCallbackCookie(i); + pw.append(Arrays.toString(client.mPackageNames)); + } } } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index df349c863128e..0fde0de59c076 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -51,6 +51,7 @@ import com.android.internal.accessibility.AccessibilityShortcutController; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -573,6 +574,15 @@ class AccessibilityUserState { pw.append(componentName.toShortString()); } } + pw.println("}"); + pw.println(" Client list info:{"); + mUserClients.dump(pw, " Client list "); + pw.println(" Registered clients:{"); + for (int i = 0; i < mUserClients.getRegisteredCallbackCount(); i++) { + AccessibilityManagerService.Client client = (AccessibilityManagerService.Client) + mUserClients.getRegisteredCallbackCookie(i); + pw.append(Arrays.toString(client.mPackageNames)); + } pw.println("}]"); }