mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 1330257 - 1. Refactor SessionAccessibility; r=eeejay
Move the AccessibilityNodeProvider implementation under SessionAccessibility, to reduce the indent of the code. Also make all methods in SessionAccessibility.Settings static to make the code easier to follow. Differential Revision: https://phabricator.services.mozilla.com/D3250
This commit is contained in:
parent
28e9ca261d
commit
6b8899beef
@ -29,18 +29,177 @@ import android.view.accessibility.AccessibilityNodeProvider;
|
||||
|
||||
public class SessionAccessibility {
|
||||
private static final String LOGTAG = "GeckoAccessibility";
|
||||
// This is a special ID we use for nodes that are eent sources.
|
||||
// This is a special ID we use for nodes that are event sources.
|
||||
// We expose it as a fragment and not an actual child of the View node.
|
||||
private static final int VIRTUAL_CONTENT_ID = -2;
|
||||
|
||||
// This is the number BrailleBack uses to start indexing routing keys.
|
||||
private static final int BRAILLE_CLICK_BASE_INDEX = -275000000;
|
||||
|
||||
/* package */ final class NodeProvider extends AccessibilityNodeProvider {
|
||||
@Override
|
||||
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualDescendantId) {
|
||||
AccessibilityNodeInfo info = (virtualDescendantId == VIRTUAL_CONTENT_ID && mVirtualContentNode != null) ?
|
||||
AccessibilityNodeInfo.obtain(mVirtualContentNode) :
|
||||
AccessibilityNodeInfo.obtain(mView, virtualDescendantId);
|
||||
|
||||
switch (virtualDescendantId) {
|
||||
case View.NO_ID:
|
||||
// This is the parent View node.
|
||||
// We intentionally don't add VIRTUAL_CONTENT_ID
|
||||
// as a child. It is a source for events,
|
||||
// but not a member of the tree you
|
||||
// can get to by traversing down.
|
||||
if (Build.VERSION.SDK_INT < 17 || mView.getDisplay() != null) {
|
||||
// When running junit tests we don't have a display
|
||||
mView.onInitializeAccessibilityNodeInfo(info);
|
||||
}
|
||||
info.setClassName("android.webkit.WebView"); // TODO: WTF
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
Bundle bundle = info.getExtras();
|
||||
bundle.putCharSequence(
|
||||
"ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES",
|
||||
"ARTICLE,BUTTON,CHECKBOX,COMBOBOX,CONTROL," +
|
||||
"FOCUSABLE,FRAME,GRAPHIC,H1,H2,H3,H4,H5,H6," +
|
||||
"HEADING,LANDMARK,LINK,LIST,LIST_ITEM,MAIN," +
|
||||
"MEDIA,RADIO,SECTION,TABLE,TEXT_FIELD," +
|
||||
"UNVISITED_LINK,VISITED_LINK");
|
||||
}
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
|
||||
info.addChild(hostView, VIRTUAL_CONTENT_ID);
|
||||
break;
|
||||
default:
|
||||
info.setParent(mView);
|
||||
info.setSource(mView, virtualDescendantId);
|
||||
info.setVisibleToUser(mView.isShown());
|
||||
info.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
|
||||
info.setEnabled(true);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
|
||||
info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
|
||||
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD |
|
||||
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
|
||||
break;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
||||
if (virtualViewId == View.NO_ID) {
|
||||
return performRootAction(action, arguments);
|
||||
}
|
||||
return performContentAction(action, arguments);
|
||||
}
|
||||
|
||||
private boolean performRootAction(int action, Bundle arguments) {
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
|
||||
final GeckoBundle data = new GeckoBundle(1);
|
||||
data.putBoolean("gainFocus", action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityViewFocused", data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return mView.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private boolean performContentAction(int action, Bundle arguments) {
|
||||
final GeckoBundle data;
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
final AccessibilityEvent event = obtainEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, VIRTUAL_CONTENT_ID);
|
||||
((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_CLICK:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_LONG_CLICK:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityLongPress", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollForward", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollBackward", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SELECT:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySelect", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
|
||||
if (mLastItem) {
|
||||
return false;
|
||||
}
|
||||
// fall-through
|
||||
case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
|
||||
if (arguments != null) {
|
||||
data = new GeckoBundle(1);
|
||||
data.putString("rule", arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING));
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
mSession.getEventDispatcher().dispatch(action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ?
|
||||
"GeckoView:AccessibilityNext" : "GeckoView:AccessibilityPrevious", data);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
|
||||
case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
|
||||
// XXX: Self brailling gives this action with a bogus argument instead of an actual click action;
|
||||
// the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit.
|
||||
// Other negative values are used by ChromeVox, but we don't support them.
|
||||
// FAKE_GRANULARITY_READ_CURRENT = -1
|
||||
// FAKE_GRANULARITY_READ_TITLE = -2
|
||||
// FAKE_GRANULARITY_STOP_SPEECH = -3
|
||||
// FAKE_GRANULARITY_CHANGE_SHIFTER = -4
|
||||
int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
|
||||
if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
|
||||
int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
|
||||
data = new GeckoBundle(1);
|
||||
data.putInt("keyIndex", keyIndex);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", data);
|
||||
} else if (granularity > 0) {
|
||||
boolean extendSelection = arguments.getBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
|
||||
data = new GeckoBundle(3);
|
||||
data.putString("direction", action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY ? "Next" : "Previous");
|
||||
data.putInt("granularity", granularity);
|
||||
data.putBoolean("select", extendSelection);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityByGranularity", data);
|
||||
}
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SET_SELECTION:
|
||||
if (arguments == null) {
|
||||
return false;
|
||||
}
|
||||
int selectionStart = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
|
||||
int selectionEnd = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT);
|
||||
data = new GeckoBundle(2);
|
||||
data.putInt("start", selectionStart);
|
||||
data.putInt("end", selectionEnd);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySetSelection", data);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_CUT:
|
||||
case AccessibilityNodeInfo.ACTION_COPY:
|
||||
case AccessibilityNodeInfo.ACTION_PASTE:
|
||||
data = new GeckoBundle(1);
|
||||
data.putInt("action", action);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityClipboard", data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return mView.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
// Gecko session we are proxying
|
||||
/* package */ final GeckoSession mSession;
|
||||
// This is the view that delegates accessibility to us. We also sends event through it.
|
||||
private View mView;
|
||||
// Aave we reached the last item in content?
|
||||
// Have we reached the last item in content?
|
||||
private boolean mLastItem;
|
||||
// Used to store the JSON message and populate the event later in the code path.
|
||||
private AccessibilityNodeInfo mVirtualContentNode;
|
||||
@ -48,7 +207,7 @@ public class SessionAccessibility {
|
||||
/* package */ SessionAccessibility(final GeckoSession session) {
|
||||
mSession = session;
|
||||
|
||||
Settings.getInstance().dispatch();
|
||||
Settings.updateAccessibilitySettings();
|
||||
|
||||
session.getEventDispatcher().registerUiThreadListener(new BundleEventListener() {
|
||||
@Override
|
||||
@ -86,202 +245,32 @@ public class SessionAccessibility {
|
||||
}
|
||||
|
||||
mView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
|
||||
private AccessibilityNodeProvider mAccessibilityNodeProvider;
|
||||
private NodeProvider mProvider;
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeProvider getAccessibilityNodeProvider(final View hostView) {
|
||||
|
||||
if (mAccessibilityNodeProvider == null)
|
||||
mAccessibilityNodeProvider = new AccessibilityNodeProvider() {
|
||||
@Override
|
||||
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualDescendantId) {
|
||||
assertAttachedView(hostView);
|
||||
|
||||
AccessibilityNodeInfo info = (virtualDescendantId == VIRTUAL_CONTENT_ID && mVirtualContentNode != null) ?
|
||||
AccessibilityNodeInfo.obtain(mVirtualContentNode) :
|
||||
AccessibilityNodeInfo.obtain(mView, virtualDescendantId);
|
||||
|
||||
switch (virtualDescendantId) {
|
||||
case View.NO_ID:
|
||||
// This is the parent View node.
|
||||
// We intentionally don't add VIRTUAL_CONTENT_ID
|
||||
// as a child. It is a source for events,
|
||||
// but not a member of the tree you
|
||||
// can get to by traversing down.
|
||||
if (mView.getDisplay() != null) {
|
||||
// When running junit tests we don't have a display
|
||||
onInitializeAccessibilityNodeInfo(mView, info);
|
||||
}
|
||||
info.setClassName("android.webkit.WebView"); // TODO: WTF
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
Bundle bundle = info.getExtras();
|
||||
bundle.putCharSequence(
|
||||
"ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES",
|
||||
"ARTICLE,BUTTON,CHECKBOX,COMBOBOX,CONTROL," +
|
||||
"FOCUSABLE,FRAME,GRAPHIC,H1,H2,H3,H4,H5,H6," +
|
||||
"HEADING,LANDMARK,LINK,LIST,LIST_ITEM,MAIN," +
|
||||
"MEDIA,RADIO,SECTION,TABLE,TEXT_FIELD," +
|
||||
"UNVISITED_LINK,VISITED_LINK");
|
||||
}
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
|
||||
info.addChild(hostView, VIRTUAL_CONTENT_ID);
|
||||
break;
|
||||
default:
|
||||
info.setParent(mView);
|
||||
info.setSource(mView, virtualDescendantId);
|
||||
info.setVisibleToUser(mView.isShown());
|
||||
info.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
|
||||
info.setEnabled(true);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
|
||||
info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
|
||||
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD |
|
||||
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
|
||||
break;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAction(int virtualViewId, int action, Bundle arguments) {
|
||||
assertAttachedView(hostView);
|
||||
|
||||
if (virtualViewId == View.NO_ID) {
|
||||
return performRootAction(action, arguments);
|
||||
}
|
||||
return performContentAction(action, arguments);
|
||||
}
|
||||
|
||||
private boolean performRootAction(int action, Bundle arguments) {
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
|
||||
final GeckoBundle data = new GeckoBundle(1);
|
||||
data.putBoolean("gainFocus", action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityViewFocused", data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return mView.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private boolean performContentAction(int action, Bundle arguments) {
|
||||
final GeckoBundle data;
|
||||
switch (action) {
|
||||
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
|
||||
final AccessibilityEvent event = obtainEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, VIRTUAL_CONTENT_ID);
|
||||
((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_CLICK:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_LONG_CLICK:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityLongPress", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollForward", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollBackward", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SELECT:
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySelect", null);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
|
||||
if (mLastItem) {
|
||||
return false;
|
||||
}
|
||||
// fall-through
|
||||
case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
|
||||
if (arguments != null) {
|
||||
data = new GeckoBundle(1);
|
||||
data.putString("rule", arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING));
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
mSession.getEventDispatcher().dispatch(action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ?
|
||||
"GeckoView:AccessibilityNext" : "GeckoView:AccessibilityPrevious", data);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
|
||||
case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
|
||||
// XXX: Self brailling gives this action with a bogus argument instead of an actual click action;
|
||||
// the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit.
|
||||
// Other negative values are used by ChromeVox, but we don't support them.
|
||||
// FAKE_GRANULARITY_READ_CURRENT = -1
|
||||
// FAKE_GRANULARITY_READ_TITLE = -2
|
||||
// FAKE_GRANULARITY_STOP_SPEECH = -3
|
||||
// FAKE_GRANULARITY_CHANGE_SHIFTER = -4
|
||||
int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
|
||||
if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
|
||||
int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
|
||||
data = new GeckoBundle(1);
|
||||
data.putInt("keyIndex", keyIndex);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", data);
|
||||
} else if (granularity > 0) {
|
||||
boolean extendSelection = arguments.getBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
|
||||
data = new GeckoBundle(3);
|
||||
data.putString("direction", action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY ? "Next" : "Previous");
|
||||
data.putInt("granularity", granularity);
|
||||
data.putBoolean("select", extendSelection);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityByGranularity", data);
|
||||
}
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_SET_SELECTION:
|
||||
if (arguments == null) {
|
||||
return false;
|
||||
}
|
||||
int selectionStart = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
|
||||
int selectionEnd = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT);
|
||||
data = new GeckoBundle(2);
|
||||
data.putInt("start", selectionStart);
|
||||
data.putInt("end", selectionEnd);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySetSelection", data);
|
||||
return true;
|
||||
case AccessibilityNodeInfo.ACTION_CUT:
|
||||
case AccessibilityNodeInfo.ACTION_COPY:
|
||||
case AccessibilityNodeInfo.ACTION_PASTE:
|
||||
data = new GeckoBundle(1);
|
||||
data.putInt("action", action);
|
||||
mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityClipboard", data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return mView.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
|
||||
private void assertAttachedView(final View view) {
|
||||
if (view != mView) {
|
||||
throw new AssertionError("delegate used with wrong view.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return mAccessibilityNodeProvider;
|
||||
if (hostView != mView) {
|
||||
return null;
|
||||
}
|
||||
if (mProvider == null) {
|
||||
mProvider = new NodeProvider();
|
||||
}
|
||||
return mProvider;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static class Settings {
|
||||
private static final Settings INSTANCE = new Settings();
|
||||
private static final String FORCE_ACCESSIBILITY_PREF = "accessibility.force_disabled";
|
||||
|
||||
private volatile boolean mEnabled;
|
||||
/* package */ volatile boolean mForceEnabled;
|
||||
private static volatile boolean sEnabled;
|
||||
/* package */ static volatile boolean sForceEnabled;
|
||||
|
||||
public Settings() {
|
||||
static {
|
||||
final Context context = GeckoAppShell.getApplicationContext();
|
||||
AccessibilityManager accessibilityManager =
|
||||
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
|
||||
mEnabled = accessibilityManager.isEnabled() &&
|
||||
accessibilityManager.isTouchExplorationEnabled();
|
||||
|
||||
accessibilityManager.addAccessibilityStateChangeListener(
|
||||
new AccessibilityManager.AccessibilityStateChangeListener() {
|
||||
@Override
|
||||
@ -306,7 +295,7 @@ public class SessionAccessibility {
|
||||
@Override
|
||||
public void prefValue(String pref, int value) {
|
||||
if (pref.equals(FORCE_ACCESSIBILITY_PREF)) {
|
||||
mForceEnabled = value < 0;
|
||||
sForceEnabled = value < 0;
|
||||
dispatch();
|
||||
}
|
||||
}
|
||||
@ -314,15 +303,11 @@ public class SessionAccessibility {
|
||||
PrefsHelper.addObserver(new String[]{ FORCE_ACCESSIBILITY_PREF }, prefHandler);
|
||||
}
|
||||
|
||||
public static Settings getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return INSTANCE.mEnabled || INSTANCE.mForceEnabled;
|
||||
return sEnabled || sForceEnabled;
|
||||
}
|
||||
|
||||
private void updateAccessibilitySettings() {
|
||||
public static void updateAccessibilitySettings() {
|
||||
final AccessibilityManager accessibilityManager = (AccessibilityManager)
|
||||
GeckoAppShell.getApplicationContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
mEnabled = accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled();
|
||||
@ -330,9 +315,9 @@ public class SessionAccessibility {
|
||||
dispatch();
|
||||
}
|
||||
|
||||
private void dispatch() {
|
||||
/* package */ static void dispatch() {
|
||||
final GeckoBundle ret = new GeckoBundle(1);
|
||||
ret.putBoolean("enabled", mEnabled || mForceEnabled);
|
||||
ret.putBoolean("enabled", isTouchExplorationEnabled());
|
||||
// "GeckoView:AccessibilitySettings" is dispatched to the Gecko thread.
|
||||
EventDispatcher.getInstance().dispatch("GeckoView:AccessibilitySettings", ret);
|
||||
// "GeckoView:AccessibilityEnabled" is dispatched to the UI thread.
|
||||
|
Loading…
Reference in New Issue
Block a user