| Index: content/browser/accessibility/browser_accessibility_manager_android.cc
|
| diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
|
| index 973257a8642f658236cdc9c598ff7f1e7af58e0d..31cadb8d988ca8f3e4577da57039361e5b3ed877 100644
|
| --- a/content/browser/accessibility/browser_accessibility_manager_android.cc
|
| +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
|
| @@ -12,6 +12,8 @@
|
| #include "base/android/jni_string.h"
|
| #include "base/feature_list.h"
|
| #include "base/i18n/char_iterator.h"
|
| +#include "base/macros.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/values.h"
|
| @@ -31,6 +33,161 @@ namespace content {
|
|
|
| namespace {
|
|
|
| +// IMPORTANT!
|
| +// These values are written to logs. Do not renumber or delete
|
| +// existing items; add new entries to the end of the list.
|
| +//
|
| +// Note: The string names for these enums must correspond with the names of
|
| +// constants from AccessibilityEvent and AccessibilityServiceInfo, defined
|
| +// below. For example, UMA_EVENT_ANNOUNCEMENT corresponds to
|
| +// ACCESSIBILITYEVENT_TYPE_ANNOUNCEMENT via the macro
|
| +// EVENT_TYPE_HISTOGRAM(event_type_mask, ANNOUNCEMENT).
|
| +enum {
|
| + UMA_CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0,
|
| + UMA_CAPABILITY_CAN_PERFORM_GESTURES = 1,
|
| + UMA_CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 2,
|
| + UMA_CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 3,
|
| + UMA_CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 4,
|
| + UMA_CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 5,
|
| + UMA_EVENT_ANNOUNCEMENT = 6,
|
| + UMA_EVENT_ASSIST_READING_CONTEXT = 7,
|
| + UMA_EVENT_GESTURE_DETECTION_END = 8,
|
| + UMA_EVENT_GESTURE_DETECTION_START = 9,
|
| + UMA_EVENT_NOTIFICATION_STATE_CHANGED = 10,
|
| + UMA_EVENT_TOUCH_EXPLORATION_GESTURE_END = 11,
|
| + UMA_EVENT_TOUCH_EXPLORATION_GESTURE_START = 12,
|
| + UMA_EVENT_TOUCH_INTERACTION_END = 13,
|
| + UMA_EVENT_TOUCH_INTERACTION_START = 14,
|
| + UMA_EVENT_VIEW_ACCESSIBILITY_FOCUSED = 15,
|
| + UMA_EVENT_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 16,
|
| + UMA_EVENT_VIEW_CLICKED = 17,
|
| + UMA_EVENT_VIEW_CONTEXT_CLICKED = 18,
|
| + UMA_EVENT_VIEW_FOCUSED = 19,
|
| + UMA_EVENT_VIEW_HOVER_ENTER = 20,
|
| + UMA_EVENT_VIEW_HOVER_EXIT = 21,
|
| + UMA_EVENT_VIEW_LONG_CLICKED = 22,
|
| + UMA_EVENT_VIEW_SCROLLED = 23,
|
| + UMA_EVENT_VIEW_SELECTED = 24,
|
| + UMA_EVENT_VIEW_TEXT_CHANGED = 25,
|
| + UMA_EVENT_VIEW_TEXT_SELECTION_CHANGED = 26,
|
| + UMA_EVENT_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 27,
|
| + UMA_EVENT_WINDOWS_CHANGED = 28,
|
| + UMA_EVENT_WINDOW_CONTENT_CHANGED = 29,
|
| + UMA_EVENT_WINDOW_STATE_CHANGED = 30,
|
| + UMA_FEEDBACK_AUDIBLE = 31,
|
| + UMA_FEEDBACK_BRAILLE = 32,
|
| + UMA_FEEDBACK_GENERIC = 33,
|
| + UMA_FEEDBACK_HAPTIC = 34,
|
| + UMA_FEEDBACK_SPOKEN = 35,
|
| + UMA_FEEDBACK_VISUAL = 36,
|
| + UMA_FLAG_FORCE_DIRECT_BOOT_AWARE = 37,
|
| + UMA_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 38,
|
| + UMA_FLAG_REPORT_VIEW_IDS = 39,
|
| + UMA_FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 40,
|
| + UMA_FLAG_REQUEST_FILTER_KEY_EVENTS = 41,
|
| + UMA_FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 42,
|
| + UMA_FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 43,
|
| +
|
| + // This must always be the last enum. It's okay for its value to
|
| + // increase, but none of the other enum values may change.
|
| + UMA_ACCESSIBILITYSERVICEINFO_MAX
|
| +};
|
| +
|
| +// These are constants from
|
| +// android.view.accessibility.AccessibilityEvent in Java.
|
| +//
|
| +// If you add a new constant, add a new UMA enum above and add a line
|
| +// to CollectStats(), below.
|
| +enum {
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_CLICKED = 0x00000001,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_LONG_CLICKED = 0x00000002,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_SELECTED = 0x00000004,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_FOCUSED = 0x00000008,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_TEXT_CHANGED = 0x00000010,
|
| + ACCESSIBILITYEVENT_TYPE_WINDOW_STATE_CHANGED = 0x00000020,
|
| + ACCESSIBILITYEVENT_TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_HOVER_ENTER = 0x00000080,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_HOVER_EXIT = 0x00000100,
|
| + ACCESSIBILITYEVENT_TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200,
|
| + ACCESSIBILITYEVENT_TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400,
|
| + ACCESSIBILITYEVENT_TYPE_WINDOW_CONTENT_CHANGED = 0x00000800,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_SCROLLED = 0x00001000,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000,
|
| + ACCESSIBILITYEVENT_TYPE_ANNOUNCEMENT = 0x00004000,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY =
|
| + 0x00020000,
|
| + ACCESSIBILITYEVENT_TYPE_GESTURE_DETECTION_START = 0x00040000,
|
| + ACCESSIBILITYEVENT_TYPE_GESTURE_DETECTION_END = 0x00080000,
|
| + ACCESSIBILITYEVENT_TYPE_TOUCH_INTERACTION_START = 0x00100000,
|
| + ACCESSIBILITYEVENT_TYPE_TOUCH_INTERACTION_END = 0x00200000,
|
| + ACCESSIBILITYEVENT_TYPE_WINDOWS_CHANGED = 0x00400000,
|
| + ACCESSIBILITYEVENT_TYPE_VIEW_CONTEXT_CLICKED = 0x00800000,
|
| + ACCESSIBILITYEVENT_TYPE_ASSIST_READING_CONTEXT = 0x01000000,
|
| +};
|
| +
|
| +// These are constants from
|
| +// android.accessibilityservice.AccessibilityServiceInfo in Java:
|
| +//
|
| +// If you add a new constant, add a new UMA enum above and add a line
|
| +// to CollectStats(), below.
|
| +enum {
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001,
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION =
|
| + 0x00000002,
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY =
|
| + 0x00000004,
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS =
|
| + 0x00000008,
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0x00000010,
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_SPOKEN = 0x0000001,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_HAPTIC = 0x0000002,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_AUDIBLE = 0x0000004,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_VISUAL = 0x0000008,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_GENERIC = 0x0000010,
|
| + ACCESSIBILITYSERVICEINFO_FEEDBACK_BRAILLE = 0x0000020,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_REPORT_VIEW_IDS = 0x00000010,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040,
|
| + ACCESSIBILITYSERVICEINFO_FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000,
|
| +};
|
| +
|
| +// These macros simplify recording a histogram based on information we get
|
| +// from an AccessibilityService. There are four bitmasks of information
|
| +// we get from each AccessibilityService, and for each possible bit mask
|
| +// corresponding to one flag, we want to check if that flag is set, and if
|
| +// so, record the corresponding histogram.
|
| +//
|
| +// Doing this with macros reduces the chance for human error by
|
| +// recording the wrong histogram for the wrong flag.
|
| +//
|
| +// These macros are used by CollectStats(), below.
|
| +#define EVENT_TYPE_HISTOGRAM(event_type_mask, event_type) \
|
| + if (event_type_mask & ACCESSIBILITYEVENT_TYPE_##event_type) \
|
| + UMA_HISTOGRAM_ENUMERATION("Accessibility.AndroidServiceInfo", \
|
| + UMA_EVENT_##event_type, \
|
| + UMA_ACCESSIBILITYSERVICEINFO_MAX)
|
| +#define FLAGS_HISTOGRAM(flags_mask, flag) \
|
| + if (flags_mask & ACCESSIBILITYSERVICEINFO_FLAG_##flag) \
|
| + UMA_HISTOGRAM_ENUMERATION("Accessibility.AndroidServiceInfo", \
|
| + UMA_FLAG_##flag, UMA_ACCESSIBILITYSERVICEINFO_MAX)
|
| +#define FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, feedback_type) \
|
| + if (feedback_type_mask & ACCESSIBILITYSERVICEINFO_FEEDBACK_##feedback_type) \
|
| + UMA_HISTOGRAM_ENUMERATION("Accessibility.AndroidServiceInfo", \
|
| + UMA_FEEDBACK_##feedback_type, \
|
| + UMA_ACCESSIBILITYSERVICEINFO_MAX)
|
| +#define CAPABILITY_TYPE_HISTOGRAM(capability_type_mask, capability_type) \
|
| + if (capability_type_mask & \
|
| + ACCESSIBILITYSERVICEINFO_CAPABILITY_##capability_type) \
|
| + UMA_HISTOGRAM_ENUMERATION("Accessibility.AndroidServiceInfo", \
|
| + UMA_CAPABILITY_##capability_type, \
|
| + UMA_ACCESSIBILITYSERVICEINFO_MAX)
|
| +
|
| using SearchKeyToPredicateMap =
|
| base::hash_map<base::string16, AccessibilityMatchPredicate>;
|
| base::LazyInstance<SearchKeyToPredicateMap>::DestructorAtExit
|
| @@ -170,6 +327,11 @@ BrowserAccessibilityManagerAndroid::BrowserAccessibilityManagerAndroid(
|
| prune_tree_for_screen_reader_(true) {
|
| Initialize(initial_tree);
|
| SetContentViewCore(content_view_core);
|
| +
|
| + // TODO(dmazzoni): get rid of the use of this class by
|
| + // AXTreeSnapshotCallback so that content_view_core is always valid.
|
| + if (!content_view_core.is_null())
|
| + CollectStats();
|
| }
|
|
|
| BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() {
|
| @@ -1107,6 +1269,75 @@ BrowserAccessibilityManagerAndroid::GetJavaRefFromRootManager() {
|
| return root_manager->java_ref().get(env);
|
| }
|
|
|
| +void BrowserAccessibilityManagerAndroid::CollectStats() {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
|
| + if (obj.is_null())
|
| + return;
|
| +
|
| + int event_type_mask =
|
| + Java_BrowserAccessibilityManager_getAccessibilityServiceEventTypeMask(
|
| + env, obj);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, ANNOUNCEMENT);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, ASSIST_READING_CONTEXT);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, GESTURE_DETECTION_END);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, GESTURE_DETECTION_START);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, NOTIFICATION_STATE_CHANGED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_EXPLORATION_GESTURE_END);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_EXPLORATION_GESTURE_START);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_INTERACTION_END);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_INTERACTION_START);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_ACCESSIBILITY_FOCUSED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_ACCESSIBILITY_FOCUS_CLEARED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_CLICKED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_CONTEXT_CLICKED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_FOCUSED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_HOVER_ENTER);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_HOVER_EXIT);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_LONG_CLICKED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_SCROLLED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_SELECTED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_TEXT_CHANGED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_TEXT_SELECTION_CHANGED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask,
|
| + VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOWS_CHANGED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOW_CONTENT_CHANGED);
|
| + EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOW_STATE_CHANGED);
|
| +
|
| + int feedback_type_mask =
|
| + Java_BrowserAccessibilityManager_getAccessibilityServiceFeedbackTypeMask(
|
| + env, obj);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, SPOKEN);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, HAPTIC);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, AUDIBLE);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, VISUAL);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, GENERIC);
|
| + FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, BRAILLE);
|
| +
|
| + int flags_mask =
|
| + Java_BrowserAccessibilityManager_getAccessibilityServiceFlagsMask(env,
|
| + obj);
|
| + FLAGS_HISTOGRAM(flags_mask, INCLUDE_NOT_IMPORTANT_VIEWS);
|
| + FLAGS_HISTOGRAM(flags_mask, REQUEST_TOUCH_EXPLORATION_MODE);
|
| + FLAGS_HISTOGRAM(flags_mask, REQUEST_ENHANCED_WEB_ACCESSIBILITY);
|
| + FLAGS_HISTOGRAM(flags_mask, REPORT_VIEW_IDS);
|
| + FLAGS_HISTOGRAM(flags_mask, REQUEST_FILTER_KEY_EVENTS);
|
| + FLAGS_HISTOGRAM(flags_mask, RETRIEVE_INTERACTIVE_WINDOWS);
|
| + FLAGS_HISTOGRAM(flags_mask, FORCE_DIRECT_BOOT_AWARE);
|
| +
|
| + int capabilities_mask =
|
| + Java_BrowserAccessibilityManager_getAccessibilityServiceCapabilitiesMask(
|
| + env, obj);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_RETRIEVE_WINDOW_CONTENT);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_REQUEST_TOUCH_EXPLORATION);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask,
|
| + CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_REQUEST_FILTER_KEY_EVENTS);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_CONTROL_MAGNIFICATION);
|
| + CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_PERFORM_GESTURES);
|
| +}
|
| +
|
| bool RegisterBrowserAccessibilityManager(JNIEnv* env) {
|
| return RegisterNativesImpl(env);
|
| }
|
|
|