diff options
| author | 2011-10-06 17:28:51 -0700 | |
|---|---|---|
| committer | 2011-10-06 17:28:51 -0700 | |
| commit | 31743d8cbbd0d54bfe8d2a43154a2b9615c8f282 (patch) | |
| tree | 8dc7310a4dc06d1e0b7acff0da62723e489fa653 | |
| parent | 3b88d87ef6107c91d99d6f44d68b1fafd973ffdc (diff) | |
| parent | b6eca6e6691d4563d8395b3c3843d9932a2a6560 (diff) | |
Merge "Accessibility test automation API not working."
| -rw-r--r-- | core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java | 227 | ||||
| -rw-r--r-- | services/java/com/android/server/accessibility/AccessibilityManagerService.java | 84 |
2 files changed, 136 insertions, 175 deletions
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java index cd8dcb973229..3521296713e1 100644 --- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java +++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java @@ -19,14 +19,10 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELE import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT; -import com.android.frameworks.coretests.R; - import android.content.Context; import android.graphics.Rect; -import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; -import android.provider.Settings; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; @@ -36,8 +32,8 @@ import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityManager; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; +import com.android.frameworks.coretests.R; + import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -55,14 +51,9 @@ public class InterrogationActivityTest private static String LOG_TAG = "InterrogationActivityTest"; - // Timeout before give up wait for the system to process an accessibility setting change. + // Timeout before give up wait for the system to process an accessibility setting change. private static final int TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING = 2000; - // Helpers to figure out the first and last test methods - // This is a workaround for the lack of such support in JUnit3 - private static int sTestMethodCount; - private static int sExecutedTestMethodCount; - // Handle to a connection to the AccessibilityManagerService private static IAccessibilityServiceConnection sConnection; @@ -71,19 +62,20 @@ public class InterrogationActivityTest public InterrogationActivityTest() { super(InterrogationActivity.class); - sTestMethodCount = getTestMethodCount(); } @LargeTest public void testFindAccessibilityNodeInfoByViewId() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertNotNull(button); assertEquals(0, button.getChildCount()); @@ -116,7 +108,6 @@ public class InterrogationActivityTest assertEquals(ACTION_FOCUS | ACTION_SELECT | ACTION_CLEAR_SELECTION, button.getActions()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewId: " @@ -127,18 +118,19 @@ public class InterrogationActivityTest @LargeTest public void testFindAccessibilityNodeInfoByViewText() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view by text List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), "butto"); + .findAccessibilityNodeInfosByViewTextInActiveWindow(connection, "butto"); assertEquals(9, buttons.size()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewText: " @@ -149,19 +141,20 @@ public class InterrogationActivityTest @LargeTest public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view by text List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), + .findAccessibilityNodeInfosByViewTextInActiveWindow(connection, "contentDescription"); assertEquals(1, buttons.size()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: " @@ -172,9 +165,11 @@ public class InterrogationActivityTest @LargeTest public void testTraverseAllViews() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); @@ -195,7 +190,7 @@ public class InterrogationActivityTest classNameAndTextList.add("android.widget.ButtonButton9"); AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.root); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.root); assertNotNull("We must find the existing root.", root); Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>(); @@ -221,7 +216,6 @@ public class InterrogationActivityTest } } } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testTraverseAllViews: " + elapsedTimeMillis + "ms"); @@ -231,15 +225,17 @@ public class InterrogationActivityTest @LargeTest public void testPerformAccessibilityActionFocus() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view and make sure it is not focused AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isFocused()); // focus the view @@ -247,10 +243,9 @@ public class InterrogationActivityTest // find the view again and make sure it is focused button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertTrue(button.isFocused()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testPerformAccessibilityActionFocus: " + elapsedTimeMillis + "ms"); @@ -260,15 +255,17 @@ public class InterrogationActivityTest @LargeTest public void testPerformAccessibilityActionClearFocus() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view and make sure it is not focused AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isFocused()); // focus the view @@ -276,7 +273,7 @@ public class InterrogationActivityTest // find the view again and make sure it is focused button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertTrue(button.isFocused()); // unfocus the view @@ -284,10 +281,9 @@ public class InterrogationActivityTest // find the view again and make sure it is not focused button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isFocused()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testPerformAccessibilityActionClearFocus: " @@ -298,15 +294,17 @@ public class InterrogationActivityTest @LargeTest public void testPerformAccessibilityActionSelect() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view and make sure it is not selected AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isSelected()); // select the view @@ -314,10 +312,9 @@ public class InterrogationActivityTest // find the view again and make sure it is selected button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertTrue(button.isSelected()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testPerformAccessibilityActionSelect: " + elapsedTimeMillis + "ms"); @@ -327,15 +324,17 @@ public class InterrogationActivityTest @LargeTest public void testPerformAccessibilityActionClearSelection() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view and make sure it is not selected AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isSelected()); // select the view @@ -343,7 +342,7 @@ public class InterrogationActivityTest // find the view again and make sure it is selected button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertTrue(button.isSelected()); // unselect the view @@ -351,10 +350,9 @@ public class InterrogationActivityTest // find the view again and make sure it is not selected button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isSelected()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testPerformAccessibilityActionClearSelection: " @@ -365,15 +363,17 @@ public class InterrogationActivityTest @LargeTest public void testAccessibilityEventGetSource() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity - getActivity(); + getActivity(); // find a view and make sure it is not focused AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); assertFalse(button.isSelected()); // focus the view @@ -419,7 +419,6 @@ public class InterrogationActivityTest assertSame(button.isCheckable(), source.isCheckable()); assertSame(button.isChecked(), source.isChecked()); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testAccessibilityEventGetSource: " + elapsedTimeMillis + "ms"); @@ -429,15 +428,17 @@ public class InterrogationActivityTest @LargeTest public void testObjectContract() throws Exception { - beforeClassIfNeeded(); final long startTimeMillis = SystemClock.uptimeMillis(); try { + // hook into the system first + IAccessibilityServiceConnection connection = getConnection(); + // bring up the activity getActivity(); // find a view and make sure it is not focused AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance() - .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5); + .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5); AccessibilityNodeInfo parent = button.getParent(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { @@ -451,7 +452,6 @@ public class InterrogationActivityTest } fail("Parent's children do not have the info whose parent is the parent."); } finally { - afterClassIfNeeded(); if (DEBUG) { final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; Log.i(LOG_TAG, "testObjectContract: " + elapsedTimeMillis + "ms"); @@ -464,90 +464,10 @@ public class InterrogationActivityTest /* intentionally do not scrub */ } - /** - * Sets accessibility in a given state by writing the state to the - * settings and waiting until the accessibility manager service picks - * it up for max {@link #TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING}. - * - * @param state The accessibility state. - * @throws Exception If any error occurs. - */ - private void ensureAccessibilityState(boolean state) throws Exception { - Context context = getInstrumentation().getContext(); - // If the local manager ready => nothing to do. - AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(context); - if (accessibilityManager.isEnabled() == state) { - return; - } - synchronized (this) { - // Check if the system already knows about the desired state. - final boolean currentState = Settings.Secure.getInt(context.getContentResolver(), - Settings.Secure.ACCESSIBILITY_ENABLED) == 1; - if (currentState != state) { - // Make sure we wake ourselves as the desired state is propagated. - accessibilityManager.addAccessibilityStateChangeListener( - new AccessibilityManager.AccessibilityStateChangeListener() { - public void onAccessibilityStateChanged(boolean enabled) { - synchronized (this) { - notifyAll(); - } - } - }); - Settings.Secure.putInt(context.getContentResolver(), - Settings.Secure.ACCESSIBILITY_ENABLED, state ? 1 : 0); - } - // No while one attempt and that is it. - try { - wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING); - } catch (InterruptedException ie) { - /* ignore */ - } - } - if (accessibilityManager.isEnabled() != state) { - throw new IllegalStateException("Could not set accessibility state to: " + state); - } - } - - /** - * Execute some set up code before any test method. - * - * NOTE: I miss Junit4's @BeforeClass - * - * @throws Exception If an error occurs. - */ - private void beforeClassIfNeeded() throws Exception { - sExecutedTestMethodCount++; - if (sExecutedTestMethodCount == 1) { - ensureAccessibilityState(true); - } - } - - /** - * Execute some clean up code after all test methods. - * - * NOTE: I miss Junit4's @AfterClass - * - * @throws Exception If an error occurs. - */ - public void afterClassIfNeeded() throws Exception { - if (sExecutedTestMethodCount == sTestMethodCount) { - sExecutedTestMethodCount = 0; - ensureAccessibilityState(false); - } - } - - private static IAccessibilityServiceConnection getConnection() throws Exception { + private IAccessibilityServiceConnection getConnection() throws Exception { if (sConnection == null) { IEventListener listener = new IEventListener.Stub() { - public void setConnection(IAccessibilityServiceConnection connection) - throws RemoteException { - AccessibilityServiceInfo info = new AccessibilityServiceInfo(); - info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; - info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; - info.notificationTimeout = 0; - info.flags = AccessibilityServiceInfo.DEFAULT; - connection.setServiceInfo(info); - } + public void setConnection(IAccessibilityServiceConnection connection) {} public void onInterrupt() {} @@ -560,26 +480,33 @@ public class InterrogationActivityTest } } }; - IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface( - ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)); - sConnection = manager.registerEventListener(listener); - } - return sConnection; - } - /** - * @return The number of test methods. - */ - private int getTestMethodCount() { - int testMethodCount = 0; - for (Method method : getClass().getMethods()) { - final int modifiers = method.getModifiers(); - if (method.getName().startsWith("test") - && (modifiers & Modifier.PUBLIC) != 0 - && (modifiers & Modifier.STATIC) == 0) { - testMethodCount++; + AccessibilityManager accessibilityManager = + AccessibilityManager.getInstance(getInstrumentation().getContext()); + + synchronized (this) { + if (!accessibilityManager.isEnabled()) { + // Make sure we wake ourselves as the desired state is propagated. + accessibilityManager.addAccessibilityStateChangeListener( + new AccessibilityManager.AccessibilityStateChangeListener() { + public void onAccessibilityStateChanged(boolean enabled) { + synchronized (this) { + notifyAll(); + } + } + }); + IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface( + ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)); + sConnection = manager.registerEventListener(listener); + + wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING); + } else { + IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface( + ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)); + sConnection = manager.registerEventListener(listener); + } } } - return testMethodCount; + return sConnection; } } diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index ed8fa40f9dc3..fd528cce8490 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -298,16 +298,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub super.onChange(selfChange); synchronized (mLock) { - mIsAccessibilityEnabled = Settings.Secure.getInt( - mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; - if (mIsAccessibilityEnabled) { - manageServicesLocked(); - } else { - unbindAllServicesLocked(); - } - updateInputFilterLocked(); - sendStateToClientsLocked(); + handleAccessibilityEnabledSettingChangedLocked(); } } }); @@ -354,6 +345,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub client.asBinder().linkToDeath(new DeathRecipient() { public void binderDied() { synchronized (mLock) { + addedClient.asBinder().unlinkToDeath(this, 0); mClients.remove(addedClient); } } @@ -445,10 +437,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub IAccessibilityInteractionConnection connection) throws RemoteException { synchronized (mLock) { final IWindow addedWindowToken = windowToken; + final IAccessibilityInteractionConnection addedConnection = connection; final int windowId = sNextWindowId++; - connection.asBinder().linkToDeath(new DeathRecipient() { + addedConnection.asBinder().linkToDeath(new DeathRecipient() { public void binderDied() { synchronized (mLock) { + addedConnection.asBinder().unlinkToDeath(this, 0); removeAccessibilityInteractionConnection(addedWindowToken); } } @@ -485,21 +479,23 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub ComponentName componentName = new ComponentName("foo.bar", "AutomationAccessibilityService"); synchronized (mLock) { - Service oldService = mComponentNameToServiceMap.get(componentName); - if (oldService != null) { - tryRemoveServiceLocked(oldService); + // If an automation services is connected to the system all services are stopped + // so the automation one is the only one running. Settings are not changed so when + // the automation service goes away the state is restored from the settings. + + // Disable all services. + final int runningServiceCount = mServices.size(); + for (int i = 0; i < runningServiceCount; i++) { + Service runningService = mServices.get(i); + runningService.unbind(); + } + // If necessary enable accessibility and announce that. + if (!mIsAccessibilityEnabled) { + mIsAccessibilityEnabled = true; + sendStateToClientsLocked(); } - // Now this service is enabled. - mEnabledServices.add(componentName); - // Also make sure this service is the only one. - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, - componentName.flattenToString()); - // This API is intended for testing so enable accessibility to make - // sure clients can start poking with the window content. - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_ENABLED, 1); } + // Hook the automation service up. AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; @@ -717,11 +713,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * Manages services by starting enabled ones and stopping disabled ones. */ private void manageServicesLocked() { + unbindAutomationService(); populateEnabledServicesLocked(mEnabledServices); final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices, mEnabledServices); // No enabled installed services => disable accessibility to avoid - // sending accessibility events with no recipient across processes. + // sending accessibility events with no recipient across processes. if (mIsAccessibilityEnabled && enabledInstalledServicesCount == 0) { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 0); @@ -744,6 +741,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } /** + * Unbinds the automation service if such is running. + */ + private void unbindAutomationService() { + List<Service> runningServices = mServices; + int runningServiceCount = mServices.size(); + for (int i = 0; i < runningServiceCount; i++) { + Service service = runningServices.get(i); + if (service.mIsAutomation) { + service.unbind(); + return; + } + } + } + + /** * Populates a list with the {@link ComponentName}s of all enabled * {@link AccessibilityService}s. * @@ -868,6 +880,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } /** + * Updated the state based on the accessibility enabled setting. + */ + private void handleAccessibilityEnabledSettingChangedLocked() { + mIsAccessibilityEnabled = Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; + if (mIsAccessibilityEnabled) { + manageServicesLocked(); + } else { + unbindAllServicesLocked(); + } + updateInputFilterLocked(); + sendStateToClientsLocked(); + } + + /** * This class represents an accessibility service. It stores all per service * data required for the service management, provides API for starting/stopping the * service and is responsible for adding/removing the service in the data structures @@ -1171,7 +1199,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public void binderDied() { synchronized (mLock) { + mService.unlinkToDeath(this, 0); tryRemoveServiceLocked(this); + // We no longer have an automation service, so restore + // the state based on values in the settings database. + if (mIsAutomation) { + handleAccessibilityEnabledSettingChangedLocked(); + } } } |