diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 19a91a67705fb..13ceb4adfcdd0 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -23,7 +23,6 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; -import android.os.SystemClock; import android.util.Log; import android.view.KeyEvent; import android.view.accessibility.AccessibilityEvent; @@ -659,16 +658,12 @@ public abstract class AccessibilityService extends Service { */ public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub implements HandlerCaller.Callback { - - static final int NO_ID = -1; - private static final int DO_SET_SET_CONNECTION = 1; private static final int DO_ON_INTERRUPT = 2; private static final int DO_ON_ACCESSIBILITY_EVENT = 3; private static final int DO_ON_GESTURE = 4; private static final int DO_CLEAR_ACCESSIBILITY_CACHE = 5; private static final int DO_ON_KEY_EVENT = 6; - private static final int DO_ON_WINDOWS_CHANGED = 7; private final HandlerCaller mCaller; @@ -714,12 +709,6 @@ public abstract class AccessibilityService extends Service { mCaller.sendMessage(message); } - @Override - public void onWindowsChanged(int[] windowIds) { - Message message = mCaller.obtainMessageO(DO_ON_WINDOWS_CHANGED, windowIds); - mCaller.sendMessage(message); - } - @Override public void executeMessage(Message message) { switch (message.what) { @@ -791,31 +780,6 @@ public abstract class AccessibilityService extends Service { } } return; - case DO_ON_WINDOWS_CHANGED: { - final int[] windowIds = (int[]) message.obj; - - // Update the cached windows first. - // NOTE: The cache will hold on to the windows so do not recycle. - if (windowIds != null) { - AccessibilityInteractionClient.getInstance().removeWindows(windowIds); - } - - // Let the client know the windows changed. - AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_WINDOWS_CHANGED); - event.setEventTime(SystemClock.uptimeMillis()); - event.setSealed(true); - - mCallback.onAccessibilityEvent(event); - - // Make sure the event is recycled. - try { - event.recycle(); - } catch (IllegalStateException ise) { - /* ignore - best effort */ - } - } break; - default : Log.w(LOG_TAG, "Unknown message type " + message.what); } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl index edd872712eb33..6ce0219b81f57 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl @@ -39,6 +39,4 @@ import android.view.KeyEvent; void clearAccessibilityCache(); void onKeyEvent(in KeyEvent event, int sequence); - - void onWindowsChanged(in int[] changedWindowIds); } diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java index f796587e8cee0..4f342315504fd 100644 --- a/core/java/android/view/accessibility/AccessibilityCache.java +++ b/core/java/android/view/accessibility/AccessibilityCache.java @@ -58,20 +58,18 @@ final class AccessibilityCache { } } - public void removeWindows(int[] windowIds) { + public void clearWindows() { synchronized (mLock) { - final int windowCount = windowIds.length; - for (int i = 0; i < windowCount; i++) { - final int windowId = windowIds[i]; - AccessibilityWindowInfo window = mWindowCache.get(windowId); + final int windowCount = mWindowCache.size(); + for (int i = windowCount - 1; i >= 0; i--) { + AccessibilityWindowInfo window = mWindowCache.valueAt(i); if (window != null) { if (DEBUG) { - Log.i(LOG_TAG, "Removing window: " + windowId); + Log.i(LOG_TAG, "Removing window: " + window.getId()); } window.recycle(); - mWindowCache.remove(windowId); + mWindowCache.removeAt(i); } - clearNodesForWindowLocked(windowIds[i]); } } } @@ -111,6 +109,10 @@ final class AccessibilityCache { case AccessibilityEvent.TYPE_VIEW_SCROLLED: { clearSubTreeLocked(event.getWindowId(), event.getSourceNodeId()); } break; + + case AccessibilityEvent.TYPE_WINDOWS_CHANGED: { + clearWindows(); + } break; } } diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 4748402f41ffc..db78ec5776c24 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -84,7 +84,7 @@ public final class AccessibilityInteractionClient private static final Object sStaticLock = new Object(); private static final LongSparseArray sClients = - new LongSparseArray(); + new LongSparseArray<>(); private final AtomicInteger mInteractionIdCounter = new AtomicInteger(); @@ -101,7 +101,7 @@ public final class AccessibilityInteractionClient private Message mSameThreadMessage; private static final SparseArray sConnectionCache = - new SparseArray(); + new SparseArray<>(); private static final AccessibilityCache sAccessibilityCache = new AccessibilityCache(); @@ -162,19 +162,6 @@ public final class AccessibilityInteractionClient false, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS); } - /** - * Gets the root {@link AccessibilityNodeInfo} in a given window. - * - * @param connectionId The id of a connection for interacting with the system. - * @param windowId The window id. - * @return The root {@link AccessibilityNodeInfo} if found, null otherwise. - */ - public AccessibilityNodeInfo getRootInWindow(int connectionId, int windowId) { - return findAccessibilityNodeInfoByAccessibilityId(connectionId, windowId, - AccessibilityNodeInfo.ROOT_NODE_ID, false, - AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS); - } - /** * Gets the info for a window. * @@ -225,11 +212,17 @@ public final class AccessibilityInteractionClient try { IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { - // The system is just sending data for windows that we introspected - // and changed but not ones that appeared, so we have to always call - // into the system process. This is less expensice as opposed to - // sending all windows on every window change. - List windows = connection.getWindows(); + List windows = sAccessibilityCache.getWindows(); + if (windows != null) { + if (DEBUG) { + Log.i(LOG_TAG, "Windows cache hit"); + } + return windows; + } + if (DEBUG) { + Log.i(LOG_TAG, "Windows cache miss"); + } + windows = connection.getWindows(); if (windows != null) { final int windowCount = windows.size(); for (int i = 0; i < windowCount; i++) { @@ -534,10 +527,6 @@ public final class AccessibilityInteractionClient sAccessibilityCache.onAccessibilityEvent(event); } - public void removeWindows(int[] windowIds) { - sAccessibilityCache.removeWindows(windowIds); - } - /** * Gets the the result of an async request that returns an {@link AccessibilityNodeInfo}. * @@ -603,8 +592,7 @@ public final class AccessibilityInteractionClient // instantiate new result list to avoid passing internal instances to clients. final boolean isIpcCall = (Binder.getCallingPid() != Process.myPid()); if (!isIpcCall) { - mFindAccessibilityNodeInfosResult = - new ArrayList(infos); + mFindAccessibilityNodeInfosResult = new ArrayList<>(infos); } else { mFindAccessibilityNodeInfosResult = infos; } @@ -795,8 +783,8 @@ public final class AccessibilityInteractionClient Log.e(LOG_TAG, "No root."); } // Check for duplicates. - HashSet seen = new HashSet(); - Queue fringe = new LinkedList(); + HashSet seen = new HashSet<>(); + Queue fringe = new LinkedList<>(); fringe.add(root); while (!fringe.isEmpty()) { AccessibilityNodeInfo current = fringe.poll(); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 07bb713841758..b1f19540060c1 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -62,7 +62,6 @@ import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; -import android.util.LongArray; import android.util.Pools.Pool; import android.util.Pools.SimplePool; import android.util.Slog; @@ -114,8 +113,6 @@ import java.util.concurrent.CopyOnWriteArrayList; * accessed only by the system. The task of this service is to be a centralized * event dispatch for {@link AccessibilityEvent}s generated across all processes * on the device. Events are dispatched to {@link AccessibilityService}s. - * - * @hide */ public class AccessibilityManagerService extends IAccessibilityManager.Stub { @@ -155,13 +152,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final Object mLock = new Object(); private final Pool mPendingEventPool = - new SimplePool(MAX_POOL_SIZE); + new SimplePool<>(MAX_POOL_SIZE); private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); private final List mEnabledServicesForFeedbackTempList = - new ArrayList(); + new ArrayList<>(); private final Rect mTempRect = new Rect(); @@ -183,27 +180,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private boolean mHasInputFilter; - private final Set mTempComponentNameSet = new HashSet(); + private final Set mTempComponentNameSet = new HashSet<>(); private final List mTempAccessibilityServiceInfoList = - new ArrayList(); + new ArrayList<>(); private final RemoteCallbackList mGlobalClients = - new RemoteCallbackList(); + new RemoteCallbackList<>(); private final SparseArray mGlobalInteractionConnections = - new SparseArray(); + new SparseArray<>(); - private final SparseArray mGlobalWindowTokens = new SparseArray(); + private final SparseArray mGlobalWindowTokens = new SparseArray<>(); - private final SparseArray mUserStates = new SparseArray(); + private final SparseArray mUserStates = new SparseArray<>(); private final UserManager mUserManager; private int mCurrentUserId = UserHandle.USER_OWNER; - private final LongArray mTempLongArray = new LongArray(); - //TODO: Remove this hack private boolean mInitialized; @@ -439,10 +434,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // to clients as being installed - it really is not. UserState userState = getUserStateLocked(resolvedUserId); if (userState.mUiAutomationService != null) { - List installedServices = - new ArrayList(); + List installedServices = new ArrayList<>(); installedServices.addAll(userState.mInstalledServices); - installedServices.remove(userState.mUiAutomationService); + installedServices.remove(userState.mUiAutomationService.mAccessibilityServiceInfo); return installedServices; } return userState.mInstalledServices; @@ -655,7 +649,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // Automation service is not bound, so pretend it died to perform clean up. if (userState.mUiAutomationService != null && serviceClient != null - && userState.mUiAutomationService != null && userState.mUiAutomationService.mServiceInterface != null && userState.mUiAutomationService.mServiceInterface.asBinder() == serviceClient.asBinder()) { @@ -907,16 +900,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } - private void notifyWindowsChangedLocked(List windows) { - UserState state = getCurrentUserStateLocked(); - for (int i = state.mBoundServices.size() - 1; i >= 0; i--) { - Service service = state.mBoundServices.get(i); - if (mSecurityPolicy.canRetrieveWindowsLocked(service)) { - service.notifyWindowsChangedLocked(windows); - } - } - } - /** * Removes an AccessibilityInteractionConnection. * @@ -961,10 +944,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { try { accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext); mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo); - } catch (XmlPullParserException xppe) { + } catch (XmlPullParserException | IOException xppe) { Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe); - } catch (IOException ioe) { - Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", ioe); } } @@ -1035,7 +1016,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // An out of bounds exception can happen if services are going away // as the for loop is running. If that happens, just bail because // there are no more services to notify. - return; } } @@ -1053,7 +1033,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { * Removes a service. * * @param service The service. - * @return True if the service was removed, false otherwise. */ private void removeServiceLocked(Service service, UserState userState) { userState.mBoundServices.remove(service); @@ -1093,7 +1072,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } Set packageNames = service.mPackageNames; - CharSequence packageName = event.getPackageName(); + String packageName = (event.getPackageName() != null) + ? event.getPackageName().toString() : null; if (packageNames.isEmpty() || packageNames.contains(packageName)) { int feedbackType = service.mFeedbackType; @@ -1386,8 +1366,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (mWindowsForAccessibilityCallback != null) { mWindowsForAccessibilityCallback = null; - mWindowManagerService.setWindowsForAccessibilityCallback( - mWindowsForAccessibilityCallback); + mWindowManagerService.setWindowsForAccessibilityCallback(null); } } @@ -1437,8 +1416,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } private boolean readConfigurationForUserStateLocked(UserState userState) { - boolean somthingChanged = false; - somthingChanged |= readAccessibilityEnabledSettingLocked(userState); + boolean somthingChanged = readAccessibilityEnabledSettingLocked(userState); somthingChanged |= readInstalledAccessibilityServiceLocked(userState); somthingChanged |= readEnabledAccessibilityServicesLocked(userState); somthingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState); @@ -1868,7 +1846,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { int mFeedbackType; - Set mPackageNames = new HashSet(); + Set mPackageNames = new HashSet<>(); boolean mIsDefault; @@ -1890,20 +1868,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { boolean mIsAutomation; - final Rect mTempBounds1 = new Rect(); - - final Rect mTempBounds2 = new Rect(); - final ResolveInfo mResolveInfo; // the events pending events to be dispatched to this service final SparseArray mPendingEvents = - new SparseArray(); + new SparseArray<>(); final KeyEventDispatcher mKeyEventDispatcher = new KeyEventDispatcher(); final SparseArray mIntrospectedWindows = - new SparseArray(); + new SparseArray<>(); boolean mWasConnectedAndDied; @@ -2106,7 +2080,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (!permissionGranted) { return null; } - List windows = new ArrayList(); + List windows = new ArrayList<>(); final int windowCount = mSecurityPolicy.mWindows.size(); for (int i = 0; i < windowCount; i++) { AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(i); @@ -2646,51 +2620,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } - public void notifyWindowsChangedLocked(List windows) { - LongArray changedWindows = mTempLongArray; - changedWindows.clear(); - - // Figure out which windows the service cares about changed. - final int windowCount = windows.size(); - for (int i = 0; i < windowCount; i++) { - AccessibilityWindowInfo newState = windows.get(i); - final int windowId = newState.getId(); - AccessibilityWindowInfo oldState = mIntrospectedWindows.get(windowId); - if (oldState != null && oldState.changed(newState)) { - oldState.recycle(); - mIntrospectedWindows.put(newState.getId(), - AccessibilityWindowInfo.obtain(newState)); - changedWindows.add(windowId); - } - } - - // Figure out which windows the service cares about went away. - final int introspectedWindowCount = mIntrospectedWindows.size(); - for (int i = introspectedWindowCount - 1; i >= 0; i--) { - AccessibilityWindowInfo window = mIntrospectedWindows.valueAt(i); - if (changedWindows.indexOf(window.getId()) < 0 && !windows.contains(window)) { - changedWindows.add(window.getId()); - mIntrospectedWindows.removeAt(i); - window.recycle(); - } - } - - int[] windowIds = null; - - final int changedWindowCount = changedWindows.size(); - if (changedWindowCount > 0) { - windowIds = new int[changedWindowCount]; - for (int i = 0; i < changedWindowCount; i++) { - // Cast is fine as we use long array to cache ints. - windowIds[i] = (int) changedWindows.get(i); - } - changedWindows.clear(); - } - - mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_WINDOWS_CHANGED, - windowIds).sendToTarget(); - } - private void notifyGestureInternal(int gestureId) { final IAccessibilityServiceClient listener; synchronized (mLock) { @@ -2725,20 +2654,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } - private void notifyWindowsChangedInternal(int[] windowIds) { - final IAccessibilityServiceClient listener; - synchronized (mLock) { - listener = mServiceInterface; - } - if (listener != null) { - try { - listener.onWindowsChanged(windowIds); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error during sending windows to: " + mService, re); - } - } - } - private void sendDownAndUpKeyEvents(int keyCode) { final long token = Binder.clearCallingIdentity(); @@ -2844,7 +2759,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public static final int MSG_ON_KEY_EVENT = 2; public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 3; public static final int MSG_ON_KEY_EVENT_TIMEOUT = 4; - public static final int MSG_ON_WINDOWS_CHANGED = 5; public InvocationHandler(Looper looper) { super(looper, null, true); @@ -2874,11 +2788,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { setOnKeyEventResult(false, eventState.sequence); } break; - case MSG_ON_WINDOWS_CHANGED: { - final int[] windowIds = (int[]) message.obj; - notifyWindowsChangedInternal(windowIds); - } break; - default: { throw new IllegalArgumentException("Unknown message: " + type); } @@ -3028,14 +2937,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { @Override public void onWindowsForAccessibilityChanged(List windows) { synchronized (mLock) { - List receivedWindows = (List) windows; - // Populate the windows to report. - List reportedWindows = - new ArrayList(); - final int receivedWindowCount = receivedWindows.size(); + List reportedWindows = new ArrayList<>(); + final int receivedWindowCount = windows.size(); for (int i = 0; i < receivedWindowCount; i++) { - WindowInfo receivedWindow = receivedWindows.get(i); + WindowInfo receivedWindow = windows.get(i); AccessibilityWindowInfo reportedWindow = populateReportedWindow( receivedWindow); if (reportedWindow != null) { @@ -3224,8 +3130,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY; - public final List mWindows = - new ArrayList(); + public final List mWindows = new ArrayList<>(); public int mActiveWindowId = INVALID_WINDOW_ID; public int mFocusedWindowId = INVALID_WINDOW_ID; @@ -3265,7 +3170,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START: case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END: case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: - case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { + case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: + // Also windows changing should always be anounced. + case AccessibilityEvent.TYPE_WINDOWS_CHANGED: { return true; } // All events for changes in window content should be @@ -3327,7 +3234,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } - notifyWindowsChangedLocked(mWindows); + notifyWindowsChanged(); // If we are delaying a window state change event as the window // source was showing when it was fired, now is the time to send. @@ -3452,10 +3359,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { AccessibilityWindowInfo window = mWindows.get(i); window.setActive(window.getId() == windowId); } - notifyWindowsChangedLocked(mWindows); + notifyWindowsChanged(); } } + private void notifyWindowsChanged() { + // Let the client know the windows changed. + AccessibilityEvent event = AccessibilityEvent.obtain( + AccessibilityEvent.TYPE_WINDOWS_CHANGED); + event.setEventTime(SystemClock.uptimeMillis()); + sendAccessibilityEvent(event, mCurrentUserId); + } + public boolean canGetAccessibilityNodeInfoLocked(Service service, int windowId) { return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId); } @@ -3568,30 +3483,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // Non-transient state. public final RemoteCallbackList mClients = - new RemoteCallbackList(); + new RemoteCallbackList<>(); public final SparseArray mInteractionConnections = - new SparseArray(); + new SparseArray<>(); - public final SparseArray mWindowTokens = new SparseArray(); + public final SparseArray mWindowTokens = new SparseArray<>(); // Transient state. public final CopyOnWriteArrayList mBoundServices = - new CopyOnWriteArrayList(); + new CopyOnWriteArrayList<>(); public final Map mComponentNameToServiceMap = - new HashMap(); + new HashMap<>(); public final List mInstalledServices = - new ArrayList(); + new ArrayList<>(); - public final Set mBindingServices = new HashSet(); + public final Set mBindingServices = new HashSet<>(); - public final Set mEnabledServices = new HashSet(); + public final Set mEnabledServices = new HashSet<>(); public final Set mTouchExplorationGrantedServices = - new HashSet(); + new HashSet<>(); public int mHandledFeedbackTypes = 0;