summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Svet Ganov <svetoslavganov@google.com> 2017-11-15 20:15:25 -0800
committer Eugene Susla <eugenesusla@google.com> 2017-11-28 17:58:38 -0800
commit8ddfb4794f128ad6ac10fed72c73fdec61ea7bcb (patch)
tree21d23dd06d8bf7600fbc2c0389f7165de26cca6b
parente4cf6bf4745754615b19d95a90d809889c5e4b43 (diff)
Don't generate irrelevant a11y events - framework
Now before we fire an a11y event we check if this event has an observer. As a bonus we don't push the state to clients if the dynamic service config did not change. Test: cts-tradefed run cts-dev -m CtsAccessibilityServiceTestCases bug:69427760 Change-Id: Ie208e13b8557bb7a120198a43efcb79c2752f5db
-rw-r--r--api/current.txt1
-rw-r--r--api/test-current.txt9
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java6
-rw-r--r--core/java/android/inputmethodservice/KeyboardView.java9
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java41
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java16
-rw-r--r--core/java/android/widget/NumberPicker.java7
-rw-r--r--core/java/android/widget/TextView.java4
-rw-r--r--core/java/android/widget/Toast.java3
-rw-r--r--core/java/com/android/internal/widget/ExploreByTouchHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/PasswordTextView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityClientConnection.java115
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java17
-rw-r--r--services/accessibility/java/com/android/server/accessibility/TouchExplorer.java2
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java3
18 files changed, 217 insertions, 56 deletions
diff --git a/api/current.txt b/api/current.txt
index c1188dcd330b..8d9e584e0b47 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47894,6 +47894,7 @@ package android.view.accessibility {
method public void interrupt();
method public static boolean isAccessibilityButtonSupported();
method public boolean isEnabled();
+ method public boolean isObservedEventType(int);
method public boolean isTouchExplorationEnabled();
method public void removeAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
method public boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
diff --git a/api/test-current.txt b/api/test-current.txt
index 8647ed397c49..b18153885867 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -958,6 +958,15 @@ package android.view {
package android.view.accessibility {
+ public final class AccessibilityManager {
+ method public void addAccessibilityServicesStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, android.os.Handler);
+ method public void removeAccessibilityServicesStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener);
+ }
+
+ public static abstract interface AccessibilityManager.AccessibilityServicesStateChangeListener {
+ method public abstract void onAccessibilityServicesStateChanged(android.view.accessibility.AccessibilityManager);
+ }
+
public class AccessibilityNodeInfo implements android.os.Parcelable {
method public static void setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger);
}
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 06a9b0676d08..e0d60cd059d0 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -16,6 +16,8 @@
package android.accessibilityservice;
+import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -47,8 +49,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
-
/**
* This class describes an {@link AccessibilityService}. The system notifies an
* {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
@@ -554,7 +554,7 @@ public class AccessibilityServiceInfo implements Parcelable {
}
/**
- * Updates the properties that an AccessibilitySerivice can change dynamically.
+ * Updates the properties that an AccessibilityService can change dynamically.
*
* @param other The info from which to update the properties.
*
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 13b9206b12ee..7836cd0952aa 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -21,18 +21,16 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Paint.Align;
import android.graphics.PorterDuff;
import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.Paint.Align;
import android.graphics.Region.Op;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard.Key;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.GestureDetector;
@@ -986,6 +984,9 @@ public class KeyboardView extends View implements View.OnClickListener {
private void sendAccessibilityEventForUnicodeCharacter(int eventType, int code) {
if (mAccessibilityManager.isEnabled()) {
+ if (!mAccessibilityManager.isObservedEventType(eventType)) {
+ return;
+ }
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
onInitializeAccessibilityEvent(event);
final String text;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e36a2989afbc..03f3154b8394 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7196,7 +7196,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param text The announcement text.
*/
public void announceForAccessibility(CharSequence text) {
- if (AccessibilityManager.getInstance(mContext).isEnabled() && mParent != null) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_ANNOUNCEMENT) && mParent != null) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_ANNOUNCEMENT);
onInitializeAccessibilityEvent(event);
@@ -10915,7 +10916,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
invalidate();
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED)) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
event.setAction(action);
@@ -11740,7 +11742,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
int fromIndex, int toIndex) {
- if (mParent == null) {
+ if (mParent == null || !AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY)) {
return;
}
AccessibilityEvent event = AccessibilityEvent.obtain(
@@ -26130,7 +26133,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@Override
public void run() {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_SCROLLED)) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_SCROLLED);
event.setScrollDeltaX(mDeltaX);
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 5adea669314c..1d19a9f5969a 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -16,6 +16,7 @@
package android.view.accessibility;
+import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -23,6 +24,8 @@ import android.util.Pools.SynchronizedPool;
import com.android.internal.util.BitUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -709,6 +712,38 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
*/
public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+ TYPE_VIEW_CLICKED,
+ TYPE_VIEW_LONG_CLICKED,
+ TYPE_VIEW_SELECTED,
+ TYPE_VIEW_FOCUSED,
+ TYPE_VIEW_TEXT_CHANGED,
+ TYPE_WINDOW_STATE_CHANGED,
+ TYPE_NOTIFICATION_STATE_CHANGED,
+ TYPE_VIEW_HOVER_ENTER,
+ TYPE_VIEW_HOVER_EXIT,
+ TYPE_TOUCH_EXPLORATION_GESTURE_START,
+ TYPE_TOUCH_EXPLORATION_GESTURE_END,
+ TYPE_WINDOW_CONTENT_CHANGED,
+ TYPE_VIEW_SCROLLED,
+ TYPE_VIEW_TEXT_SELECTION_CHANGED,
+ TYPE_ANNOUNCEMENT,
+ TYPE_VIEW_ACCESSIBILITY_FOCUSED,
+ TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
+ TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
+ TYPE_GESTURE_DETECTION_START,
+ TYPE_GESTURE_DETECTION_END,
+ TYPE_TOUCH_INTERACTION_START,
+ TYPE_TOUCH_INTERACTION_END,
+ TYPE_WINDOWS_CHANGED,
+ TYPE_VIEW_CONTEXT_CLICKED,
+ TYPE_ASSIST_READING_CONTEXT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventType {}
+
/**
* Mask for {@link AccessibilityEvent} all types.
*
@@ -741,7 +776,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
private static final SynchronizedPool<AccessibilityEvent> sPool =
new SynchronizedPool<AccessibilityEvent>(MAX_POOL_SIZE);
- private int mEventType;
+ private @EventType int mEventType;
private CharSequence mPackageName;
private long mEventTime;
int mMovementGranularity;
@@ -833,7 +868,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
*
* @return The event type.
*/
- public int getEventType() {
+ public @EventType int getEventType() {
return mEventType;
}
@@ -890,7 +925,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
- public void setEventType(int eventType) {
+ public void setEventType(@EventType int eventType) {
enforceNotSealed();
mEventType = eventType;
}
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 35f6acba04dc..0375635fd708 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -24,6 +24,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -187,6 +188,7 @@ public final class AccessibilityManager {
*
* @hide
*/
+ @TestApi
public interface AccessibilityServicesStateChangeListener {
/**
@@ -452,6 +454,18 @@ public final class AccessibilityManager {
}
/**
+ * Returns whether there are observers registered for this event type. If
+ * this method returns false you shuold not generate events of this type
+ * to conserve resources.
+ *
+ * @param type The event type.
+ * @return Whether the event is being observed.
+ */
+ public boolean isObservedEventType(@AccessibilityEvent.EventType int type) {
+ return mIsEnabled && (mRelevantEventTypes & type) != 0;
+ }
+
+ /**
* Requests feedback interruption from all accessibility services.
*/
public void interrupt() {
@@ -683,6 +697,7 @@ public final class AccessibilityManager {
* for a callback on the process's main handler.
* @hide
*/
+ @TestApi
public void addAccessibilityServicesStateChangeListener(
@NonNull AccessibilityServicesStateChangeListener listener, @Nullable Handler handler) {
synchronized (mLock) {
@@ -698,6 +713,7 @@ public final class AccessibilityManager {
*
* @hide
*/
+ @TestApi
public void removeAccessibilityServicesStateChangeListener(
@NonNull AccessibilityServicesStateChangeListener listener) {
// Final CopyOnWriteArrayList - no lock needed.
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 4d3189efa64e..b37928066899 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1952,7 +1952,8 @@ public class NumberPicker extends LinearLayout {
CharSequence beforeText = mInputText.getText();
if (!text.equals(beforeText.toString())) {
mInputText.setText(text);
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
mInputText.onInitializeAccessibilityEvent(event);
@@ -2612,7 +2613,7 @@ public class NumberPicker extends LinearLayout {
}
private void sendAccessibilityEventForVirtualText(int eventType) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(eventType)) {
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
mInputText.onInitializeAccessibilityEvent(event);
mInputText.onPopulateAccessibilityEvent(event);
@@ -2623,7 +2624,7 @@ public class NumberPicker extends LinearLayout {
private void sendAccessibilityEventForVirtualButton(int virtualViewId, int eventType,
String text) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(eventType)) {
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.setClassName(Button.class.getName());
event.setPackageName(mContext.getPackageName());
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d9bc51fffd6a..71532a72d7b4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10836,6 +10836,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
int fromIndex, int removedCount, int addedCount) {
+ if (!AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)) {
+ return;
+ }
AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
event.setFromIndex(fromIndex);
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index d80712006a53..bfde6ac38e55 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -504,7 +504,8 @@ public class Toast {
private void trySendAccessibilityEvent() {
AccessibilityManager accessibilityManager =
AccessibilityManager.getInstance(mView.getContext());
- if (!accessibilityManager.isEnabled()) {
+ if (!accessibilityManager.isObservedEventType(
+ AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)) {
return;
}
// treat toasts as notifications since they are used to
diff --git a/core/java/com/android/internal/widget/ExploreByTouchHelper.java b/core/java/com/android/internal/widget/ExploreByTouchHelper.java
index 50ad547e6e65..759a41a2c0ca 100644
--- a/core/java/com/android/internal/widget/ExploreByTouchHelper.java
+++ b/core/java/com/android/internal/widget/ExploreByTouchHelper.java
@@ -186,6 +186,9 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
}
final AccessibilityEvent event = createEvent(virtualViewId, eventType);
+ if (event == null) {
+ return false;
+ }
return parent.requestSendAccessibilityEvent(mView, event);
}
@@ -240,6 +243,9 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
if (parent != null) {
final AccessibilityEvent event = createEvent(virtualViewId,
AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ if (event == null) {
+ return;
+ }
event.setContentChangeTypes(changeTypes);
parent.requestSendAccessibilityEvent(mView, event);
}
@@ -305,6 +311,9 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
* the specified item.
*/
private AccessibilityEvent createEventForHost(int eventType) {
+ if (!AccessibilityManager.getInstance(mContext).isObservedEventType(eventType)) {
+ return null;
+ }
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
mView.onInitializeAccessibilityEvent(event);
@@ -325,6 +334,9 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
* the specified item.
*/
private AccessibilityEvent createEventForChild(int virtualViewId, int eventType) {
+ if (!AccessibilityManager.getInstance(mContext).isObservedEventType(eventType)) {
+ return null;
+ }
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.setEnabled(true);
event.setClassName(DEFAULT_CLASS_NAME);
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index 12f75bb2d56c..0219db332eaf 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -307,8 +307,9 @@ public class PasswordTextView extends View {
void sendAccessibilityEventTypeViewTextChanged(String beforeText, int fromIndex,
int removedCount, int addedCount) {
- if (AccessibilityManager.getInstance(mContext).isEnabled() &&
- (isFocused() || isSelected() && isShown())) {
+ if (AccessibilityManager.getInstance(mContext).isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)
+ && (isFocused() || isSelected() && isShown())) {
AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
event.setFromIndex(fromIndex);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 2b48e0fb32bd..51175d1d7cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -387,7 +387,9 @@ public class PipTouchHandler {
}
case MotionEvent.ACTION_HOVER_ENTER:
case MotionEvent.ACTION_HOVER_MOVE: {
- if (mAccessibilityManager.isEnabled() && !mSendingHoverAccessibilityEvents) {
+ if (mAccessibilityManager.isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_HOVER_ENTER)
+ && !mSendingHoverAccessibilityEvents) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
event.setImportantForAccessibility(true);
@@ -400,7 +402,9 @@ public class PipTouchHandler {
break;
}
case MotionEvent.ACTION_HOVER_EXIT: {
- if (mAccessibilityManager.isEnabled() && mSendingHoverAccessibilityEvents) {
+ if (mAccessibilityManager.isObservedEventType(
+ AccessibilityEvent.TYPE_VIEW_HOVER_EXIT)
+ && mSendingHoverAccessibilityEvents) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
event.setImportantForAccessibility(true);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 0d41e2029086..383d32765811 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -441,7 +441,8 @@ public class VolumeDialogImpl implements VolumeDialog {
.withEndAction(() -> mDialog.dismiss())
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
.start();
- if (mAccessibilityMgr.isEnabled()) {
+ if (mAccessibilityMgr.isObservedEventType(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)) {
AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
event.setPackageName(mContext.getPackageName());
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityClientConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityClientConnection.java
index 7e94d7b6f1fe..22d922be11af 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityClientConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityClientConnection.java
@@ -20,9 +20,7 @@ import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
-import android.accessibilityservice.GestureDescription;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
@@ -49,7 +47,6 @@ import android.view.MagnificationSpec;
import android.view.View;
import android.view.accessibility.AccessibilityCache;
import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -65,6 +62,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -106,7 +104,7 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
int mFeedbackType;
- Set<String> mPackageNames = new HashSet<>();
+ final Set<String> mPackageNames = new HashSet<>();
boolean mIsDefault;
@@ -284,40 +282,98 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
return true;
}
- public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) {
- mEventTypes = info.eventTypes;
- mFeedbackType = info.feedbackType;
- String[] packageNames = info.packageNames;
- if (packageNames != null) {
- mPackageNames.addAll(Arrays.asList(packageNames));
+ boolean setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) {
+ boolean somethingChanged = false;
+
+ if (mEventTypes != info.eventTypes) {
+ mEventTypes = info.eventTypes;
+ somethingChanged = true;
}
- mNotificationTimeout = info.notificationTimeout;
- mIsDefault = (info.flags & DEFAULT) != 0;
- if (supportsFlagForNotImportantViews(info)) {
- if ((info.flags & AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0) {
- mFetchFlags |= AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
- } else {
- mFetchFlags &= ~AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+ if (mFeedbackType != info.feedbackType) {
+ mFeedbackType = info.feedbackType;
+ somethingChanged = true;
+ }
+
+ final String[] oldPackageNames = mPackageNames.toArray(new String[mPackageNames.size()]);
+ if (!Arrays.equals(oldPackageNames, info.packageNames)) {
+ mPackageNames.clear();
+ if (info.packageNames != null) {
+ Collections.addAll(mPackageNames, info.packageNames);
}
+ somethingChanged = true;
}
- if ((info.flags & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0) {
- mFetchFlags |= AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
- } else {
- mFetchFlags &= ~AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
+ if (mNotificationTimeout != info.notificationTimeout) {
+ mNotificationTimeout = info.notificationTimeout;
+ somethingChanged = true;
+ }
+
+ final boolean newIsDefault = (info.flags & DEFAULT) != 0;
+ if (mIsDefault != newIsDefault) {
+ mIsDefault = newIsDefault;
+ somethingChanged = true;
}
- mRequestTouchExplorationMode = (info.flags
+ if (supportsFlagForNotImportantViews(info)) {
+ somethingChanged |= updateFetchFlag(info.flags,
+ AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS);
+ }
+
+ somethingChanged |= updateFetchFlag(info.flags,
+ AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS);
+
+ final boolean newRequestTouchExplorationMode = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
- mRequestFilterKeyEvents = (info.flags
+ if (mRequestTouchExplorationMode != newRequestTouchExplorationMode) {
+ mRequestTouchExplorationMode = newRequestTouchExplorationMode;
+ somethingChanged = true;
+ }
+
+ final boolean newRequestFilterKeyEvents = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
- mRetrieveInteractiveWindows = (info.flags
+ if (mRequestFilterKeyEvents != newRequestFilterKeyEvents) {
+ mRequestFilterKeyEvents = newRequestFilterKeyEvents;
+ somethingChanged = true;
+ }
+
+ final boolean newRetrieveInteractiveWindows = (info.flags
& AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
- mCaptureFingerprintGestures = (info.flags
+ if (mRetrieveInteractiveWindows != newRetrieveInteractiveWindows) {
+ mRetrieveInteractiveWindows = newRetrieveInteractiveWindows;
+ somethingChanged = true;
+ }
+
+ final boolean newCaptureFingerprintGestures = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES) != 0;
- mRequestAccessibilityButton = (info.flags
+ if (mCaptureFingerprintGestures != newCaptureFingerprintGestures) {
+ mCaptureFingerprintGestures = newCaptureFingerprintGestures;
+ somethingChanged = true;
+ }
+
+ final boolean newRequestAccessibilityButton = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
+ if (mRequestAccessibilityButton != newRequestAccessibilityButton) {
+ mRequestAccessibilityButton = newRequestAccessibilityButton;
+ somethingChanged = true;
+ }
+
+ return somethingChanged;
+ }
+
+ private boolean updateFetchFlag(int allFlags, int flagToUpdate) {
+ if ((allFlags & flagToUpdate) != 0) {
+ if ((mFetchFlags & flagToUpdate) == 0) {
+ mFetchFlags |= flagToUpdate;
+ return true;
+ }
+ } else {
+ if ((mFetchFlags & flagToUpdate) != 0) {
+ mFetchFlags &= ~flagToUpdate;
+ return true;
+ }
+ }
+ return false;
}
protected boolean supportsFlagForNotImportantViews(AccessibilityServiceInfo info) {
@@ -349,14 +405,15 @@ abstract class AccessibilityClientConnection extends IAccessibilityServiceConnec
// If the XML manifest had data to configure the service its info
// should be already set. In such a case update only the dynamically
// configurable properties.
+ final boolean serviceInfoChanged;
AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo;
if (oldInfo != null) {
oldInfo.updateDynamicallyConfigurableProperties(info);
- setDynamicallyConfigurableProperties(oldInfo);
+ serviceInfoChanged = setDynamicallyConfigurableProperties(oldInfo);
} else {
- setDynamicallyConfigurableProperties(info);
+ serviceInfoChanged = setDynamicallyConfigurableProperties(info);
}
- mSystemSupport.onClientChange(true);
+ mSystemSupport.onClientChange(serviceInfoChanged);
}
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 3554448efe18..8b5c85a72d7a 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2400,7 +2400,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private void announceNewUserIfNeeded() {
synchronized (mLock) {
UserState userState = getCurrentUserStateLocked();
- if (userState.isHandlingAccessibilityEvents()) {
+ if (userState.isHandlingAccessibilityEvents()
+ && userState.isObservedEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT)) {
UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
String message = mContext.getString(R.string.user_switched,
@@ -3157,13 +3158,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (mWindowsForAccessibilityCallback == null) {
return;
}
+ final int userId;
+ synchronized (mLock) {
+ userId = mCurrentUserId;
+ final UserState userState = getUserStateLocked(userId);
+ if (!userState.isObservedEventType(AccessibilityEvent.TYPE_WINDOWS_CHANGED)) {
+ return;
+ }
+ }
final long identity = Binder.clearCallingIdentity();
try {
// Let the client know the windows changed.
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_WINDOWS_CHANGED);
event.setEventTime(SystemClock.uptimeMillis());
- sendAccessibilityEvent(event, mCurrentUserId);
+ sendAccessibilityEvent(event, userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -3368,6 +3377,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mUserId = userId;
}
+ public boolean isObservedEventType(@AccessibilityEvent.EventType int type) {
+ return (mLastSentRelevantEventTypes & type) != 0;
+ }
+
public int getClientState() {
int clientState = 0;
final boolean a11yEnabled = (mUiAutomationManager.isUiAutomationRunningLocked()
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 3419b809f1b8..62017e879584 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -791,7 +791,7 @@ class TouchExplorer extends BaseEventStreamTransformation
*/
private void sendAccessibilityEvent(int type) {
AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
- if (accessibilityManager.isEnabled()) {
+ if (accessibilityManager.isObservedEventType(type)) {
AccessibilityEvent event = AccessibilityEvent.obtain(type);
event.setWindowId(mAms.getActiveWindowId());
accessibilityManager.sendAccessibilityEvent(event);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cf0140072721..bec6fc2c32f7 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4743,7 +4743,8 @@ public class NotificationManagerService extends SystemService {
}
void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
- if (!mAccessibilityManager.isEnabled()) {
+ if (!mAccessibilityManager.isObservedEventType(
+ AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)) {
return;
}