Methods Summary |
---|
boolean | accessibilityFocusOnlyInActiveWindow()
synchronized (mLock) {
return mWindowsForAccessibilityCallback == null;
}
|
public int | addAccessibilityInteractionConnection(android.view.IWindow windowToken, android.view.accessibility.IAccessibilityInteractionConnection connection, int userId)
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
final int windowId = sNextWindowId++;
// If the window 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.
if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
windowId, connection, UserHandle.USER_ALL);
wrapper.linkToDeath();
mGlobalInteractionConnections.put(windowId, wrapper);
mGlobalWindowTokens.put(windowId, windowToken.asBinder());
if (DEBUG) {
Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + windowId + " and token: " + windowToken.asBinder());
}
} else {
AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
windowId, connection, resolvedUserId);
wrapper.linkToDeath();
UserState userState = getUserStateLocked(resolvedUserId);
userState.mInteractionConnections.put(windowId, wrapper);
userState.mWindowTokens.put(windowId, windowToken.asBinder());
if (DEBUG) {
Slog.i(LOG_TAG, "Added user connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + windowId + " and userId:" + mCurrentUserId
+ " and token: " + windowToken.asBinder());
}
}
return windowId;
}
|
public int | addClient(android.view.accessibility.IAccessibilityManagerClient client, int userId)
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
// 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.
UserState userState = getUserStateLocked(resolvedUserId);
if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
mGlobalClients.register(client);
if (DEBUG) {
Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid());
}
return userState.getClientState();
} else {
userState.mClients.register(client);
// If this client is not for the current user we do not
// return a state since it is not for the foreground user.
// We will send the state to the client on a user switch.
if (DEBUG) {
Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid()
+ " and userId:" + mCurrentUserId);
}
return (resolvedUserId == mCurrentUserId) ? userState.getClientState() : 0;
}
}
|
private void | addServiceLocked(com.android.server.accessibility.AccessibilityManagerService$Service service, com.android.server.accessibility.AccessibilityManagerService$UserState userState)
try {
service.onAdded();
userState.mBoundServices.add(service);
userState.mComponentNameToServiceMap.put(service.mComponentName, service);
} catch (RemoteException re) {
/* do nothing */
}
|
private boolean | canDispatchEventToServiceLocked(com.android.server.accessibility.AccessibilityManagerService$Service service, android.view.accessibility.AccessibilityEvent event, int handledFeedbackTypes)Determines if given event can be dispatched to a service based on the package of the
event source and already notified services for that event type. Specifically, a
service is notified if it is interested in events from the package and no other service
providing the same feedback type has been notified. Exception are services the
provide generic feedback (feedback type left as a safety net for unforeseen feedback
types) which are always notified.
if (!service.canReceiveEventsLocked()) {
return false;
}
if (event.getWindowId() != WINDOW_ID_UNKNOWN && !event.isImportantForAccessibility()
&& (service.mFetchFlags
& AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) == 0) {
return false;
}
int eventType = event.getEventType();
if ((service.mEventTypes & eventType) != eventType) {
return false;
}
Set<String> packageNames = service.mPackageNames;
String packageName = (event.getPackageName() != null)
? event.getPackageName().toString() : null;
if (packageNames.isEmpty() || packageNames.contains(packageName)) {
int feedbackType = service.mFeedbackType;
if ((handledFeedbackTypes & feedbackType) != feedbackType
|| feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) {
return true;
}
}
return false;
|
private boolean | canRequestAndRequestsEnhancedWebAccessibilityLocked(com.android.server.accessibility.AccessibilityManagerService$Service service)
if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) {
return false;
}
if (service.mIsAutomation || (service.mAccessibilityServiceInfo.getCapabilities()
& AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0) {
return true;
}
return false;
|
private boolean | canRequestAndRequestsTouchExplorationLocked(com.android.server.accessibility.AccessibilityManagerService$Service service)
// Service not ready or cannot request the feature - well nothing to do.
if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) {
return false;
}
// UI test automation service can always enable it.
if (service.mIsAutomation) {
return true;
}
if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion
<= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// Up to JB-MR1 we had a white list with services that can enable touch
// exploration. When a service is first started we show a dialog to the
// use to get a permission to white list the service.
UserState userState = getUserStateLocked(service.mUserId);
if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) {
return true;
} else if (mEnableTouchExplorationDialog == null
|| !mEnableTouchExplorationDialog.isShowing()) {
mMainHandler.obtainMessage(
MainHandler.MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG,
service).sendToTarget();
}
} else {
// Starting in JB-MR2 we request an accessibility service to declare
// certain capabilities in its meta-data to allow it to enable the
// corresponding features.
if ((service.mAccessibilityServiceInfo.getCapabilities()
& AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0) {
return true;
}
}
return false;
|
public void | dump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)
mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
synchronized (mLock) {
pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
pw.println();
final int userCount = mUserStates.size();
for (int i = 0; i < userCount; i++) {
UserState userState = mUserStates.valueAt(i);
pw.append("User state[attributes:{id=" + userState.mUserId);
pw.append(", currentUser=" + (userState.mUserId == mCurrentUserId));
pw.append(", accessibilityEnabled=" + userState.mIsAccessibilityEnabled);
pw.append(", touchExplorationEnabled=" + userState.mIsTouchExplorationEnabled);
pw.append(", displayMagnificationEnabled="
+ userState.mIsDisplayMagnificationEnabled);
if (userState.mUiAutomationService != null) {
pw.append(", ");
userState.mUiAutomationService.dump(fd, pw, args);
pw.println();
}
pw.append("}");
pw.println();
pw.append(" services:{");
final int serviceCount = userState.mBoundServices.size();
for (int j = 0; j < serviceCount; j++) {
if (j > 0) {
pw.append(", ");
pw.println();
pw.append(" ");
}
Service service = userState.mBoundServices.get(j);
service.dump(fd, pw, args);
}
pw.println("}]");
pw.println();
}
if (mSecurityPolicy.mWindows != null) {
final int windowCount = mSecurityPolicy.mWindows.size();
for (int j = 0; j < windowCount; j++) {
if (j > 0) {
pw.append(',");
pw.println();
}
pw.append("Window[");
AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(j);
pw.append(window.toString());
pw.append(']");
}
}
}
|
private void | ensureWindowsAvailableTimed()
synchronized (mLock) {
if (mSecurityPolicy.mWindows != null) {
return;
}
// If we have no registered callback, update the state we
// we may have to register one but it didn't happen yet.
if (mWindowsForAccessibilityCallback == null) {
UserState userState = getCurrentUserStateLocked();
onUserStateChangedLocked(userState);
}
// We have no windows but do not care about them, done.
if (mWindowsForAccessibilityCallback == null) {
return;
}
// Wait for the windows with a timeout.
final long startMillis = SystemClock.uptimeMillis();
while (mSecurityPolicy.mWindows == null) {
final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
if (remainMillis <= 0) {
return;
}
try {
mLock.wait(remainMillis);
} catch (InterruptedException ie) {
/* ignore */
}
}
}
|
private int | findWindowIdLocked(android.os.IBinder token)
final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
if (globalIndex >= 0) {
return mGlobalWindowTokens.keyAt(globalIndex);
}
UserState userState = getCurrentUserStateLocked();
final int userIndex = userState.mWindowTokens.indexOfValue(token);
if (userIndex >= 0) {
return userState.mWindowTokens.keyAt(userIndex);
}
return -1;
|
boolean | getAccessibilityFocusClickPointInScreen(android.graphics.Point outPoint)Gets a point within the accessibility focused node where we can send down
and up events to perform a click.
return getInteractionBridgeLocked()
.getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
|
int | getActiveWindowId()
return mSecurityPolicy.getActiveWindowId();
|
private android.view.MagnificationSpec | getCompatibleMagnificationSpecLocked(int windowId)
IBinder windowToken = mGlobalWindowTokens.get(windowId);
if (windowToken == null) {
windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId);
}
if (windowToken != null) {
return mWindowManagerService.getCompatibleMagnificationSpecForWindow(
windowToken);
}
return null;
|
private com.android.server.accessibility.AccessibilityManagerService$UserState | getCurrentUserStateLocked()
return getUserStateLocked(mCurrentUserId);
|
public java.util.List | getEnabledAccessibilityServiceList(int feedbackType, int userId)
List<AccessibilityServiceInfo> result = null;
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
// The automation service is a fake one and should not be reported
// to clients as being enabled. The automation service is always the
// only active one, if it exists.
UserState userState = getUserStateLocked(resolvedUserId);
if (userState.mUiAutomationService != null) {
return Collections.emptyList();
}
result = mEnabledServicesForFeedbackTempList;
result.clear();
List<Service> services = userState.mBoundServices;
while (feedbackType != 0) {
final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackType));
feedbackType &= ~feedbackTypeBit;
final int serviceCount = services.size();
for (int i = 0; i < serviceCount; i++) {
Service service = services.get(i);
if ((service.mFeedbackType & feedbackTypeBit) != 0) {
result.add(service.mAccessibilityServiceInfo);
}
}
}
}
return result;
|
public java.util.List | getInstalledAccessibilityServiceList(int userId)
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
// The automation service is a fake one and should not be reported
// to clients as being installed - it really is not.
UserState userState = getUserStateLocked(resolvedUserId);
if (userState.mUiAutomationService != null) {
List<AccessibilityServiceInfo> installedServices = new ArrayList<>();
installedServices.addAll(userState.mInstalledServices);
installedServices.remove(userState.mUiAutomationService.mAccessibilityServiceInfo);
return installedServices;
}
return userState.mInstalledServices;
}
|
private com.android.server.accessibility.AccessibilityManagerService$InteractionBridge | getInteractionBridgeLocked()
if (mInteractionBridge == null) {
mInteractionBridge = new InteractionBridge();
}
return mInteractionBridge;
|
private com.android.server.accessibility.AccessibilityManagerService$UserState | getUserStateLocked(int userId)
UserState state = mUserStates.get(userId);
if (state == null) {
state = new UserState(userId);
mUserStates.put(userId, state);
}
return state;
|
boolean | getWindowBounds(int windowId, android.graphics.Rect outBounds)Gets the bounds of a window.
IBinder token;
synchronized (mLock) {
token = mGlobalWindowTokens.get(windowId);
if (token == null) {
token = getCurrentUserStateLocked().mWindowTokens.get(windowId);
}
}
mWindowManagerService.getWindowFrame(token, outBounds);
if (!outBounds.isEmpty()) {
return true;
}
return false;
|
public android.os.IBinder | getWindowToken(int windowId)
mSecurityPolicy.enforceCallingPermission(
Manifest.permission.RETRIEVE_WINDOW_TOKEN,
GET_WINDOW_TOKEN);
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(
UserHandle.getCallingUserId());
if (resolvedUserId != mCurrentUserId) {
return null;
}
if (mSecurityPolicy.findWindowById(windowId) == null) {
return null;
}
IBinder token = mGlobalWindowTokens.get(windowId);
if (token != null) {
return token;
}
return getCurrentUserStateLocked().mWindowTokens.get(windowId);
}
|
private boolean | hasRunningServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
return !userState.mBoundServices.isEmpty() || !userState.mBindingServices.isEmpty();
|
public void | interrupt(int userId)
CopyOnWriteArrayList<Service> services;
synchronized (mLock) {
// 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.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
// This method does nothing for a background user.
if (resolvedUserId != mCurrentUserId) {
return;
}
services = getUserStateLocked(resolvedUserId).mBoundServices;
}
for (int i = 0, count = services.size(); i < count; i++) {
Service service = services.get(i);
try {
service.mServiceInterface.onInterrupt();
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Error during sending interrupt request to "
+ service.mService, re);
}
}
|
private void | manageServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
Map<ComponentName, Service> componentNameToServiceMap =
userState.mComponentNameToServiceMap;
boolean isEnabled = userState.mIsAccessibilityEnabled;
for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) {
AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i);
ComponentName componentName = ComponentName.unflattenFromString(
installedService.getId());
Service service = componentNameToServiceMap.get(componentName);
if (isEnabled) {
// Wait for the binding if it is in process.
if (userState.mBindingServices.contains(componentName)) {
continue;
}
if (userState.mEnabledServices.contains(componentName)) {
if (service == null) {
service = new Service(userState.mUserId, componentName, installedService);
} else if (userState.mBoundServices.contains(service)) {
continue;
}
service.bindLocked();
} else {
if (service != null) {
service.unbindLocked();
}
}
} else {
if (service != null) {
service.unbindLocked();
} else {
userState.mBindingServices.remove(componentName);
}
}
}
// No enabled installed services => disable accessibility to avoid
// sending accessibility events with no recipient across processes.
if (isEnabled && userState.mBoundServices.isEmpty()
&& userState.mBindingServices.isEmpty()) {
userState.mIsAccessibilityEnabled = false;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
}
|
private void | notifyAccessibilityServicesDelayedLocked(android.view.accessibility.AccessibilityEvent event, boolean isDefault)Performs {@link AccessibilityService}s delayed notification. The delay is configurable
and denotes the period after the last event before notifying the service.
try {
UserState state = getCurrentUserStateLocked();
for (int i = 0, count = state.mBoundServices.size(); i < count; i++) {
Service service = state.mBoundServices.get(i);
if (service.mIsDefault == isDefault) {
if (canDispatchEventToServiceLocked(service, event,
state.mHandledFeedbackTypes)) {
state.mHandledFeedbackTypes |= service.mFeedbackType;
service.notifyAccessibilityEvent(event);
}
}
}
} catch (IndexOutOfBoundsException oobe) {
// 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.
}
|
private void | notifyClearAccessibilityCacheLocked()
UserState state = getCurrentUserStateLocked();
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
Service service = state.mBoundServices.get(i);
service.notifyClearAccessibilityNodeInfoCache();
}
|
private boolean | notifyGestureLocked(int gestureId, boolean isDefault)
// TODO: Now we are giving the gestures to the last enabled
// service that can handle them which is the last one
// in our list since we write the last enabled as the
// last record in the enabled services setting. Ideally,
// the user should make the call which service handles
// gestures. However, only one service should handle
// gestures to avoid user frustration when different
// behavior is observed from different combinations of
// enabled accessibility services.
UserState state = getCurrentUserStateLocked();
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
Service service = state.mBoundServices.get(i);
if (service.mRequestTouchExplorationMode && service.mIsDefault == isDefault) {
service.notifyGesture(gestureId);
return true;
}
}
return false;
|
boolean | notifyKeyEvent(android.view.KeyEvent event, int policyFlags)
synchronized (mLock) {
KeyEvent localClone = KeyEvent.obtain(event);
boolean handled = notifyKeyEventLocked(localClone, policyFlags, false);
if (!handled) {
handled = notifyKeyEventLocked(localClone, policyFlags, true);
}
return handled;
}
|
private boolean | notifyKeyEventLocked(android.view.KeyEvent event, int policyFlags, boolean isDefault)
// TODO: Now we are giving the key events to the last enabled
// service that can handle them Ideally, the user should
// make the call which service handles key events. However,
// only one service should handle key events to avoid user
// frustration when different behavior is observed from
// different combinations of enabled accessibility services.
UserState state = getCurrentUserStateLocked();
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
Service service = state.mBoundServices.get(i);
// Key events are handled only by services that declared
// this capability and requested to filter key events.
if (!service.mRequestFilterKeyEvents ||
(service.mAccessibilityServiceInfo.getCapabilities() & AccessibilityServiceInfo
.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) {
continue;
}
if (service.mIsDefault == isDefault) {
service.notifyKeyEvent(event, policyFlags);
return true;
}
}
return false;
|
private com.android.server.accessibility.AccessibilityManagerService$PendingEvent | obtainPendingEventLocked(android.view.KeyEvent event, int policyFlags, int sequence)
PendingEvent pendingEvent = mPendingEventPool.acquire();
if (pendingEvent == null) {
pendingEvent = new PendingEvent();
}
pendingEvent.event = event;
pendingEvent.policyFlags = policyFlags;
pendingEvent.sequence = sequence;
return pendingEvent;
|
boolean | onGesture(int gestureId)
synchronized (mLock) {
boolean handled = notifyGestureLocked(gestureId, false);
if (!handled) {
handled = notifyGestureLocked(gestureId, true);
}
return handled;
}
|
void | onMagnificationStateChanged()
notifyClearAccessibilityCacheLocked();
|
void | onTouchInteractionEnd()
mSecurityPolicy.onTouchInteractionEnd();
|
void | onTouchInteractionStart()
mSecurityPolicy.onTouchInteractionStart();
|
private void | onUserStateChangedLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
// TODO: Remove this hack
mInitialized = true;
updateLegacyCapabilitiesLocked(userState);
updateServicesLocked(userState);
updateWindowsForAccessibilityCallbackLocked(userState);
updateAccessibilityFocusBehaviorLocked(userState);
updateFilterKeyEventsLocked(userState);
updateTouchExplorationLocked(userState);
updateEnhancedWebAccessibilityLocked(userState);
updateDisplayColorAdjustmentSettingsLocked(userState);
scheduleUpdateInputFilter(userState);
scheduleUpdateClientsIfNeededLocked(userState);
|
private void | persistComponentNamesToSettingLocked(java.lang.String settingName, java.util.Set componentNames, int userId)Persists the component names in the specified setting in a
colon separated fashion.
StringBuilder builder = new StringBuilder();
for (ComponentName componentName : componentNames) {
if (builder.length() > 0) {
builder.append(COMPONENT_NAME_SEPARATOR);
}
builder.append(componentName.flattenToShortString());
}
Settings.Secure.putStringForUser(mContext.getContentResolver(),
settingName, builder.toString(), userId);
|
private boolean | readAccessibilityEnabledSettingLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean accessibilityEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId) == 1;
if (accessibilityEnabled != userState.mIsAccessibilityEnabled) {
userState.mIsAccessibilityEnabled = accessibilityEnabled;
return true;
}
return false;
|
private void | readComponentNamesFromSettingLocked(java.lang.String settingName, int userId, java.util.Set outComponentNames)Populates a set with the {@link ComponentName}s stored in a colon
separated value setting for a given user.
String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
settingName, userId);
outComponentNames.clear();
if (settingValue != null) {
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
splitter.setString(settingValue);
while (splitter.hasNext()) {
String str = splitter.next();
if (str == null || str.length() <= 0) {
continue;
}
ComponentName enabledService = ComponentName.unflattenFromString(str);
if (enabledService != null) {
outComponentNames.add(enabledService);
}
}
}
|
private boolean | readConfigurationForUserStateLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
boolean somthingChanged = readAccessibilityEnabledSettingLocked(userState);
somthingChanged |= readInstalledAccessibilityServiceLocked(userState);
somthingChanged |= readEnabledAccessibilityServicesLocked(userState);
somthingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
somthingChanged |= readTouchExplorationEnabledSettingLocked(userState);
somthingChanged |= readHighTextContrastEnabledSettingLocked(userState);
somthingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
somthingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
somthingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
return somthingChanged;
|
private boolean | readDisplayColorAdjustmentSettingsLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean displayAdjustmentsEnabled = DisplayAdjustmentUtils.hasAdjustments(mContext,
userState.mUserId);
if (displayAdjustmentsEnabled != userState.mHasDisplayColorAdjustment) {
userState.mHasDisplayColorAdjustment = displayAdjustmentsEnabled;
return true;
}
// If display adjustment is enabled, always assume there was a change in
// the adjustment settings.
return displayAdjustmentsEnabled;
|
private boolean | readDisplayMagnificationEnabledSettingLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean displayMagnificationEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
0, userState.mUserId) == 1;
if (displayMagnificationEnabled != userState.mIsDisplayMagnificationEnabled) {
userState.mIsDisplayMagnificationEnabled = displayMagnificationEnabled;
return true;
}
return false;
|
private boolean | readEnabledAccessibilityServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
mTempComponentNameSet.clear();
readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
userState.mUserId, mTempComponentNameSet);
if (!mTempComponentNameSet.equals(userState.mEnabledServices)) {
userState.mEnabledServices.clear();
userState.mEnabledServices.addAll(mTempComponentNameSet);
mTempComponentNameSet.clear();
return true;
}
mTempComponentNameSet.clear();
return false;
|
private boolean | readEnhancedWebAccessibilityEnabledChangedLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean enhancedWeAccessibilityEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
0, userState.mUserId) == 1;
if (enhancedWeAccessibilityEnabled != userState.mIsEnhancedWebAccessibilityEnabled) {
userState.mIsEnhancedWebAccessibilityEnabled = enhancedWeAccessibilityEnabled;
return true;
}
return false;
|
private boolean | readHighTextContrastEnabledSettingLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean highTextContrastEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0,
userState.mUserId) == 1;
if (highTextContrastEnabled != userState.mIsTextHighContrastEnabled) {
userState.mIsTextHighContrastEnabled = highTextContrastEnabled;
return true;
}
return false;
|
private boolean | readInstalledAccessibilityServiceLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
mTempAccessibilityServiceInfoList.clear();
List<ResolveInfo> installedServices = mPackageManager.queryIntentServicesAsUser(
new Intent(AccessibilityService.SERVICE_INTERFACE),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
mCurrentUserId);
for (int i = 0, count = installedServices.size(); i < count; i++) {
ResolveInfo resolveInfo = installedServices.get(i);
ServiceInfo serviceInfo = resolveInfo.serviceInfo;
if (!android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE.equals(
serviceInfo.permission)) {
Slog.w(LOG_TAG, "Skipping accessibilty service " + new ComponentName(
serviceInfo.packageName, serviceInfo.name).flattenToShortString()
+ ": it does not require the permission "
+ android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE);
continue;
}
AccessibilityServiceInfo accessibilityServiceInfo;
try {
accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo);
} catch (XmlPullParserException | IOException xppe) {
Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe);
}
}
if (!mTempAccessibilityServiceInfoList.equals(userState.mInstalledServices)) {
userState.mInstalledServices.clear();
userState.mInstalledServices.addAll(mTempAccessibilityServiceInfoList);
mTempAccessibilityServiceInfoList.clear();
return true;
}
mTempAccessibilityServiceInfoList.clear();
return false;
|
private boolean | readTouchExplorationEnabledSettingLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final boolean touchExplorationEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId) == 1;
if (touchExplorationEnabled != userState.mIsTouchExplorationEnabled) {
userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
return true;
}
return false;
|
private boolean | readTouchExplorationGrantedAccessibilityServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
mTempComponentNameSet.clear();
readComponentNamesFromSettingLocked(
Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
userState.mUserId, mTempComponentNameSet);
if (!mTempComponentNameSet.equals(userState.mTouchExplorationGrantedServices)) {
userState.mTouchExplorationGrantedServices.clear();
userState.mTouchExplorationGrantedServices.addAll(mTempComponentNameSet);
mTempComponentNameSet.clear();
return true;
}
mTempComponentNameSet.clear();
return false;
|
private void | recyclePendingEventLocked(com.android.server.accessibility.AccessibilityManagerService$PendingEvent pendingEvent)
pendingEvent.clear();
mPendingEventPool.release(pendingEvent);
|
private void | registerBroadcastReceivers()
PackageMonitor monitor = new PackageMonitor() {
@Override
public void onSomePackagesChanged() {
synchronized (mLock) {
// Only the profile parent can install accessibility services.
// Therefore we ignore packages from linked profiles.
if (getChangingUserId() != mCurrentUserId) {
return;
}
// We will update when the automation service dies.
UserState userState = getCurrentUserStateLocked();
// We have to reload the installed services since some services may
// have different attributes, resolve info (does not support equals),
// etc. Remove them then to force reload. Do it even if automation is
// running since when it goes away, we will have to reload as well.
userState.mInstalledServices.clear();
if (userState.mUiAutomationService == null) {
if (readConfigurationForUserStateLocked(userState)) {
onUserStateChangedLocked(userState);
}
}
}
}
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
final int userId = getChangingUserId();
// Only the profile parent can install accessibility services.
// Therefore we ignore packages from linked profiles.
if (userId != mCurrentUserId) {
return;
}
UserState userState = getUserStateLocked(userId);
Iterator<ComponentName> it = userState.mEnabledServices.iterator();
while (it.hasNext()) {
ComponentName comp = it.next();
String compPkg = comp.getPackageName();
if (compPkg.equals(packageName)) {
it.remove();
// Update the enabled services setting.
persistComponentNamesToSettingLocked(
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
userState.mEnabledServices, userId);
// Update the touch exploration granted services setting.
userState.mTouchExplorationGrantedServices.remove(comp);
persistComponentNamesToSettingLocked(
Settings.Secure.
TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
userState.mTouchExplorationGrantedServices, userId);
// We will update when the automation service dies.
if (userState.mUiAutomationService == null) {
onUserStateChangedLocked(userState);
}
return;
}
}
}
}
@Override
public boolean onHandleForceStop(Intent intent, String[] packages,
int uid, boolean doit) {
synchronized (mLock) {
final int userId = getChangingUserId();
// Only the profile parent can install accessibility services.
// Therefore we ignore packages from linked profiles.
if (userId != mCurrentUserId) {
return false;
}
UserState userState = getUserStateLocked(userId);
Iterator<ComponentName> it = userState.mEnabledServices.iterator();
while (it.hasNext()) {
ComponentName comp = it.next();
String compPkg = comp.getPackageName();
for (String pkg : packages) {
if (compPkg.equals(pkg)) {
if (!doit) {
return true;
}
it.remove();
persistComponentNamesToSettingLocked(
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
userState.mEnabledServices, userId);
// We will update when the automation service dies.
if (userState.mUiAutomationService == null) {
onUserStateChangedLocked(userState);
}
}
}
}
return false;
}
}
};
// package changes
monitor.register(mContext, null, UserHandle.ALL, true);
// user change and unlock
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
// We will update when the automation service dies.
UserState userState = getCurrentUserStateLocked();
if (userState.mUiAutomationService == null) {
if (readConfigurationForUserStateLocked(userState)) {
onUserStateChangedLocked(userState);
}
}
}
}
}, UserHandle.ALL, intentFilter, null, null);
|
public void | registerUiTestAutomationService(android.os.IBinder owner, android.accessibilityservice.IAccessibilityServiceClient serviceClient, android.accessibilityservice.AccessibilityServiceInfo accessibilityServiceInfo)
mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
accessibilityServiceInfo.setComponentName(sFakeAccessibilityServiceComponentName);
synchronized (mLock) {
UserState userState = getCurrentUserStateLocked();
if (userState.mUiAutomationService != null) {
throw new IllegalStateException("UiAutomationService " + serviceClient
+ "already registered!");
}
try {
owner.linkToDeath(userState.mUiAutomationSerivceOnwerDeathRecipient, 0);
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Couldn't register for the death of a"
+ " UiTestAutomationService!", re);
return;
}
userState.mUiAutomationServiceOwner = owner;
userState.mUiAutomationServiceClient = serviceClient;
// Set the temporary state.
userState.mIsAccessibilityEnabled = true;
userState.mIsTouchExplorationEnabled = false;
userState.mIsEnhancedWebAccessibilityEnabled = false;
userState.mIsDisplayMagnificationEnabled = false;
userState.mInstalledServices.add(accessibilityServiceInfo);
userState.mEnabledServices.clear();
userState.mEnabledServices.add(sFakeAccessibilityServiceComponentName);
userState.mTouchExplorationGrantedServices.add(sFakeAccessibilityServiceComponentName);
// Use the new state instead of settings.
onUserStateChangedLocked(userState);
}
|
public void | removeAccessibilityInteractionConnection(android.view.IWindow window)
synchronized (mLock) {
// 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.
mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
UserHandle.getCallingUserId());
IBinder token = window.asBinder();
final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
token, mGlobalWindowTokens, mGlobalInteractionConnections);
if (removedWindowId >= 0) {
if (DEBUG) {
Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowId + " and token: " + window.asBinder());
}
return;
}
final int userCount = mUserStates.size();
for (int i = 0; i < userCount; i++) {
UserState userState = mUserStates.valueAt(i);
final int removedWindowIdForUser =
removeAccessibilityInteractionConnectionInternalLocked(
token, userState.mWindowTokens, userState.mInteractionConnections);
if (removedWindowIdForUser >= 0) {
if (DEBUG) {
Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowIdForUser + " and userId:"
+ mUserStates.keyAt(i) + " and token: " + window.asBinder());
}
return;
}
}
}
|
private int | removeAccessibilityInteractionConnectionInternalLocked(android.os.IBinder windowToken, android.util.SparseArray windowTokens, android.util.SparseArray interactionConnections)
final int count = windowTokens.size();
for (int i = 0; i < count; i++) {
if (windowTokens.valueAt(i) == windowToken) {
final int windowId = windowTokens.keyAt(i);
windowTokens.removeAt(i);
AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId);
wrapper.unlinkToDeath();
interactionConnections.remove(windowId);
return windowId;
}
}
return -1;
|
private void | removeAccessibilityInteractionConnectionLocked(int windowId, int userId)Removes an AccessibilityInteractionConnection.
if (userId == UserHandle.USER_ALL) {
mGlobalWindowTokens.remove(windowId);
mGlobalInteractionConnections.remove(windowId);
} else {
UserState userState = getCurrentUserStateLocked();
userState.mWindowTokens.remove(windowId);
userState.mInteractionConnections.remove(windowId);
}
if (DEBUG) {
Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
}
|
private void | removeServiceLocked(com.android.server.accessibility.AccessibilityManagerService$Service service, com.android.server.accessibility.AccessibilityManagerService$UserState userState)Removes a service.
userState.mBoundServices.remove(service);
userState.mComponentNameToServiceMap.remove(service.mComponentName);
service.onRemoved();
|
private void | removeUser(int userId)
synchronized (mLock) {
mUserStates.remove(userId);
}
|
private void | scheduleUpdateClientsIfNeededLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final int clientState = userState.getClientState();
if (userState.mLastSentClientState != clientState
&& (mGlobalClients.getRegisteredCallbackCount() > 0
|| userState.mClients.getRegisteredCallbackCount() > 0)) {
userState.mLastSentClientState = clientState;
mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
clientState, userState.mUserId) .sendToTarget();
}
|
private void | scheduleUpdateInputFilter(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
|
public boolean | sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent event, int userId)
synchronized (mLock) {
// 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..
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
// This method does nothing for a background user.
if (resolvedUserId != mCurrentUserId) {
return true; // yes, recycle the event
}
if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
mSecurityPolicy.updateActiveAndAccessibilityFocusedWindowLocked(event.getWindowId(),
event.getSourceNodeId(), event.getEventType());
mSecurityPolicy.updateEventSourceLocked(event);
notifyAccessibilityServicesDelayedLocked(event, false);
notifyAccessibilityServicesDelayedLocked(event, true);
}
if (mHasInputFilter && mInputFilter != null) {
mMainHandler.obtainMessage(MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
AccessibilityEvent.obtain(event)).sendToTarget();
}
event.recycle();
getUserStateLocked(resolvedUserId).mHandledFeedbackTypes = 0;
}
return (OWN_PROCESS_ID != Binder.getCallingPid());
|
private void | showEnableTouchExplorationDialog(com.android.server.accessibility.AccessibilityManagerService$Service service)
synchronized (mLock) {
String label = service.mResolveInfo.loadLabel(
mContext.getPackageManager()).toString();
final UserState state = getCurrentUserStateLocked();
if (state.mIsTouchExplorationEnabled) {
return;
}
if (mEnableTouchExplorationDialog != null
&& mEnableTouchExplorationDialog.isShowing()) {
return;
}
mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// The user allowed the service to toggle touch exploration.
state.mTouchExplorationGrantedServices.add(service.mComponentName);
persistComponentNamesToSettingLocked(
Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
state.mTouchExplorationGrantedServices, state.mUserId);
// Enable touch exploration.
UserState userState = getUserStateLocked(service.mUserId);
userState.mIsTouchExplorationEnabled = true;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
service.mUserId);
onUserStateChangedLocked(userState);
}
})
.setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setTitle(R.string.enable_explore_by_touch_warning_title)
.setMessage(mContext.getString(
R.string.enable_explore_by_touch_warning_message, label))
.create();
mEnableTouchExplorationDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
|= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
mEnableTouchExplorationDialog.show();
}
|
private void | switchUser(int userId)
synchronized (mLock) {
if (mCurrentUserId == userId && mInitialized) {
return;
}
// Disconnect from services for the old user.
UserState oldUserState = getCurrentUserStateLocked();
oldUserState.onSwitchToAnotherUser();
// Disable the local managers for the old user.
if (oldUserState.mClients.getRegisteredCallbackCount() > 0) {
mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
oldUserState.mUserId, 0).sendToTarget();
}
// Announce user changes only if more that one exist.
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
final boolean announceNewUser = userManager.getUsers().size() > 1;
// The user changed.
mCurrentUserId = userId;
UserState userState = getCurrentUserStateLocked();
if (userState.mUiAutomationService != null) {
// Switching users disables the UI automation service.
userState.mUiAutomationService.binderDied();
}
readConfigurationForUserStateLocked(userState);
// Even if reading did not yield change, we have to update
// the state since the context in which the current user
// state was used has changed since it was inactive.
onUserStateChangedLocked(userState);
if (announceNewUser) {
// Schedule announcement of the current user if needed.
mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
}
}
|
public void | temporaryEnableAccessibilityStateUntilKeyguardRemoved(android.content.ComponentName service, boolean touchExplorationEnabled)
mSecurityPolicy.enforceCallingPermission(
Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY,
TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED);
if (!mWindowManagerService.isKeyguardLocked()) {
return;
}
synchronized (mLock) {
// Set the temporary state.
UserState userState = getCurrentUserStateLocked();
// This is a nop if UI automation is enabled.
if (userState.mUiAutomationService != null) {
return;
}
userState.mIsAccessibilityEnabled = true;
userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
userState.mIsEnhancedWebAccessibilityEnabled = false;
userState.mIsDisplayMagnificationEnabled = false;
userState.mEnabledServices.clear();
userState.mEnabledServices.add(service);
userState.mBindingServices.clear();
userState.mTouchExplorationGrantedServices.clear();
userState.mTouchExplorationGrantedServices.add(service);
// User the current state instead settings.
onUserStateChangedLocked(userState);
}
|
private void | unbindAllServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
List<Service> services = userState.mBoundServices;
for (int i = 0, count = services.size(); i < count; i++) {
Service service = services.get(i);
if (service.unbindLocked()) {
i--;
count--;
}
}
|
public void | unregisterUiTestAutomationService(android.accessibilityservice.IAccessibilityServiceClient serviceClient)
synchronized (mLock) {
UserState userState = getCurrentUserStateLocked();
// Automation service is not bound, so pretend it died to perform clean up.
if (userState.mUiAutomationService != null
&& serviceClient != null
&& userState.mUiAutomationService.mServiceInterface != null
&& userState.mUiAutomationService.mServiceInterface.asBinder()
== serviceClient.asBinder()) {
userState.mUiAutomationService.binderDied();
} else {
throw new IllegalStateException("UiAutomationService " + serviceClient
+ " not registered!");
}
}
|
private void | updateAccessibilityFocusBehaviorLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
// If there is no service that can operate with interactive windows
// then we keep the old behavior where a window loses accessibility
// focus if it is no longer active. This still changes the behavior
// for services that do not operate with interactive windows and run
// at the same time as the one(s) which does. In practice however,
// there is only one service that uses accessibility focus and it
// is typically the one that operates with interactive windows, So,
// this is fine. Note that to allow a service to work across windows
// we have to allow accessibility focus stay in any of them. Sigh...
List<Service> boundServices = userState.mBoundServices;
final int boundServiceCount = boundServices.size();
for (int i = 0; i < boundServiceCount; i++) {
Service boundService = boundServices.get(i);
if (boundService.canRetrieveInteractiveWindowsLocked()) {
userState.mAccessibilityFocusOnlyInActiveWindow = false;
return;
}
}
userState.mAccessibilityFocusOnlyInActiveWindow = true;
|
private void | updateDisplayColorAdjustmentSettingsLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
|
private void | updateEnhancedWebAccessibilityLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
boolean enabled = false;
final int serviceCount = userState.mBoundServices.size();
for (int i = 0; i < serviceCount; i++) {
Service service = userState.mBoundServices.get(i);
if (canRequestAndRequestsEnhancedWebAccessibilityLocked(service)) {
enabled = true;
break;
}
}
if (enabled != userState.mIsEnhancedWebAccessibilityEnabled) {
userState.mIsEnhancedWebAccessibilityEnabled = enabled;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0,
userState.mUserId);
}
|
private void | updateFilterKeyEventsLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
final int serviceCount = userState.mBoundServices.size();
for (int i = 0; i < serviceCount; i++) {
Service service = userState.mBoundServices.get(i);
if (service.mRequestFilterKeyEvents
&& (service.mAccessibilityServiceInfo.getCapabilities()
& AccessibilityServiceInfo
.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) != 0) {
userState.mIsFilterKeyEventsEnabled = true;
return;
}
}
userState.mIsFilterKeyEventsEnabled = false;
|
private void | updateInputFilter(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
boolean setInputFilter = false;
AccessibilityInputFilter inputFilter = null;
synchronized (mLock) {
int flags = 0;
if (userState.mIsDisplayMagnificationEnabled) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
}
// Touch exploration without accessibility makes no sense.
if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
}
if (userState.mIsFilterKeyEventsEnabled) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS;
}
if (flags != 0) {
if (!mHasInputFilter) {
mHasInputFilter = true;
if (mInputFilter == null) {
mInputFilter = new AccessibilityInputFilter(mContext,
AccessibilityManagerService.this);
}
inputFilter = mInputFilter;
setInputFilter = true;
}
mInputFilter.setEnabledFeatures(flags);
} else {
if (mHasInputFilter) {
mHasInputFilter = false;
mInputFilter.disableFeatures();
inputFilter = null;
setInputFilter = true;
}
}
}
if (setInputFilter) {
mWindowManagerService.setInputFilter(inputFilter);
}
|
private void | updateLegacyCapabilitiesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
// Up to JB-MR1 we had a white list with services that can enable touch
// exploration. When a service is first started we show a dialog to the
// use to get a permission to white list the service.
final int installedServiceCount = userState.mInstalledServices.size();
for (int i = 0; i < installedServiceCount; i++) {
AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i);
ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
if ((serviceInfo.getCapabilities()
& AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) == 0
&& resolveInfo.serviceInfo.applicationInfo.targetSdkVersion
<= Build.VERSION_CODES.JELLY_BEAN_MR1) {
ComponentName componentName = new ComponentName(
resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
if (userState.mTouchExplorationGrantedServices.contains(componentName)) {
serviceInfo.setCapabilities(serviceInfo.getCapabilities()
| AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION);
}
}
}
|
private void | updateServicesLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
if (userState.mIsAccessibilityEnabled) {
manageServicesLocked(userState);
} else {
unbindAllServicesLocked(userState);
}
|
private void | updateTouchExplorationLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
boolean enabled = false;
final int serviceCount = userState.mBoundServices.size();
for (int i = 0; i < serviceCount; i++) {
Service service = userState.mBoundServices.get(i);
if (canRequestAndRequestsTouchExplorationLocked(service)) {
enabled = true;
break;
}
}
if (enabled != userState.mIsTouchExplorationEnabled) {
userState.mIsTouchExplorationEnabled = enabled;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
userState.mUserId);
}
|
private void | updateWindowsForAccessibilityCallbackLocked(com.android.server.accessibility.AccessibilityManagerService$UserState userState)
if (userState.mIsAccessibilityEnabled) {
// We observe windows for accessibility only if there is at least
// one bound service that can retrieve window content that specified
// it is interested in accessing such windows. For services that are
// binding we do an update pass after each bind event, so we run this
// code and register the callback if needed.
boolean boundServiceCanRetrieveInteractiveWindows = false;
List<Service> boundServices = userState.mBoundServices;
final int boundServiceCount = boundServices.size();
for (int i = 0; i < boundServiceCount; i++) {
Service boundService = boundServices.get(i);
if (boundService.canRetrieveInteractiveWindowsLocked()) {
boundServiceCanRetrieveInteractiveWindows = true;
break;
}
}
if (boundServiceCanRetrieveInteractiveWindows) {
if (mWindowsForAccessibilityCallback == null) {
mWindowsForAccessibilityCallback = new WindowsForAccessibilityCallback();
mWindowManagerService.setWindowsForAccessibilityCallback(
mWindowsForAccessibilityCallback);
}
return;
}
}
if (mWindowsForAccessibilityCallback != null) {
mWindowsForAccessibilityCallback = null;
mWindowManagerService.setWindowsForAccessibilityCallback(null);
// Drop all windows we know about.
mSecurityPolicy.clearWindowsLocked();
}
|