Loading services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +8 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,14 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ */ void onClientChangeLocked(boolean serviceInfoChanged); /** * Called back to notify the system the proxy client for a device has changed. * * Changes include if the proxy is unregistered, if its service info list has changed, or if * its focus appearance has changed. */ void onProxyChanged(int deviceId); int getCurrentUserIdLocked(); Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec( Loading Loading @@ -315,8 +323,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc); void setCurrentUserFocusAppearance(int strokeWidth, int color); } public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName, Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +222 −70 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_PACKAGE_BROA import static android.accessibilityservice.AccessibilityTrace.FLAGS_USER_BROADCAST_RECEIVER; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; Loading Loading @@ -189,7 +192,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityUserState.ServiceInfoChangeListener, AccessibilityWindowManager.AccessibilityEventSender, AccessibilitySecurityPolicy.AccessibilityUserManager, SystemActionPerformer.SystemActionsChangedListener { SystemActionPerformer.SystemActionsChangedListener, ProxyManager.SystemSupport{ private static final boolean DEBUG = false; Loading Loading @@ -471,7 +474,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub new MagnificationScaleProvider(mContext)); mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = new ProxyManager(mLock, mA11yWindowManager, mContext); mProxyManager = new ProxyManager(mLock, mA11yWindowManager, mContext, mMainHandler, mUiAutomationManager, this); mFlashNotificationsController = new FlashNotificationsController(mContext); init(); } Loading Loading @@ -862,6 +866,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub }; mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, mMainHandler, Context.RECEIVER_EXPORTED); final BroadcastReceiver virtualDeviceReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final int deviceId = intent.getIntExtra( EXTRA_VIRTUAL_DEVICE_ID, DEVICE_ID_DEFAULT); mProxyManager.clearConnections(deviceId); } }; final IntentFilter virtualDeviceFilter = new IntentFilter(ACTION_VIRTUAL_DEVICE_REMOVED); mContext.registerReceiver(virtualDeviceReceiver, virtualDeviceFilter, Context.RECEIVER_NOT_EXPORTED); } /** Loading Loading @@ -940,21 +957,42 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked(userId); AccessibilityUserState userState = getUserStateLocked(resolvedUserId); // Support a process moving from the default device to a single virtual // device. final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); Client client = new Client(callback, Binder.getCallingUid(), userState, deviceId); // If the client is from a process that runs across users such as // the system UI or the system we add it to the global state that // is shared across users. AccessibilityUserState userState = getUserStateLocked(resolvedUserId); Client client = new Client(callback, Binder.getCallingUid(), userState); if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { if (mProxyManager.isProxyedDeviceId(deviceId)) { if (DEBUG) { Slog.v(LOG_TAG, "Added global client for proxy-ed pid: " + Binder.getCallingPid() + " for device id " + deviceId + " with package names " + Arrays.toString(client.mPackageNames)); } return IntPair.of(mProxyManager.getStateLocked(deviceId, mUiAutomationManager.isUiAutomationRunningLocked()), client.mLastSentRelevantEventTypes); } mGlobalClients.register(callback, client); if (DEBUG) { Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid()); } return IntPair.of( combineUserStateAndProxyState(getClientStateLocked(userState), mProxyManager.getStateLocked()), client.mLastSentRelevantEventTypes); } else { // If the display belongs to a proxy connections if (mProxyManager.isProxyedDeviceId(deviceId)) { if (DEBUG) { Slog.v(LOG_TAG, "Added user client for proxy-ed pid: " + Binder.getCallingPid() + " for device id " + deviceId + " with package names " + Arrays.toString(client.mPackageNames)); } return IntPair.of(mProxyManager.getStateLocked(deviceId, mUiAutomationManager.isUiAutomationRunningLocked()), client.mLastSentRelevantEventTypes); } userState.mUserClients.register(callback, client); // If this client is not for the current user we do not // return a state since it is not for the foreground user. Loading @@ -963,14 +1001,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid() + " and userId:" + mCurrentUserId); } } return IntPair.of( (resolvedUserId == mCurrentUserId) ? combineUserStateAndProxyState( getClientStateLocked(userState), mProxyManager.getStateLocked()) : 0, (resolvedUserId == mCurrentUserId) ? getClientStateLocked(userState) : 0, client.mLastSentRelevantEventTypes); } } } @Override public boolean removeClient(IAccessibilityManagerClient callback, int userId) { Loading Loading @@ -1094,7 +1130,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } private void dispatchAccessibilityEventLocked(AccessibilityEvent event) { if (mProxyManager.isProxyed(event.getDisplayId())) { if (mProxyManager.isProxyedDisplay(event.getDisplayId())) { mProxyManager.sendAccessibilityEventLocked(event); } else { notifyAccessibilityServicesDelayedLocked(event, false); Loading Loading @@ -1160,6 +1196,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int resolvedUserId; final List<AccessibilityServiceInfo> serviceInfos; synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getInstalledAndEnabledServiceInfosLocked( AccessibilityServiceInfo.FEEDBACK_ALL_MASK, deviceId); } // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below // performs the current profile parent resolution. Loading Loading @@ -1195,6 +1237,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getInstalledAndEnabledServiceInfosLocked(feedbackType, deviceId); } // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below // performs the current profile parent resolution. Loading Loading @@ -1239,10 +1287,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (resolvedUserId != mCurrentUserId) { return; } final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { interfacesToInterrupt = new ArrayList<>(); mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt, deviceId); } else { List<AccessibilityServiceConnection> services = getUserStateLocked(resolvedUserId).mBoundServices; int numServices = services.size() + mProxyManager.getNumProxysLocked(); interfacesToInterrupt = new ArrayList<>(numServices); interfacesToInterrupt = new ArrayList<>(services.size()); for (int i = 0; i < services.size(); i++) { AccessibilityServiceConnection service = services.get(i); IBinder a11yServiceBinder = service.mService; Loading @@ -1251,7 +1305,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub interfacesToInterrupt.add(a11yServiceInterface); } } mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt); } } for (int i = 0, count = interfacesToInterrupt.size(); i < count; i++) { try { Loading Loading @@ -1827,7 +1881,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return result; } private void notifyClearAccessibilityCacheLocked() { @Override public void notifyClearAccessibilityCacheLocked() { AccessibilityUserState state = getCurrentUserStateLocked(); for (int i = state.mBoundServices.size() - 1; i >= 0; i--) { AccessibilityServiceConnection service = state.mBoundServices.get(i); Loading Loading @@ -2031,17 +2086,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMainHandler.post(() -> { broadcastToClients(userState, ignoreRemoteException(client -> { int relevantEventTypes; boolean changed = false; synchronized (mLock) { relevantEventTypes = computeRelevantEventTypesLocked(userState, client); if (!mProxyManager.isProxyedDeviceId(client.mDeviceId)) { if (client.mLastSentRelevantEventTypes != relevantEventTypes) { client.mLastSentRelevantEventTypes = relevantEventTypes; changed = true; client.mCallback.setRelevantEventTypes(relevantEventTypes); } } if (changed) { client.mCallback.setRelevantEventTypes(relevantEventTypes); } })); }); Loading @@ -2062,7 +2114,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mUiAutomationManager.getServiceInfo(), client) ? mUiAutomationManager.getRelevantEventTypes() : 0; relevantEventTypes |= mProxyManager.getRelevantEventTypesLocked(); return relevantEventTypes; } Loading Loading @@ -2116,7 +2167,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } private static boolean isClientInPackageAllowlist( static boolean isClientInPackageAllowlist( @Nullable AccessibilityServiceInfo serviceInfo, Client client) { if (serviceInfo == null) return false; Loading Loading @@ -2309,24 +2360,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub updateAccessibilityEnabledSettingLocked(userState); } private int combineUserStateAndProxyState(int userState, int proxyState) { return userState | proxyState; void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState) { scheduleUpdateClientsIfNeededLocked(userState, false); } void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState) { void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState, boolean forceUpdate) { final int clientState = getClientStateLocked(userState); final int proxyState = mProxyManager.getStateLocked(); if ((userState.getLastSentClientStateLocked() != clientState || mProxyManager.getLastSentStateLocked() != proxyState) if (((userState.getLastSentClientStateLocked() != clientState || forceUpdate)) && (mGlobalClients.getRegisteredCallbackCount() > 0 || userState.mUserClients.getRegisteredCallbackCount() > 0)) { userState.setLastSentClientStateLocked(clientState); mProxyManager.setLastStateLocked(proxyState); // Send both the user and proxy state to the app for now. // TODO(b/250929565): Send proxy state to proxy clients mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::sendStateToAllClients, this, combineUserStateAndProxyState(clientState, proxyState), this, clientState, userState.mUserId)); } } Loading @@ -2346,8 +2393,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".sendStateToClients", FLAGS_ACCESSIBILITY_MANAGER_CLIENT, "clientState=" + clientState); } clients.broadcast(ignoreRemoteException( client -> client.setState(clientState))); clients.broadcastForEachCookie(ignoreRemoteException( client -> { Client managerClient = ((Client) client); if (!mProxyManager.isProxyedDeviceId(managerClient.mDeviceId)) { managerClient.mCallback.setState(clientState); } })); } private void scheduleNotifyClientsOfServicesStateChangeLocked( Loading @@ -2370,8 +2422,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".notifyClientsOfServicesStateChange", FLAGS_ACCESSIBILITY_MANAGER_CLIENT, "uiTimeout=" + uiTimeout); } clients.broadcast(ignoreRemoteException( client -> client.notifyServicesStateChanged(uiTimeout))); clients.broadcastForEachCookie(ignoreRemoteException( client -> { Client managerClient = ((Client) client); if (!mProxyManager.isProxyedDeviceId(managerClient.mDeviceId)) { managerClient.mCallback.notifyServicesStateChanged(uiTimeout); } })); } private void scheduleUpdateInputFilter(AccessibilityUserState userState) { Loading Loading @@ -2444,7 +2502,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } inputFilter = mInputFilter; setInputFilter = true; mProxyManager.setAccessibilityInputFilter(mInputFilter); } mInputFilter.setUserAndEnabledFeatures(userState.mUserId, flags); mInputFilter.setCombinedGenericMotionEventSources( Loading Loading @@ -2477,6 +2534,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub "inputFilter=" + inputFilter); } mWindowManagerService.setInputFilter(inputFilter); mProxyManager.setAccessibilityInputFilter(inputFilter); } } Loading Loading @@ -2541,6 +2599,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * @param userState the new user state */ private void onUserStateChangedLocked(AccessibilityUserState userState) { onUserStateChangedLocked(userState, false); } /** * Called when any property of the user state has changed. * * @param userState the new user state * @param forceUpdate whether to force an update of the app Clients. */ private void onUserStateChangedLocked(AccessibilityUserState userState, boolean forceUpdate) { if (DEBUG) { Slog.v(LOG_TAG, "onUserStateChangedLocked for user " + userState.mUserId + " with " + "forceUpdate: " + forceUpdate); } // TODO: Remove this hack mInitialized = true; updateLegacyCapabilitiesLocked(userState); Loading @@ -2553,7 +2625,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub scheduleUpdateFingerprintGestureHandling(userState); scheduleUpdateInputFilter(userState); updateRelevantEventsLocked(userState); scheduleUpdateClientsIfNeededLocked(userState); scheduleUpdateClientsIfNeededLocked(userState, forceUpdate); updateAccessibilityShortcutKeyTargetsLocked(userState); updateAccessibilityButtonTargetsLocked(userState); // Update the capabilities before the mode because we will check the current mode is Loading Loading @@ -2600,7 +2672,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (display != null) { if (observingWindows) { mA11yWindowManager.startTrackingWindows(display.getDisplayId(), mProxyManager.isProxyed(display.getDisplayId())); mProxyManager.isProxyedDisplay(display.getDisplayId())); } else { mA11yWindowManager.stopTrackingWindows(display.getDisplayId()); } Loading Loading @@ -2867,6 +2939,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, 0, userState.mUserId); mProxyManager.updateTimeoutsIfNeeded(nonInteractiveUiTimeout, interactiveUiTimeout); if (nonInteractiveUiTimeout != userState.getUserNonInteractiveUiTimeoutLocked() || interactiveUiTimeout != userState.getUserInteractiveUiTimeoutLocked()) { userState.setUserNonInteractiveUiTimeoutLocked(nonInteractiveUiTimeout); Loading Loading @@ -3632,10 +3706,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } synchronized(mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getRecommendedTimeoutMillisLocked(deviceId); } else { final AccessibilityUserState userState = getCurrentUserStateLocked(); return getRecommendedTimeoutMillisLocked(userState); } } } private long getRecommendedTimeoutMillisLocked(AccessibilityUserState userState) { return IntPair.of(userState.getInteractiveUiTimeoutLocked(), Loading Loading @@ -3712,6 +3792,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".getFocusStrokeWidth", FLAGS_ACCESSIBILITY_MANAGER); } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getFocusStrokeWidthLocked(deviceId); } final AccessibilityUserState userState = getCurrentUserStateLocked(); return userState.getFocusStrokeWidthLocked(); Loading @@ -3728,6 +3813,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".getFocusColor", FLAGS_ACCESSIBILITY_MANAGER); } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getFocusColorLocked(deviceId); } final AccessibilityUserState userState = getCurrentUserStateLocked(); return userState.getFocusColorLocked(); Loading Loading @@ -3814,7 +3904,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub throw new IllegalArgumentException("The display " + displayId + " does not exist or is" + " not tracked by accessibility."); } if (mProxyManager.isProxyed(displayId)) { if (mProxyManager.isProxyedDisplay(displayId)) { throw new IllegalArgumentException("The display " + displayId + " is already being" + " proxy-ed"); } Loading Loading @@ -3847,7 +3937,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } boolean isDisplayProxyed(int displayId) { return mProxyManager.isProxyed(displayId); return mProxyManager.isProxyedDisplay(displayId); } @Override Loading Loading @@ -3995,13 +4085,71 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @Override public void onClientChangeLocked(boolean serviceInfoChanged) { onClientChangeLocked(serviceInfoChanged, false); } /** * Called when the state of a service or proxy has changed * @param serviceInfoChanged if the service info has changed * @param forceUpdate whether to force an update of state for app clients */ public void onClientChangeLocked(boolean serviceInfoChanged, boolean forceUpdate) { AccessibilityUserState userState = getUserStateLocked(mCurrentUserId); onUserStateChangedLocked(userState); onUserStateChangedLocked(userState, forceUpdate); if (serviceInfoChanged) { scheduleNotifyClientsOfServicesStateChangeLocked(userState); } } @Override public void onProxyChanged(int deviceId) { mProxyManager.onProxyChanged(deviceId); } /** * Removes the device from tracking. This will reset any AccessibilityManagerClients to be * associated with the default user id. */ @Override public void removeDeviceIdLocked(int deviceId) { resetClientsLocked(deviceId, getCurrentUserStateLocked().mUserClients); resetClientsLocked(deviceId, mGlobalClients); // Force an update of A11yManagers if the state was previously a proxy state and needs to be // returned to the default device state. onClientChangeLocked(true, true); } private void resetClientsLocked(int deviceId, RemoteCallbackList<IAccessibilityManagerClient> clients) { if (clients == null || clients.getRegisteredCallbackCount() == 0) { return; } synchronized (mLock) { for (int i = 0; i < clients.getRegisteredCallbackCount(); i++) { final Client appClient = ((Client) clients.getRegisteredCallbackCookie(i)); if (appClient.mDeviceId == deviceId) { appClient.mDeviceId = DEVICE_ID_DEFAULT; } } } } @Override public void updateWindowsForAccessibilityCallbackLocked() { updateWindowsForAccessibilityCallbackLocked(getUserStateLocked(mCurrentUserId)); } @Override public RemoteCallbackList<IAccessibilityManagerClient> getGlobalClientsLocked() { return mGlobalClients; } @Override public RemoteCallbackList<IAccessibilityManagerClient> getCurrentUserClientsLocked() { return getCurrentUserState().mUserClients; } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, Loading Loading @@ -4313,16 +4461,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final IAccessibilityManagerClient mCallback; final String[] mPackageNames; int mLastSentRelevantEventTypes; int mUid; int mDeviceId = DEVICE_ID_DEFAULT; private Client(IAccessibilityManagerClient callback, int clientUid, AccessibilityUserState userState) { AccessibilityUserState userState, int deviceId) { mCallback = callback; mPackageNames = mPackageManager.getPackagesForUid(clientUid); mUid = clientUid; mDeviceId = deviceId; synchronized (mLock) { if (mProxyManager.isProxyedDeviceId(deviceId)) { mLastSentRelevantEventTypes = mProxyManager.computeRelevantEventTypesLocked(this); } else { mLastSentRelevantEventTypes = computeRelevantEventTypesLocked(userState, this); } } } } private final class AccessibilityContentObserver extends ContentObserver { Loading Loading @@ -4805,8 +4962,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } mMainHandler.post(() -> { broadcastToClients(userState, ignoreRemoteException(client -> { if (!mProxyManager.isProxyedDeviceId(client.mDeviceId)) { client.mCallback.setFocusAppearance(userState.getFocusStrokeWidthLocked(), userState.getFocusColorLocked()); } })); }); Loading Loading @@ -5041,11 +5200,4 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub transaction.apply(); transaction.close(); } @Override public void setCurrentUserFocusAppearance(int strokeWidth, int color) { synchronized (mLock) { getCurrentUserStateLocked().setFocusAppearanceLocked(strokeWidth, color); } } } Loading
services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +8 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,14 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ */ void onClientChangeLocked(boolean serviceInfoChanged); /** * Called back to notify the system the proxy client for a device has changed. * * Changes include if the proxy is unregistered, if its service info list has changed, or if * its focus appearance has changed. */ void onProxyChanged(int deviceId); int getCurrentUserIdLocked(); Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec( Loading Loading @@ -315,8 +323,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ void attachAccessibilityOverlayToDisplay(int displayId, SurfaceControl sc); void setCurrentUserFocusAppearance(int strokeWidth, int color); } public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName, Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +222 −70 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_PACKAGE_BROA import static android.accessibilityservice.AccessibilityTrace.FLAGS_USER_BROADCAST_RECEIVER; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; Loading Loading @@ -189,7 +192,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityUserState.ServiceInfoChangeListener, AccessibilityWindowManager.AccessibilityEventSender, AccessibilitySecurityPolicy.AccessibilityUserManager, SystemActionPerformer.SystemActionsChangedListener { SystemActionPerformer.SystemActionsChangedListener, ProxyManager.SystemSupport{ private static final boolean DEBUG = false; Loading Loading @@ -471,7 +474,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub new MagnificationScaleProvider(mContext)); mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = new ProxyManager(mLock, mA11yWindowManager, mContext); mProxyManager = new ProxyManager(mLock, mA11yWindowManager, mContext, mMainHandler, mUiAutomationManager, this); mFlashNotificationsController = new FlashNotificationsController(mContext); init(); } Loading Loading @@ -862,6 +866,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub }; mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, mMainHandler, Context.RECEIVER_EXPORTED); final BroadcastReceiver virtualDeviceReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final int deviceId = intent.getIntExtra( EXTRA_VIRTUAL_DEVICE_ID, DEVICE_ID_DEFAULT); mProxyManager.clearConnections(deviceId); } }; final IntentFilter virtualDeviceFilter = new IntentFilter(ACTION_VIRTUAL_DEVICE_REMOVED); mContext.registerReceiver(virtualDeviceReceiver, virtualDeviceFilter, Context.RECEIVER_NOT_EXPORTED); } /** Loading Loading @@ -940,21 +957,42 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked(userId); AccessibilityUserState userState = getUserStateLocked(resolvedUserId); // Support a process moving from the default device to a single virtual // device. final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); Client client = new Client(callback, Binder.getCallingUid(), userState, deviceId); // If the client is from a process that runs across users such as // the system UI or the system we add it to the global state that // is shared across users. AccessibilityUserState userState = getUserStateLocked(resolvedUserId); Client client = new Client(callback, Binder.getCallingUid(), userState); if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { if (mProxyManager.isProxyedDeviceId(deviceId)) { if (DEBUG) { Slog.v(LOG_TAG, "Added global client for proxy-ed pid: " + Binder.getCallingPid() + " for device id " + deviceId + " with package names " + Arrays.toString(client.mPackageNames)); } return IntPair.of(mProxyManager.getStateLocked(deviceId, mUiAutomationManager.isUiAutomationRunningLocked()), client.mLastSentRelevantEventTypes); } mGlobalClients.register(callback, client); if (DEBUG) { Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid()); } return IntPair.of( combineUserStateAndProxyState(getClientStateLocked(userState), mProxyManager.getStateLocked()), client.mLastSentRelevantEventTypes); } else { // If the display belongs to a proxy connections if (mProxyManager.isProxyedDeviceId(deviceId)) { if (DEBUG) { Slog.v(LOG_TAG, "Added user client for proxy-ed pid: " + Binder.getCallingPid() + " for device id " + deviceId + " with package names " + Arrays.toString(client.mPackageNames)); } return IntPair.of(mProxyManager.getStateLocked(deviceId, mUiAutomationManager.isUiAutomationRunningLocked()), client.mLastSentRelevantEventTypes); } userState.mUserClients.register(callback, client); // If this client is not for the current user we do not // return a state since it is not for the foreground user. Loading @@ -963,14 +1001,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid() + " and userId:" + mCurrentUserId); } } return IntPair.of( (resolvedUserId == mCurrentUserId) ? combineUserStateAndProxyState( getClientStateLocked(userState), mProxyManager.getStateLocked()) : 0, (resolvedUserId == mCurrentUserId) ? getClientStateLocked(userState) : 0, client.mLastSentRelevantEventTypes); } } } @Override public boolean removeClient(IAccessibilityManagerClient callback, int userId) { Loading Loading @@ -1094,7 +1130,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } private void dispatchAccessibilityEventLocked(AccessibilityEvent event) { if (mProxyManager.isProxyed(event.getDisplayId())) { if (mProxyManager.isProxyedDisplay(event.getDisplayId())) { mProxyManager.sendAccessibilityEventLocked(event); } else { notifyAccessibilityServicesDelayedLocked(event, false); Loading Loading @@ -1160,6 +1196,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int resolvedUserId; final List<AccessibilityServiceInfo> serviceInfos; synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getInstalledAndEnabledServiceInfosLocked( AccessibilityServiceInfo.FEEDBACK_ALL_MASK, deviceId); } // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below // performs the current profile parent resolution. Loading Loading @@ -1195,6 +1237,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getInstalledAndEnabledServiceInfosLocked(feedbackType, deviceId); } // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below // performs the current profile parent resolution. Loading Loading @@ -1239,10 +1287,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (resolvedUserId != mCurrentUserId) { return; } final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { interfacesToInterrupt = new ArrayList<>(); mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt, deviceId); } else { List<AccessibilityServiceConnection> services = getUserStateLocked(resolvedUserId).mBoundServices; int numServices = services.size() + mProxyManager.getNumProxysLocked(); interfacesToInterrupt = new ArrayList<>(numServices); interfacesToInterrupt = new ArrayList<>(services.size()); for (int i = 0; i < services.size(); i++) { AccessibilityServiceConnection service = services.get(i); IBinder a11yServiceBinder = service.mService; Loading @@ -1251,7 +1305,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub interfacesToInterrupt.add(a11yServiceInterface); } } mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt); } } for (int i = 0, count = interfacesToInterrupt.size(); i < count; i++) { try { Loading Loading @@ -1827,7 +1881,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return result; } private void notifyClearAccessibilityCacheLocked() { @Override public void notifyClearAccessibilityCacheLocked() { AccessibilityUserState state = getCurrentUserStateLocked(); for (int i = state.mBoundServices.size() - 1; i >= 0; i--) { AccessibilityServiceConnection service = state.mBoundServices.get(i); Loading Loading @@ -2031,17 +2086,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMainHandler.post(() -> { broadcastToClients(userState, ignoreRemoteException(client -> { int relevantEventTypes; boolean changed = false; synchronized (mLock) { relevantEventTypes = computeRelevantEventTypesLocked(userState, client); if (!mProxyManager.isProxyedDeviceId(client.mDeviceId)) { if (client.mLastSentRelevantEventTypes != relevantEventTypes) { client.mLastSentRelevantEventTypes = relevantEventTypes; changed = true; client.mCallback.setRelevantEventTypes(relevantEventTypes); } } if (changed) { client.mCallback.setRelevantEventTypes(relevantEventTypes); } })); }); Loading @@ -2062,7 +2114,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mUiAutomationManager.getServiceInfo(), client) ? mUiAutomationManager.getRelevantEventTypes() : 0; relevantEventTypes |= mProxyManager.getRelevantEventTypesLocked(); return relevantEventTypes; } Loading Loading @@ -2116,7 +2167,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } private static boolean isClientInPackageAllowlist( static boolean isClientInPackageAllowlist( @Nullable AccessibilityServiceInfo serviceInfo, Client client) { if (serviceInfo == null) return false; Loading Loading @@ -2309,24 +2360,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub updateAccessibilityEnabledSettingLocked(userState); } private int combineUserStateAndProxyState(int userState, int proxyState) { return userState | proxyState; void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState) { scheduleUpdateClientsIfNeededLocked(userState, false); } void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState) { void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState, boolean forceUpdate) { final int clientState = getClientStateLocked(userState); final int proxyState = mProxyManager.getStateLocked(); if ((userState.getLastSentClientStateLocked() != clientState || mProxyManager.getLastSentStateLocked() != proxyState) if (((userState.getLastSentClientStateLocked() != clientState || forceUpdate)) && (mGlobalClients.getRegisteredCallbackCount() > 0 || userState.mUserClients.getRegisteredCallbackCount() > 0)) { userState.setLastSentClientStateLocked(clientState); mProxyManager.setLastStateLocked(proxyState); // Send both the user and proxy state to the app for now. // TODO(b/250929565): Send proxy state to proxy clients mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::sendStateToAllClients, this, combineUserStateAndProxyState(clientState, proxyState), this, clientState, userState.mUserId)); } } Loading @@ -2346,8 +2393,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".sendStateToClients", FLAGS_ACCESSIBILITY_MANAGER_CLIENT, "clientState=" + clientState); } clients.broadcast(ignoreRemoteException( client -> client.setState(clientState))); clients.broadcastForEachCookie(ignoreRemoteException( client -> { Client managerClient = ((Client) client); if (!mProxyManager.isProxyedDeviceId(managerClient.mDeviceId)) { managerClient.mCallback.setState(clientState); } })); } private void scheduleNotifyClientsOfServicesStateChangeLocked( Loading @@ -2370,8 +2422,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".notifyClientsOfServicesStateChange", FLAGS_ACCESSIBILITY_MANAGER_CLIENT, "uiTimeout=" + uiTimeout); } clients.broadcast(ignoreRemoteException( client -> client.notifyServicesStateChanged(uiTimeout))); clients.broadcastForEachCookie(ignoreRemoteException( client -> { Client managerClient = ((Client) client); if (!mProxyManager.isProxyedDeviceId(managerClient.mDeviceId)) { managerClient.mCallback.notifyServicesStateChanged(uiTimeout); } })); } private void scheduleUpdateInputFilter(AccessibilityUserState userState) { Loading Loading @@ -2444,7 +2502,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } inputFilter = mInputFilter; setInputFilter = true; mProxyManager.setAccessibilityInputFilter(mInputFilter); } mInputFilter.setUserAndEnabledFeatures(userState.mUserId, flags); mInputFilter.setCombinedGenericMotionEventSources( Loading Loading @@ -2477,6 +2534,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub "inputFilter=" + inputFilter); } mWindowManagerService.setInputFilter(inputFilter); mProxyManager.setAccessibilityInputFilter(inputFilter); } } Loading Loading @@ -2541,6 +2599,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * @param userState the new user state */ private void onUserStateChangedLocked(AccessibilityUserState userState) { onUserStateChangedLocked(userState, false); } /** * Called when any property of the user state has changed. * * @param userState the new user state * @param forceUpdate whether to force an update of the app Clients. */ private void onUserStateChangedLocked(AccessibilityUserState userState, boolean forceUpdate) { if (DEBUG) { Slog.v(LOG_TAG, "onUserStateChangedLocked for user " + userState.mUserId + " with " + "forceUpdate: " + forceUpdate); } // TODO: Remove this hack mInitialized = true; updateLegacyCapabilitiesLocked(userState); Loading @@ -2553,7 +2625,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub scheduleUpdateFingerprintGestureHandling(userState); scheduleUpdateInputFilter(userState); updateRelevantEventsLocked(userState); scheduleUpdateClientsIfNeededLocked(userState); scheduleUpdateClientsIfNeededLocked(userState, forceUpdate); updateAccessibilityShortcutKeyTargetsLocked(userState); updateAccessibilityButtonTargetsLocked(userState); // Update the capabilities before the mode because we will check the current mode is Loading Loading @@ -2600,7 +2672,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub if (display != null) { if (observingWindows) { mA11yWindowManager.startTrackingWindows(display.getDisplayId(), mProxyManager.isProxyed(display.getDisplayId())); mProxyManager.isProxyedDisplay(display.getDisplayId())); } else { mA11yWindowManager.stopTrackingWindows(display.getDisplayId()); } Loading Loading @@ -2867,6 +2939,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, 0, userState.mUserId); mProxyManager.updateTimeoutsIfNeeded(nonInteractiveUiTimeout, interactiveUiTimeout); if (nonInteractiveUiTimeout != userState.getUserNonInteractiveUiTimeoutLocked() || interactiveUiTimeout != userState.getUserInteractiveUiTimeoutLocked()) { userState.setUserNonInteractiveUiTimeoutLocked(nonInteractiveUiTimeout); Loading Loading @@ -3632,10 +3706,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } synchronized(mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getRecommendedTimeoutMillisLocked(deviceId); } else { final AccessibilityUserState userState = getCurrentUserStateLocked(); return getRecommendedTimeoutMillisLocked(userState); } } } private long getRecommendedTimeoutMillisLocked(AccessibilityUserState userState) { return IntPair.of(userState.getInteractiveUiTimeoutLocked(), Loading Loading @@ -3712,6 +3792,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".getFocusStrokeWidth", FLAGS_ACCESSIBILITY_MANAGER); } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getFocusStrokeWidthLocked(deviceId); } final AccessibilityUserState userState = getCurrentUserStateLocked(); return userState.getFocusStrokeWidthLocked(); Loading @@ -3728,6 +3813,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mTraceManager.logTrace(LOG_TAG + ".getFocusColor", FLAGS_ACCESSIBILITY_MANAGER); } synchronized (mLock) { final int deviceId = mProxyManager.getFirstDeviceIdForUidLocked( Binder.getCallingUid()); if (mProxyManager.isProxyedDeviceId(deviceId)) { return mProxyManager.getFocusColorLocked(deviceId); } final AccessibilityUserState userState = getCurrentUserStateLocked(); return userState.getFocusColorLocked(); Loading Loading @@ -3814,7 +3904,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub throw new IllegalArgumentException("The display " + displayId + " does not exist or is" + " not tracked by accessibility."); } if (mProxyManager.isProxyed(displayId)) { if (mProxyManager.isProxyedDisplay(displayId)) { throw new IllegalArgumentException("The display " + displayId + " is already being" + " proxy-ed"); } Loading Loading @@ -3847,7 +3937,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } boolean isDisplayProxyed(int displayId) { return mProxyManager.isProxyed(displayId); return mProxyManager.isProxyedDisplay(displayId); } @Override Loading Loading @@ -3995,13 +4085,71 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @Override public void onClientChangeLocked(boolean serviceInfoChanged) { onClientChangeLocked(serviceInfoChanged, false); } /** * Called when the state of a service or proxy has changed * @param serviceInfoChanged if the service info has changed * @param forceUpdate whether to force an update of state for app clients */ public void onClientChangeLocked(boolean serviceInfoChanged, boolean forceUpdate) { AccessibilityUserState userState = getUserStateLocked(mCurrentUserId); onUserStateChangedLocked(userState); onUserStateChangedLocked(userState, forceUpdate); if (serviceInfoChanged) { scheduleNotifyClientsOfServicesStateChangeLocked(userState); } } @Override public void onProxyChanged(int deviceId) { mProxyManager.onProxyChanged(deviceId); } /** * Removes the device from tracking. This will reset any AccessibilityManagerClients to be * associated with the default user id. */ @Override public void removeDeviceIdLocked(int deviceId) { resetClientsLocked(deviceId, getCurrentUserStateLocked().mUserClients); resetClientsLocked(deviceId, mGlobalClients); // Force an update of A11yManagers if the state was previously a proxy state and needs to be // returned to the default device state. onClientChangeLocked(true, true); } private void resetClientsLocked(int deviceId, RemoteCallbackList<IAccessibilityManagerClient> clients) { if (clients == null || clients.getRegisteredCallbackCount() == 0) { return; } synchronized (mLock) { for (int i = 0; i < clients.getRegisteredCallbackCount(); i++) { final Client appClient = ((Client) clients.getRegisteredCallbackCookie(i)); if (appClient.mDeviceId == deviceId) { appClient.mDeviceId = DEVICE_ID_DEFAULT; } } } } @Override public void updateWindowsForAccessibilityCallbackLocked() { updateWindowsForAccessibilityCallbackLocked(getUserStateLocked(mCurrentUserId)); } @Override public RemoteCallbackList<IAccessibilityManagerClient> getGlobalClientsLocked() { return mGlobalClients; } @Override public RemoteCallbackList<IAccessibilityManagerClient> getCurrentUserClientsLocked() { return getCurrentUserState().mUserClients; } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, Loading Loading @@ -4313,16 +4461,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final IAccessibilityManagerClient mCallback; final String[] mPackageNames; int mLastSentRelevantEventTypes; int mUid; int mDeviceId = DEVICE_ID_DEFAULT; private Client(IAccessibilityManagerClient callback, int clientUid, AccessibilityUserState userState) { AccessibilityUserState userState, int deviceId) { mCallback = callback; mPackageNames = mPackageManager.getPackagesForUid(clientUid); mUid = clientUid; mDeviceId = deviceId; synchronized (mLock) { if (mProxyManager.isProxyedDeviceId(deviceId)) { mLastSentRelevantEventTypes = mProxyManager.computeRelevantEventTypesLocked(this); } else { mLastSentRelevantEventTypes = computeRelevantEventTypesLocked(userState, this); } } } } private final class AccessibilityContentObserver extends ContentObserver { Loading Loading @@ -4805,8 +4962,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } mMainHandler.post(() -> { broadcastToClients(userState, ignoreRemoteException(client -> { if (!mProxyManager.isProxyedDeviceId(client.mDeviceId)) { client.mCallback.setFocusAppearance(userState.getFocusStrokeWidthLocked(), userState.getFocusColorLocked()); } })); }); Loading Loading @@ -5041,11 +5200,4 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub transaction.apply(); transaction.close(); } @Override public void setCurrentUserFocusAppearance(int strokeWidth, int color) { synchronized (mLock) { getCurrentUserStateLocked().setFocusAppearanceLocked(strokeWidth, color); } } }