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