Bug 1019425 - Activate accessibility when both accessibilty and explore by touch are enabled. r?mfinkle
This simplifies some old code. We get rid of a whitelist of services, and rely on the face that accessibility and explore by touch is enabled to enter our internal accessibility mode.
The whitelist methode held 2 assumptions that are not true anymore:
1. There are some non-accessibility accessibility service apps in the wild that read notifications.
In later Android versions this has been made into a non-a11y use case with NotificationListenerService. So the cases of non-a11y accessibility services has shrunk.
2. Not all screen readers (Gingerbread TalkBack, for example) supported explore by touch. Today, we
exclusively support accessibility services that use explore by touch, and we should not activate our
accessibility mode in any other case.
MozReview-Commit-ID: LMeCedoIGbb
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoAccessibility.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAccessibility.java
@@ -1,29 +1,23 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UIAsyncTask;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -43,45 +37,27 @@ public class GeckoAccessibility {
private static JSONObject sHoverEnter;
private static AccessibilityNodeInfo sVirtualCursorNode;
private static int sCurrentNode;
// This is the number Brailleback uses to start indexing routing keys.
private static final int BRAILLE_CLICK_BASE_INDEX = -275000000;
private static SelfBrailleClient sSelfBrailleClient;
- private static final HashSet<String> sServiceWhitelist =
- new HashSet<String>(Arrays.asList(new String[] {
- "com.google.android.marvin.talkback.TalkBackService", // Google Talkback screen reader
- "com.mot.readout.ScreenReader", // Motorola screen reader
- "info.spielproject.spiel.SpielService", // Spiel screen reader
- "es.codefactory.android.app.ma.MAAccessibilityService" // Codefactory Mobile Accessibility screen reader
- }));
-
public static void updateAccessibilitySettings (final Context context) {
new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
@Override
public Void doInBackground() {
JSONObject ret = new JSONObject();
sEnabled = false;
AccessibilityManager accessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
- if (accessibilityManager.isEnabled()) {
- ActivityManager activityManager =
- (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- List<RunningServiceInfo> runningServices = activityManager.getRunningServices(Integer.MAX_VALUE);
-
- for (RunningServiceInfo runningServiceInfo : runningServices) {
- sEnabled = sServiceWhitelist.contains(runningServiceInfo.service.getClassName());
- if (sEnabled)
- break;
- }
- if (Versions.feature16Plus && sEnabled && sSelfBrailleClient == null) {
- sSelfBrailleClient = new SelfBrailleClient(GeckoAppShell.getContext(), false);
- }
+ sEnabled = accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled();
+ if (Versions.feature16Plus && sEnabled && sSelfBrailleClient == null) {
+ sSelfBrailleClient = new SelfBrailleClient(GeckoAppShell.getContext(), false);
}
try {
ret.put("enabled", sEnabled);
} catch (Exception ex) {
Log.e(LOGTAG, "Error building JSON arguments for Accessibility:Settings:", ex);
}
@@ -263,28 +239,33 @@ public class GeckoAccessibility {
public static void setDelegate(LayerView layerview) {
// Only use this delegate in Jelly Bean.
if (Versions.feature16Plus) {
layerview.setAccessibilityDelegate(new GeckoAccessibilityDelegate());
layerview.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
}
- public static void setAccessibilityStateChangeListener(final Context context) {
- // The state change listener is only supported on API14+
- if (Versions.feature14Plus) {
- AccessibilityManager accessibilityManager =
- (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
- accessibilityManager.addAccessibilityStateChangeListener(new AccessibilityManager.AccessibilityStateChangeListener() {
- @Override
- public void onAccessibilityStateChanged(boolean enabled) {
- updateAccessibilitySettings(context);
- }
- });
- }
+ public static void setAccessibilityManagerListeners(final Context context) {
+ AccessibilityManager accessibilityManager =
+ (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+
+ accessibilityManager.addAccessibilityStateChangeListener(new AccessibilityManager.AccessibilityStateChangeListener() {
+ @Override
+ public void onAccessibilityStateChanged(boolean enabled) {
+ updateAccessibilitySettings(context);
+ }
+ });
+
+ accessibilityManager.addTouchExplorationStateChangeListener(new AccessibilityManager.TouchExplorationStateChangeListener() {
+ @Override
+ public void onTouchExplorationStateChanged(boolean enabled) {
+ updateAccessibilitySettings(context);
+ }
+ });
}
public static void onLayerViewFocusChanged(LayerView layerview, boolean gainFocus) {
if (sEnabled)
GeckoAppShell.notifyObservers("Accessibility:Focus", gainFocus ? "true" : "false");
}
public static class GeckoAccessibilityDelegate extends View.AccessibilityDelegate {
--- a/mobile/android/base/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/gfx/LayerView.java
@@ -127,17 +127,17 @@ public class LayerView extends ScrollVie
mToolbarAnimator = mLayerClient.getDynamicToolbarAnimator();
mRenderer = new LayerRenderer(this);
setFocusable(true);
setFocusableInTouchMode(true);
GeckoAccessibility.setDelegate(this);
- GeckoAccessibility.setAccessibilityStateChangeListener(getContext());
+ GeckoAccessibility.setAccessibilityManagerListeners(getContext());
}
/**
* MotionEventHelper dragAsync() robocop tests can instruct
* PanZoomController not to generate longpress events.
*/
public void setIsLongpressEnabled(boolean isLongpressEnabled) {
mPanZoomController.setIsLongpressEnabled(isLongpressEnabled);