1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
#define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
#include <string>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/strings/string16.h"
#include "chrome/browser/accessibility/accessibility_events.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/accessibility/ax_enums.h"
class Profile;
template <typename T> struct DefaultSingletonTraits;
namespace views {
class View;
}
// NOTE: This class is part of the Accessibility Extension API, which lets
// extensions receive accessibility events. It's distinct from code that
// implements platform accessibility APIs like MSAA or ATK.
//
// Singleton class that adds listeners to many views, then sends an
// accessibility notification whenever a relevant event occurs in an
// accessible view.
//
// Views are not accessible by default. When you register a root widget,
// that widget and all of its descendants will start sending accessibility
// event notifications. You can then override the default behavior for
// specific descendants using other methods.
//
// You can use Profile::PauseAccessibilityEvents to prevent a flurry
// of accessibility events when a window is being created or initialized.
class AccessibilityEventRouterViews : public content::NotificationObserver {
public:
// Get the single instance of this class.
static AccessibilityEventRouterViews* GetInstance();
// Handle an accessibility event generated by a view.
void HandleAccessibilityEvent(
views::View* view, ui::AXEvent event_type);
// Handle a menu item being focused (separate because a menu item is
// not necessarily its own view).
void HandleMenuItemFocused(const base::string16& menu_name,
const base::string16& menu_item_name,
int item_index,
int item_count,
bool has_submenu);
// NotificationObserver implementation.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
private:
friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>;
FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
TestFocusNotification);
FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
MenuIndexAndCountForInvisibleMenu);
FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
AccessibilityFocusableView);
AccessibilityEventRouterViews();
~AccessibilityEventRouterViews() override;
// Call DispatchAccessibilityEvent using a view storage id.
static void DispatchEventOnViewStorageId(
int view_storage_id,
ui::AXEvent event);
// Checks the type of the view and calls one of the more specific
// Send*Notification methods, below.
void DispatchAccessibilityEvent(
views::View* view,
ui::AXEvent event);
// Each of these methods constructs an AccessibilityControlInfo object
// and sends a notification of a specific accessibility event.
static void SendButtonNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendStaticTextNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendLinkNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendMenuNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendTabNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendMenuItemNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendTreeNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendTreeItemNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendTextfieldNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendComboboxNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendCheckboxNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendWindowNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendSliderNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendAlertControlNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendTableNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
static void SendRowNotification(
views::View* view,
ui::AXEvent event,
Profile* profile);
// Return the name of a view.
static std::string GetViewName(views::View* view);
// Get the context of a view - the name of the enclosing group, toolbar, etc.
static std::string GetViewContext(views::View* view);
// Return a descendant of this view with a given accessible role, if found.
static views::View* FindDescendantWithAccessibleRole(
views::View* view,
ui::AXRole role);
// Recursively explore all menu items of |menu| and return in |count|
// the total number of items, and in |index| the 0-based index of
// |item|, if found. Initialize |count| to zero before calling this
// method. |index| will be unchanged if the item is not found, so
// initialize it to -1 to detect this case.
static void RecursiveGetMenuItemIndexAndCount(views::View* menu,
views::View* item,
int* index,
int* count);
// Recursively explore the subviews and return the text from the first
// subview with a role of STATIC_TEXT.
static std::string RecursiveGetStaticText(views::View* view);
// Returns the first ancestor of |view| (including |view|) that is
// accessible.
static views::View* FindFirstAccessibleAncestor(views::View* view);
// The profile associated with the most recent window event - used to
// figure out where to route a few events that can't be directly traced
// to a window with a profile (like menu events).
Profile* most_recent_profile_;
// The most recent accessibility focusable view is stored in view storage
// and is used to prevent multiple events from being dispatched on a
// hoverable view from its multiple children. This is the id for the most
// recent view we put in view storage.
const int most_recent_view_id_;
// Notification registrar so we can clear most_recent_profile_ when a
// profile is destroyed.
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRouterViews);
};
#endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
|