| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/accessibility/browser_accessibility_state_impl_android.h" |
| |
| #include <memory> |
| |
| #include "base/containers/contains.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "ui/accessibility/android/accessibility_state.h" |
| #include "ui/gfx/animation/animation.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| // These are hashes of different accessibility services which are generally used |
| // as part of an assistive technology. |
| const uint32_t kAssistiveTechPackageHashes[] = { |
| 0x349d4b1a, // Android Accessibility Suite |
| 0xa5a469fc, // Sound Amplifier |
| 0xb13e6179, // Action Blocks Accessibility |
| 0xb38ef877, // Voice Access |
| 0xbc2897b4, // BrailleBack |
| }; |
| |
| // These are hashes of different "accessibility" services that enable |
| // accessibility but are only using it in the context of password management. |
| const uint32_t kPasswordPackageHashes[] = { |
| 0x013b76f2, 0x31cd47e3, 0x353cf6c5, 0x48723526, 0x4a8cfa8a, |
| 0x7e0ad835, 0x7e3515d0, 0x8e4c009f, 0x920ad3bd, 0xca841f39, |
| }; |
| |
| // 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, |
| UMA_SERVICE_TYPE_UNKNOWN = 44, |
| UMA_SERVICE_TYPE_PASSWORD_MANAGER = 45, |
| UMA_SERVICE_TYPE_ASSISTIVE_TECH = 46, |
| |
| UMA_CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES = 47, |
| UMA_CAPABILITY_CAN_TAKE_SCREENSHOT = 48, |
| UMA_FLAG_ENABLE_ACCESSIBILITY_VOLUME = 49, |
| UMA_FLAG_REQUEST_ACCESSIBILITY_BUTTON = 50, |
| UMA_FLAG_REQUEST_FINGERPRINT_GESTURES = 51, |
| UMA_FLAG_REQUEST_MULTI_FINGER_GESTURES = 52, |
| UMA_FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK = 53, |
| UMA_FLAG_SERVICE_HANDLES_DOUBLE_TAP = 54, |
| |
| UMA_SERVICE_TYPE_ASSISTIVE_TECH_WITH_PASSWORD_MANAGER = 55, |
| UMA_SERVICE_TYPE_ASSISTIVE_TECH_WITH_UNKNOWN = 56, |
| UMA_SERVICE_TYPE_PASSWORD_MANAGER_WITH_UNKNOWN = 57, |
| UMA_SERVICE_TYPE_ALL_VARIANTS = 58, |
| |
| UMA_EVENT_SPEECH_STATE_CHANGE = 59, |
| UMA_FEEDBACK_ALL_MASK = 60, |
| UMA_FLAG_REQUEST_2_FINGER_PASSTHROUGH = 61, |
| UMA_FLAG_SEND_MOTION_EVENTS = 62, |
| UMA_FLAG_INPUT_METHOD_EDITOR = 63, |
| |
| // 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 RecordAccessibilityServiceStatsHistogram(), 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, |
| ACCESSIBILITYEVENT_TYPE_SPEECH_STATE_CHANGE = 0x02000000, |
| }; |
| |
| // 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 RecordAccessibilityServiceStatsHistogram(), 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_CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES = |
| 0x00000040, |
| ACCESSIBILITYSERVICEINFO_CAPABILITY_CAN_TAKE_SCREENSHOT = 0x00000080, |
| 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_FEEDBACK_ALL_MASK = 0xFFFFFFFF, |
| 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_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080, |
| ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x00000100, |
| ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_FINGERPRINT_GESTURES = 0x00000200, |
| ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK = |
| 0x00000400, |
| ACCESSIBILITYSERVICEINFO_FLAG_SERVICE_HANDLES_DOUBLE_TAP = 0x00000800, |
| ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_MULTI_FINGER_GESTURES = 0x00001000, |
| ACCESSIBILITYSERVICEINFO_FLAG_REQUEST_2_FINGER_PASSTHROUGH = 0x0002000, |
| ACCESSIBILITYSERVICEINFO_FLAG_SEND_MOTION_EVENTS = 0x0004000, |
| ACCESSIBILITYSERVICEINFO_FLAG_INPUT_METHOD_EDITOR = 0x0008000, |
| 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 RecordAccessibilityServiceStatsHistogram(), below. |
| #define EVENT_TYPE_HISTOGRAM(event_type_mask, event_type, histogram) \ |
| if (event_type_mask & ACCESSIBILITYEVENT_TYPE_##event_type) \ |
| base::UmaHistogramEnumeration(histogram, UMA_EVENT_##event_type, \ |
| UMA_ACCESSIBILITYSERVICEINFO_MAX) |
| #define FLAGS_HISTOGRAM(flags_mask, flag, histogram) \ |
| if (flags_mask & ACCESSIBILITYSERVICEINFO_FLAG_##flag) \ |
| base::UmaHistogramEnumeration(histogram, UMA_FLAG_##flag, \ |
| UMA_ACCESSIBILITYSERVICEINFO_MAX) |
| #define FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, feedback_type, histogram) \ |
| if (feedback_type_mask & ACCESSIBILITYSERVICEINFO_FEEDBACK_##feedback_type) \ |
| base::UmaHistogramEnumeration(histogram, UMA_FEEDBACK_##feedback_type, \ |
| UMA_ACCESSIBILITYSERVICEINFO_MAX) |
| #define CAPABILITY_TYPE_HISTOGRAM(capability_type_mask, capability_type, \ |
| histogram) \ |
| if (capability_type_mask & \ |
| ACCESSIBILITYSERVICEINFO_CAPABILITY_##capability_type) \ |
| base::UmaHistogramEnumeration(histogram, UMA_CAPABILITY_##capability_type, \ |
| UMA_ACCESSIBILITYSERVICEINFO_MAX) |
| #define SERVICE_TYPE_HISTOGRAM(service_type, histogram) \ |
| base::UmaHistogramEnumeration(histogram, service_type, \ |
| UMA_ACCESSIBILITYSERVICEINFO_MAX); |
| |
| // This macro simplifies the recording of the aggregate accessibility |
| // information in the CollectAccessibilityServiceStats() method, below. |
| // |
| // There are 7 possible variants of the "Accessibility.AndroidServiceInfo.{}" |
| // histogram. We consider users that have: assistive tech, password managers, or |
| // an unknown service enabled. We track the 7 possible subsets of these (the |
| // empty set of nothing enabled is implicitly tracked by whichever users do not |
| // belong to one of the other groups). Requested event, feedback, flag, and |
| // capabilities are recorded per subset. |
| #define RECORD_ALL_HISTOGRAMS(event, feedback, flag, capability, \ |
| service_type_variant) \ |
| RecordAccessibilityServiceStatsHistogram( \ |
| event, feedback, flag, capability, \ |
| "Accessibility.AndroidServiceInfo." #service_type_variant); \ |
| SERVICE_TYPE_HISTOGRAM( \ |
| UMA_SERVICE_TYPE_##service_type_variant, \ |
| "Accessibility.AndroidServiceInfo." #service_type_variant) |
| } // namespace |
| |
| BrowserAccessibilityStateImplAndroid::BrowserAccessibilityStateImplAndroid() { |
| ui::AccessibilityState::RegisterAccessibilityStateDelegate(this); |
| } |
| |
| BrowserAccessibilityStateImplAndroid::~BrowserAccessibilityStateImplAndroid() { |
| ui::AccessibilityState::UnregisterAccessibilityStateDelegate(this); |
| } |
| |
| void BrowserAccessibilityStateImplAndroid:: |
| RecordAccessibilityServiceInfoHistograms() { |
| int event_type_mask = |
| ui::AccessibilityState::GetAccessibilityServiceEventTypeMask(); |
| int feedback_type_mask = |
| ui::AccessibilityState::GetAccessibilityServiceFeedbackTypeMask(); |
| |
| int flags_mask = ui::AccessibilityState::GetAccessibilityServiceFlagsMask(); |
| |
| int capabilities_mask = |
| ui::AccessibilityState::GetAccessibilityServiceCapabilitiesMask(); |
| |
| std::vector<std::string> service_ids = |
| ui::AccessibilityState::GetAccessibilityServiceIds(); |
| |
| int len = service_ids.size(); |
| bool has_assistive_tech = false; |
| bool has_password_manager = false; |
| bool has_unknown = false; |
| |
| for (int i = 0; i < len; ++i) { |
| std::string service_id = service_ids[i]; |
| std::string service_package = service_id.erase(service_id.find("/")); |
| uint32_t service_hash = base::PersistentHash(service_package); |
| |
| if (base::Contains(kAssistiveTechPackageHashes, service_hash)) { |
| has_assistive_tech = true; |
| } else if (base::Contains(kPasswordPackageHashes, service_hash)) { |
| has_password_manager = true; |
| } else { |
| has_unknown = true; |
| } |
| } |
| |
| if (has_assistive_tech && has_password_manager && has_unknown) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, ALL_VARIANTS); |
| } else if (has_assistive_tech && has_password_manager) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, |
| ASSISTIVE_TECH_WITH_PASSWORD_MANAGER); |
| } else if (has_assistive_tech && has_unknown) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, ASSISTIVE_TECH_WITH_UNKNOWN); |
| } else if (has_password_manager && has_unknown) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, PASSWORD_MANAGER_WITH_UNKNOWN); |
| } else if (has_assistive_tech) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, ASSISTIVE_TECH); |
| } else if (has_password_manager) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, PASSWORD_MANAGER); |
| } else if (has_unknown) { |
| RECORD_ALL_HISTOGRAMS(event_type_mask, feedback_type_mask, flags_mask, |
| capabilities_mask, UNKNOWN); |
| } |
| } |
| |
| void BrowserAccessibilityStateImplAndroid:: |
| RecordAccessibilityServiceStatsHistogram(int event_type_mask, |
| int feedback_type_mask, |
| int flags_mask, |
| int capabilities_mask, |
| std::string histogram) { |
| EVENT_TYPE_HISTOGRAM(event_type_mask, ANNOUNCEMENT, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, ASSIST_READING_CONTEXT, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, GESTURE_DETECTION_END, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, GESTURE_DETECTION_START, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, NOTIFICATION_STATE_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_EXPLORATION_GESTURE_END, |
| histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_EXPLORATION_GESTURE_START, |
| histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_INTERACTION_END, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, TOUCH_INTERACTION_START, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_ACCESSIBILITY_FOCUSED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_ACCESSIBILITY_FOCUS_CLEARED, |
| histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_CLICKED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_CONTEXT_CLICKED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_FOCUSED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_HOVER_ENTER, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_HOVER_EXIT, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_LONG_CLICKED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_SCROLLED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_SELECTED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_TEXT_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, VIEW_TEXT_SELECTION_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, |
| VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOWS_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOW_CONTENT_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, WINDOW_STATE_CHANGED, histogram); |
| EVENT_TYPE_HISTOGRAM(event_type_mask, SPEECH_STATE_CHANGE, histogram); |
| |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, SPOKEN, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, HAPTIC, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, AUDIBLE, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, VISUAL, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, GENERIC, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, BRAILLE, histogram); |
| FEEDBACK_TYPE_HISTOGRAM(feedback_type_mask, ALL_MASK, histogram); |
| |
| FLAGS_HISTOGRAM(flags_mask, INCLUDE_NOT_IMPORTANT_VIEWS, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_TOUCH_EXPLORATION_MODE, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_ENHANCED_WEB_ACCESSIBILITY, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REPORT_VIEW_IDS, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_FILTER_KEY_EVENTS, histogram); |
| FLAGS_HISTOGRAM(flags_mask, RETRIEVE_INTERACTIVE_WINDOWS, histogram); |
| FLAGS_HISTOGRAM(flags_mask, FORCE_DIRECT_BOOT_AWARE, histogram); |
| FLAGS_HISTOGRAM(flags_mask, ENABLE_ACCESSIBILITY_VOLUME, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_ACCESSIBILITY_BUTTON, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_FINGERPRINT_GESTURES, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_MULTI_FINGER_GESTURES, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK, |
| histogram); |
| FLAGS_HISTOGRAM(flags_mask, SERVICE_HANDLES_DOUBLE_TAP, histogram); |
| FLAGS_HISTOGRAM(flags_mask, REQUEST_2_FINGER_PASSTHROUGH, histogram); |
| FLAGS_HISTOGRAM(flags_mask, SEND_MOTION_EVENTS, histogram); |
| FLAGS_HISTOGRAM(flags_mask, INPUT_METHOD_EDITOR, histogram); |
| |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_RETRIEVE_WINDOW_CONTENT, |
| histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_REQUEST_TOUCH_EXPLORATION, |
| histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, |
| CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY, histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_REQUEST_FILTER_KEY_EVENTS, |
| histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_CONTROL_MAGNIFICATION, |
| histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_PERFORM_GESTURES, histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_REQUEST_FINGERPRINT_GESTURES, |
| histogram); |
| CAPABILITY_TYPE_HISTOGRAM(capabilities_mask, CAN_TAKE_SCREENSHOT, histogram); |
| } |
| |
| void BrowserAccessibilityStateImplAndroid::OnAnimatorDurationScaleChanged() { |
| // We need to call into gfx::Animation and WebContentsImpl on the UI thread, |
| // so ensure that we setup the notification on the correct thread. |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| |
| gfx::Animation::UpdatePrefersReducedMotion(); |
| for (content::WebContentsImpl* wc : |
| content::WebContentsImpl::GetAllWebContents()) { |
| wc->OnWebPreferencesChanged(); |
| } |
| } |
| |
| void BrowserAccessibilityStateImplAndroid::OnDisplayInversionEnabledChanged( |
| bool enabled) { |
| // We need to call into GetInstanceForWeb on the UI thread, |
| // so ensure that we setup the notification on the correct thread. |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForWeb(); |
| native_theme->set_inverted_colors(enabled); |
| native_theme->NotifyOnNativeThemeUpdated(); |
| } |
| |
| void BrowserAccessibilityStateImplAndroid::OnContrastLevelChanged( |
| bool highContrastEnabled) { |
| // We need to call into GetInstanceForWeb on the UI thread, |
| // so ensure that we setup the notification on the correct thread. |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForWeb(); |
| native_theme->SetPreferredContrast( |
| highContrastEnabled ? ui::NativeTheme::PreferredContrast::kMore |
| : ui::NativeTheme::PreferredContrast::kNoPreference); |
| native_theme->set_prefers_reduced_transparency(highContrastEnabled); |
| native_theme->NotifyOnNativeThemeUpdated(); |
| } |
| |
| void BrowserAccessibilityStateImplAndroid::UpdateHistogramsOnOtherThread() { |
| BrowserAccessibilityStateImpl::UpdateHistogramsOnOtherThread(); |
| |
| // NOTE: this method is run from another thread to reduce jank, since |
| // there's no guarantee these system calls will return quickly. Be careful |
| // not to add any code that isn't safe to run from a non-main thread! |
| DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| |
| // Screen reader metric. |
| ui::AXMode mode = |
| BrowserAccessibilityStateImpl::GetInstance()->GetAccessibilityMode(); |
| UMA_HISTOGRAM_BOOLEAN("Accessibility.Android.ScreenReader", |
| mode.has_mode(ui::AXMode::kScreenReader)); |
| } |
| |
| void BrowserAccessibilityStateImplAndroid::UpdateUniqueUserHistograms() { |
| BrowserAccessibilityStateImpl::UpdateUniqueUserHistograms(); |
| |
| ui::AXMode mode = GetAccessibilityMode(); |
| UMA_HISTOGRAM_BOOLEAN("Accessibility.Android.ScreenReader.EveryReport", |
| mode.has_mode(ui::AXMode::kScreenReader)); |
| } |
| |
| // static |
| std::unique_ptr<BrowserAccessibilityStateImpl> |
| BrowserAccessibilityStateImpl::Create() { |
| return std::make_unique<BrowserAccessibilityStateImplAndroid>(); |
| } |
| |
| } // namespace content |