Refactoring of the Accessibility.

1. The accessibility manager service updates its internal state
   based on which settings are enabled, what accessibility services
   are installed and what features are requested by the enabled
   services. It was trying to do the minimal amount of work to
   react to contextual changes like these which resulted in missed
   cases and complex code. Now there is a single method that reads
   the contextual information and single method that reacts to
   contextual changes. This makes the code much easier to maintain.

2. The accessibility manager service was not updating its internal
   state when requested features from accessibility services change.
   It was relying on changing system settings and reacting to the
   settings change. This is problematic since the internal state is
   not updated atomically which leads to race condition bugs. For
   example, if touch exploration is enabled and a service requests
   it is disabled, the internal state will not be updated but a
   request for a settings change will be made. Now while the settings
   change is propagating another request form the same service
   comes to enable touch exploration but the system incorrectly
   thinks touch exploration is enabled. At the end the feature is
   disabled even though it was requested.

3. Fixed a potential NPE if the accessibility input filter's event
   handler was nullified between processing two event batches.

4. Fixed a bug where, if magnification is enabled, it does not work
   on the settings screen since the magnified bounds are not pushed
   from the window manager to the accessibility manager.

Change-Id: Idf629a06480e12f0d88372762df6c024fe0d7856
This commit is contained in:
Svetoslav
2013-02-07 19:21:42 -08:00
parent 3c6721899e
commit 57bf88508e
4 changed files with 441 additions and 451 deletions

View File

@@ -398,6 +398,13 @@ public class AccessibilityServiceInfo implements Parcelable {
flags = other.flags;
}
/**
* @hide
*/
public void setComponentName(ComponentName component) {
mId = component.flattenToShortString();
}
/**
* The accessibility service id.
* <p>
@@ -514,6 +521,33 @@ public class AccessibilityServiceInfo implements Parcelable {
mNonLocalizedDescription = parcel.readString();
}
@Override
public int hashCode() {
return 31 * 1 + ((mId == null) ? 0 : mId.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AccessibilityServiceInfo other = (AccessibilityServiceInfo) obj;
if (mId == null) {
if (other.mId != null) {
return false;
}
} else if (!mId.equals(other.mId)) {
return false;
}
return true;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();

View File

@@ -174,7 +174,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
mMotionEventSequenceStarted = true;
}
} else {
// Wait for an enter hover event to start processing.
// Wait for an enter hover event to start processing.
if (!mHoverEventSequenceStarted) {
if (motionEvent.getActionMasked() != MotionEvent.ACTION_HOVER_ENTER) {
return;
@@ -234,10 +234,14 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
if (DEBUG) {
Slog.i(TAG, "Handling batched event: " + event + ", policyFlags: " + policyFlags);
}
mPm.userActivity(event.getEventTime(), false);
MotionEvent transformedEvent = MotionEvent.obtain(event);
mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
transformedEvent.recycle();
// Since we do batch processing it is possible that by the time the
// next batch is processed the event handle had been set to null.
if (mEventHandler != null) {
mPm.userActivity(event.getEventTime(), false);
MotionEvent transformedEvent = MotionEvent.obtain(event);
mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
transformedEvent.recycle();
}
}
@Override

View File

@@ -86,8 +86,8 @@ final class DisplayMagnifier {
mContext = windowManagerService.mContext;
mWindowManagerService = windowManagerService;
mCallbacks = callbacks;
mMagnifedViewport = new MagnifiedViewport();
mHandler = new MyHandler(mWindowManagerService.mH.getLooper());
mMagnifedViewport = new MagnifiedViewport();
mLongAnimationDuration = mContext.getResources().getInteger(
com.android.internal.R.integer.config_longAnimTime);
}
@@ -273,6 +273,7 @@ final class DisplayMagnifier {
mContext.getResources().getDisplayMetrics());
mHalfBorderWidth = (int) (mBorderWidth + 0.5) / 2;
mWindow = new ViewportWindow(mContext);
recomputeBoundsLocked();
}
public void updateMagnificationSpecLocked(MagnificationSpec spec) {