// Copyright (c) 2011 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_EVENT_ROUTER_VIEWS_H_
#define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
#pragma once
#include <string>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/singleton.h"
#include "base/task.h"
#include "chrome/browser/accessibility_events.h"
#include "ui/base/accessibility/accessibility_types.h"
class Profile;
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:
// Internal information about a particular view to override the
// information we get directly from the view.
struct ViewInfo {
ViewInfo() : ignore(false) {}
// If nonempty, will use this name instead of the view's label.
std::string name;
// If true, will ignore this widget and not send accessibility events.
bool ignore;
};
// Get the single instance of this class.
static AccessibilityEventRouterViews* GetInstance();
// Handle an accessibility event generated by a view.
void HandleAccessibilityEvent(
views::View* view, ui::AccessibilityTypes::Event event_type);
// Handle a menu item being focused (separate because a menu item is
// not necessarily its own view).
void HandleMenuItemFocused(
const std::wstring& menu_name,
const std::wstring& menu_item_name,
int item_index,
int item_count,
bool has_submenu);
private:
AccessibilityEventRouterViews();
virtual ~AccessibilityEventRouterViews();
friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>;
FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
TestFocusNotification);
// Checks the type of the view and calls one of the more specific
// Send*Notification methods, below.
void DispatchAccessibilityNotification(
views::View* view, NotificationType type);
// Return the name of a view.
std::string GetViewName(views::View* view);
// Each of these methods constructs an AccessibilityControlInfo object
// and sends a notification of a specific accessibility event.
void SendButtonNotification(
views::View* view, NotificationType type, Profile* profile);
void SendLinkNotification(
views::View* view, NotificationType type, Profile* profile);
void SendMenuNotification(
views::View* view, NotificationType type, Profile* profile);
void SendMenuItemNotification(
views::View* view, NotificationType type, Profile* profile);
void SendLocationBarNotification(
views::View* view, NotificationType type, Profile* profile);
void SendTextfieldNotification(
views::View* view, NotificationType type, Profile* profile);
void SendComboboxNotification(
views::View* view, NotificationType type, Profile* profile);
void SendCheckboxNotification(
views::View* view, NotificationType type, Profile* profile);
// Return true if it's an event on a menu.
bool IsMenuEvent(views::View* view, NotificationType type);
// 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.
void RecursiveGetMenuItemIndexAndCount(
views::View* menu, views::View* item, int* index, int* count);
// 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_;
// Used to defer handling of some events until the next time
// through the event loop.
ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_;
};
#endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_