Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
      6 #define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
      7 #pragma once
      8 
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/gtest_prod_util.h"
     13 #include "base/memory/singleton.h"
     14 #include "base/task.h"
     15 #include "chrome/browser/accessibility_events.h"
     16 #include "ui/base/accessibility/accessibility_types.h"
     17 
     18 class Profile;
     19 namespace views {
     20 class View;
     21 }
     22 
     23 // NOTE: This class is part of the Accessibility Extension API, which lets
     24 // extensions receive accessibility events. It's distinct from code that
     25 // implements platform accessibility APIs like MSAA or ATK.
     26 //
     27 // Singleton class that adds listeners to many views, then sends an
     28 // accessibility notification whenever a relevant event occurs in an
     29 // accessible view.
     30 //
     31 // Views are not accessible by default. When you register a root widget,
     32 // that widget and all of its descendants will start sending accessibility
     33 // event notifications. You can then override the default behavior for
     34 // specific descendants using other methods.
     35 //
     36 // You can use Profile::PauseAccessibilityEvents to prevent a flurry
     37 // of accessibility events when a window is being created or initialized.
     38 class AccessibilityEventRouterViews {
     39  public:
     40   // Internal information about a particular view to override the
     41   // information we get directly from the view.
     42   struct ViewInfo {
     43     ViewInfo() : ignore(false) {}
     44 
     45     // If nonempty, will use this name instead of the view's label.
     46     std::string name;
     47 
     48     // If true, will ignore this widget and not send accessibility events.
     49     bool ignore;
     50   };
     51 
     52   // Get the single instance of this class.
     53   static AccessibilityEventRouterViews* GetInstance();
     54 
     55   // Handle an accessibility event generated by a view.
     56   void HandleAccessibilityEvent(
     57       views::View* view, ui::AccessibilityTypes::Event event_type);
     58 
     59   // Handle a menu item being focused (separate because a menu item is
     60   // not necessarily its own view).
     61   void HandleMenuItemFocused(
     62       const std::wstring& menu_name,
     63       const std::wstring& menu_item_name,
     64       int item_index,
     65       int item_count,
     66       bool has_submenu);
     67 
     68  private:
     69   AccessibilityEventRouterViews();
     70   virtual ~AccessibilityEventRouterViews();
     71 
     72   friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>;
     73   FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
     74                            TestFocusNotification);
     75 
     76   // Checks the type of the view and calls one of the more specific
     77   // Send*Notification methods, below.
     78   void DispatchAccessibilityNotification(
     79       views::View* view, NotificationType type);
     80 
     81   // Return the name of a view.
     82   std::string GetViewName(views::View* view);
     83 
     84   // Each of these methods constructs an AccessibilityControlInfo object
     85   // and sends a notification of a specific accessibility event.
     86   void SendButtonNotification(
     87       views::View* view, NotificationType type, Profile* profile);
     88   void SendLinkNotification(
     89       views::View* view, NotificationType type, Profile* profile);
     90   void SendMenuNotification(
     91       views::View* view, NotificationType type, Profile* profile);
     92   void SendMenuItemNotification(
     93       views::View* view, NotificationType type, Profile* profile);
     94   void SendLocationBarNotification(
     95       views::View* view, NotificationType type, Profile* profile);
     96   void SendTextfieldNotification(
     97       views::View* view, NotificationType type, Profile* profile);
     98   void SendComboboxNotification(
     99       views::View* view, NotificationType type, Profile* profile);
    100   void SendCheckboxNotification(
    101       views::View* view, NotificationType type, Profile* profile);
    102 
    103   // Return true if it's an event on a menu.
    104   bool IsMenuEvent(views::View* view, NotificationType type);
    105 
    106   // Recursively explore all menu items of |menu| and return in |count|
    107   // the total number of items, and in |index| the 0-based index of
    108   // |item|, if found. Initialize |count| to zero before calling this
    109   // method. |index| will be unchanged if the item is not found, so
    110   // initialize it to -1 to detect this case.
    111   void RecursiveGetMenuItemIndexAndCount(
    112       views::View* menu, views::View* item, int* index, int* count);
    113 
    114   // The profile associated with the most recent window event  - used to
    115   // figure out where to route a few events that can't be directly traced
    116   // to a window with a profile (like menu events).
    117   Profile* most_recent_profile_;
    118 
    119   // Used to defer handling of some events until the next time
    120   // through the event loop.
    121   ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_;
    122 };
    123 
    124 #endif  // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
    125