From 10e340cb2aaa6adfb640ff9ef12021634868ce7f Mon Sep 17 00:00:00 2001 From: Phil Weaver Date: Mon, 7 Nov 2016 10:05:26 -0800 Subject: [PATCH] Throttle app a11y events in one place. We were throttling content changed a11y events both in View and in ViewRootImpl. This change eliminates the throttling in View, so events can be consolidated to reduce the number of IPCs. Change-Id: I1e1ecf1afc399e4103da82e6ed1779abfd3ec955 --- core/java/android/view/View.java | 93 ++++----------------------- core/java/android/view/ViewGroup.java | 3 +- 2 files changed, 16 insertions(+), 80 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 14e8185b88da4..70a07e100569c 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2032,8 +2032,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; - SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent; - /** * The view's tag. * {@hide} @@ -10901,11 +10899,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) { return; } - if (mSendViewStateChangedAccessibilityEvent == null) { - mSendViewStateChangedAccessibilityEvent = - new SendViewStateChangedAccessibilityEvent(); + // If this is a live region, we should send a subtree change event + // from this view immediately. Otherwise, we can let it propagate up. + if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) { + final AccessibilityEvent event = AccessibilityEvent.obtain(); + event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + event.setContentChangeTypes(changeType); + sendAccessibilityEventUnchecked(event); + } else if (mParent != null) { + try { + mParent.notifySubtreeAccessibilityStateChanged(this, this, changeType); + } catch (AbstractMethodError e) { + Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() + + " does not fully implement ViewParent", e); + } } - mSendViewStateChangedAccessibilityEvent.runOrPost(changeType); } /** @@ -25720,79 +25728,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - private class SendViewStateChangedAccessibilityEvent implements Runnable { - private int mChangeTypes = 0; - private boolean mPosted; - private boolean mPostedWithDelay; - private long mLastEventTimeMillis; - - @Override - public void run() { - mPosted = false; - mPostedWithDelay = false; - mLastEventTimeMillis = SystemClock.uptimeMillis(); - if (AccessibilityManager.getInstance(mContext).isEnabled()) { - final AccessibilityEvent event = AccessibilityEvent.obtain(); - event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); - event.setContentChangeTypes(mChangeTypes); - sendAccessibilityEventUnchecked(event); - } - mChangeTypes = 0; - } - - public void runOrPost(int changeType) { - mChangeTypes |= changeType; - - // If this is a live region or the child of a live region, collect - // all events from this frame and send them on the next frame. - if (inLiveRegion()) { - // If we're already posted with a delay, remove that. - if (mPostedWithDelay) { - removeCallbacks(this); - mPostedWithDelay = false; - } - // Only post if we're not already posted. - if (!mPosted) { - post(this); - mPosted = true; - } - return; - } - - if (mPosted) { - return; - } - - final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis; - final long minEventIntevalMillis = - ViewConfiguration.getSendRecurringAccessibilityEventsInterval(); - if (timeSinceLastMillis >= minEventIntevalMillis) { - removeCallbacks(this); - run(); - } else { - postDelayed(this, minEventIntevalMillis - timeSinceLastMillis); - mPostedWithDelay = true; - } - } - } - - private boolean inLiveRegion() { - if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) { - return true; - } - - ViewParent parent = getParent(); - while (parent instanceof View) { - if (((View) parent).getAccessibilityLiveRegion() - != View.ACCESSIBILITY_LIVE_REGION_NONE) { - return true; - } - parent = parent.getParent(); - } - - return false; - } - /** * Dump all private flags in readable format, useful for documentation and * sanity checking. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 50593f28d9e39..54187d361b163 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3535,7 +3535,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // If this is a live region, we should send a subtree change event // from this view. Otherwise, we can let it propagate up. if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) { - notifyViewAccessibilityStateChangedIfNeeded(changeType); + notifyViewAccessibilityStateChangedIfNeeded( + AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE); } else if (mParent != null) { try { mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);