diff options
| author | 2017-11-15 20:15:25 -0800 | |
|---|---|---|
| committer | 2017-11-28 17:58:38 -0800 | |
| commit | 8ddfb4794f128ad6ac10fed72c73fdec61ea7bcb (patch) | |
| tree | 21d23dd06d8bf7600fbc2c0389f7165de26cca6b | |
| parent | e4cf6bf4745754615b19d95a90d809889c5e4b43 (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
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; } |