Commit c837b2b4 authored by dmazzoni@chromium.org's avatar dmazzoni@chromium.org

Add a context field to the accessibility extension API.

This makes it possible to provide more helpful spoken feedback when focusing
a toolbar button or infobar button - e.g. it can now read the full text of
the infobar when you move focus to any of its buttons.

BUG=106724
TEST=Adds new unit tests; will need new ChromeVox push to test manually.
Review URL: http://codereview.chromium.org/8850004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114640 0039d316-1c4b-4281-b951-d872f2087c98
parent b7544d08
......@@ -33,8 +33,9 @@ void SendAccessibilityVolumeNotification(double volume, bool is_muted) {
}
AccessibilityControlInfo::AccessibilityControlInfo(
Profile* profile, const std::string& control_name)
: AccessibilityEventInfo(profile), name_(control_name) {
Profile* profile, const std::string& name)
: AccessibilityEventInfo(profile),
name_(name) {
}
AccessibilityControlInfo::~AccessibilityControlInfo() {
......@@ -43,6 +44,8 @@ AccessibilityControlInfo::~AccessibilityControlInfo() {
void AccessibilityControlInfo::SerializeToDict(DictionaryValue *dict) const {
dict->SetString(keys::kNameKey, name_);
dict->SetString(keys::kTypeKey, type());
if (!context_.empty())
dict->SetString(keys::kContextKey, context_);
}
AccessibilityWindowInfo::AccessibilityWindowInfo(Profile* profile,
......@@ -55,8 +58,10 @@ const char* AccessibilityWindowInfo::type() const {
}
AccessibilityButtonInfo::AccessibilityButtonInfo(Profile* profile,
const std::string& button_name)
const std::string& button_name,
const std::string& context)
: AccessibilityControlInfo(profile, button_name) {
set_context(context);
}
const char* AccessibilityButtonInfo::type() const {
......@@ -64,8 +69,11 @@ const char* AccessibilityButtonInfo::type() const {
}
AccessibilityLinkInfo::AccessibilityLinkInfo(Profile* profile,
const std::string& link_name)
: AccessibilityControlInfo(profile, link_name) { }
const std::string& link_name,
const std::string& context)
: AccessibilityControlInfo(profile, link_name) {
set_context(context);
}
const char* AccessibilityLinkInfo::type() const {
return keys::kTypeLink;
......@@ -74,6 +82,7 @@ const char* AccessibilityLinkInfo::type() const {
AccessibilityRadioButtonInfo::AccessibilityRadioButtonInfo(
Profile* profile,
const std::string& name,
const std::string& context,
bool checked,
int item_index,
int item_count)
......@@ -81,6 +90,7 @@ AccessibilityRadioButtonInfo::AccessibilityRadioButtonInfo(
checked_(checked),
item_index_(item_index),
item_count_(item_count) {
set_context(context);
}
const char* AccessibilityRadioButtonInfo::type() const {
......@@ -97,9 +107,11 @@ void AccessibilityRadioButtonInfo::SerializeToDict(
AccessibilityCheckboxInfo::AccessibilityCheckboxInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool checked)
: AccessibilityControlInfo(profile, name),
checked_(checked) {
set_context(context);
}
const char* AccessibilityCheckboxInfo::type() const {
......@@ -113,11 +125,13 @@ void AccessibilityCheckboxInfo::SerializeToDict(DictionaryValue *dict) const {
AccessibilityTabInfo::AccessibilityTabInfo(Profile* profile,
const std::string& tab_name,
const std::string& context,
int tab_index,
int tab_count)
: AccessibilityControlInfo(profile, tab_name),
tab_index_(tab_index),
tab_count_(tab_count) {
set_context(context);
}
const char* AccessibilityTabInfo::type() const {
......@@ -132,6 +146,7 @@ void AccessibilityTabInfo::SerializeToDict(DictionaryValue *dict) const {
AccessibilityComboBoxInfo::AccessibilityComboBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
const std::string& value,
int item_index,
int item_count)
......@@ -139,6 +154,7 @@ AccessibilityComboBoxInfo::AccessibilityComboBoxInfo(Profile* profile,
value_(value),
item_index_(item_index),
item_count_(item_count) {
set_context(context);
}
const char* AccessibilityComboBoxInfo::type() const {
......@@ -154,12 +170,14 @@ void AccessibilityComboBoxInfo::SerializeToDict(DictionaryValue *dict) const {
AccessibilityTextBoxInfo::AccessibilityTextBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool password)
: AccessibilityControlInfo(profile, name),
value_(""),
password_(password),
selection_start_(0),
selection_end_(0) {
set_context(context);
}
const char* AccessibilityTextBoxInfo::type() const {
......@@ -176,6 +194,7 @@ void AccessibilityTextBoxInfo::SerializeToDict(DictionaryValue *dict) const {
AccessibilityListBoxInfo::AccessibilityListBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
const std::string& value,
int item_index,
int item_count)
......@@ -183,6 +202,7 @@ AccessibilityListBoxInfo::AccessibilityListBoxInfo(Profile* profile,
value_(value),
item_index_(item_index),
item_count_(item_count) {
set_context(context);
}
const char* AccessibilityListBoxInfo::type() const {
......@@ -237,6 +257,7 @@ const char* AccessibilityMenuInfo::type() const {
AccessibilityMenuItemInfo::AccessibilityMenuItemInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool has_submenu,
int item_index,
int item_count)
......@@ -244,6 +265,7 @@ AccessibilityMenuItemInfo::AccessibilityMenuItemInfo(Profile* profile,
has_submenu_(has_submenu),
item_index_(item_index),
item_count_(item_count) {
set_context(context);
}
const char* AccessibilityMenuItemInfo::type() const {
......
......@@ -59,11 +59,20 @@ class AccessibilityControlInfo : public AccessibilityEventInfo {
const std::string& name() const { return name_; }
const std::string& context() const { return context_; }
protected:
AccessibilityControlInfo(Profile* profile, const std::string& control_name);
AccessibilityControlInfo(Profile* profile,
const std::string& name);
void set_context(const std::string& context) { context_ = context; }
// The name of the control, like "OK" or "Password".
std::string name_;
// A string describing the context of the control, such as the name of
// the group or toolbar it's contained in.
std::string context_;
};
// Accessibility information about a window passed to onWindowOpened
......@@ -79,7 +88,9 @@ class AccessibilityWindowInfo : public AccessibilityControlInfo {
// and onControlAction event listeners.
class AccessibilityButtonInfo : public AccessibilityControlInfo {
public:
AccessibilityButtonInfo(Profile* profile, const std::string& button_name);
AccessibilityButtonInfo(Profile* profile,
const std::string& button_name,
const std::string& context);
virtual const char* type() const OVERRIDE;
};
......@@ -88,7 +99,9 @@ class AccessibilityButtonInfo : public AccessibilityControlInfo {
// and onControlAction event listeners.
class AccessibilityLinkInfo : public AccessibilityControlInfo {
public:
AccessibilityLinkInfo(Profile* profile, const std::string& link_name);
AccessibilityLinkInfo(Profile* profile,
const std::string& link_name,
const std::string& context);
virtual const char* type() const OVERRIDE;
};
......@@ -99,6 +112,7 @@ class AccessibilityRadioButtonInfo : public AccessibilityControlInfo {
public:
AccessibilityRadioButtonInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool checked,
int item_index,
int item_count);
......@@ -126,6 +140,7 @@ class AccessibilityCheckboxInfo : public AccessibilityControlInfo {
public:
AccessibilityCheckboxInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool checked);
virtual const char* type() const OVERRIDE;
......@@ -146,6 +161,7 @@ class AccessibilityTabInfo : public AccessibilityControlInfo {
public:
AccessibilityTabInfo(Profile* profile,
const std::string& tab_name,
const std::string& context,
int tab_index,
int tab_count);
......@@ -173,6 +189,7 @@ class AccessibilityComboBoxInfo : public AccessibilityControlInfo {
public:
AccessibilityComboBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
const std::string& value,
int item_index,
int item_count);
......@@ -205,6 +222,7 @@ class AccessibilityTextBoxInfo : public AccessibilityControlInfo {
public:
AccessibilityTextBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool password);
virtual const char* type() const OVERRIDE;
......@@ -236,6 +254,7 @@ class AccessibilityListBoxInfo : public AccessibilityControlInfo {
public:
AccessibilityListBoxInfo(Profile* profile,
const std::string& name,
const std::string& context,
const std::string& value,
int item_index,
int item_count);
......@@ -305,6 +324,7 @@ class AccessibilityMenuItemInfo : public AccessibilityControlInfo {
public:
AccessibilityMenuItemInfo(Profile* profile,
const std::string& name,
const std::string& context,
bool has_submenu,
int item_index,
int item_count);
......
......@@ -9,6 +9,7 @@ namespace extension_accessibility_api_constants {
// String keys for AccessibilityObject properties.
const char kTypeKey[] = "type";
const char kNameKey[] = "name";
const char kContextKey[] = "context";
const char kDetailsKey[] = "details";
const char kValueKey[] = "details.value";
const char kPasswordKey[] = "details.isPassword";
......
......@@ -13,6 +13,7 @@ namespace extension_accessibility_api_constants {
// Keys.
extern const char kTypeKey[];
extern const char kNameKey[];
extern const char kContextKey[];
extern const char kDetailsKey[];
extern const char kValueKey[];
extern const char kPasswordKey[];
......
......@@ -44,7 +44,7 @@ TEST_F(WizardAccessibilityHandlerTest, TestFocusEvents) {
// Test a simple control.
std::string button_name = "Save";
AccessibilityButtonInfo button_info(NULL, button_name);
AccessibilityButtonInfo button_info(NULL, button_name, "");
handler.DescribeAccessibilityEvent(
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
&button_info,
......@@ -55,7 +55,7 @@ TEST_F(WizardAccessibilityHandlerTest, TestFocusEvents) {
// Test a control with multiple states.
std::string checkbox_name = "Accessibility";
AccessibilityCheckboxInfo checkbox_info(NULL, checkbox_name, false);
AccessibilityCheckboxInfo checkbox_info(NULL, checkbox_name, "", false);
handler.DescribeAccessibilityEvent(
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
&checkbox_info,
......@@ -76,7 +76,7 @@ TEST_F(WizardAccessibilityHandlerTest, TestFocusEvents) {
std::string combobox_name = "Language";
std::string combobox_value = "English";
AccessibilityComboBoxInfo combobox_info(
NULL, combobox_name, combobox_value, 12, 35);
NULL, combobox_name, "", combobox_value, 12, 35);
handler.DescribeAccessibilityEvent(
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
&combobox_info,
......@@ -92,7 +92,7 @@ TEST_F(WizardAccessibilityHandlerTest, TestTextEvents) {
std::string description;
EarconType earcon;
AccessibilityTextBoxInfo textbox_info(NULL, "", false);
AccessibilityTextBoxInfo textbox_info(NULL, "", "", false);
handler.DescribeAccessibilityEvent(
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
&textbox_info,
......
......@@ -551,8 +551,11 @@ void LocationBarViewGtk::OnKillFocus() {
void LocationBarViewGtk::OnSetFocus() {
Profile* profile = browser_->profile();
AccessibilityTextBoxInfo info(profile,
l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION), false);
AccessibilityTextBoxInfo info(
profile,
l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION),
std::string(),
false);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
content::Source<Profile>(profile),
......
......@@ -91,6 +91,7 @@ void AccessibilityEventRouterViews::HandleMenuItemFocused(
AccessibilityMenuItemInfo info(most_recent_profile_,
UTF16ToUTF8(menu_item_name),
UTF16ToUTF8(menu_name),
has_submenu,
item_index,
item_count);
......@@ -170,22 +171,26 @@ void AccessibilityEventRouterViews::DispatchAccessibilityNotification(
}
}
// static
void AccessibilityEventRouterViews::SendButtonNotification(
views::View* view,
int type,
Profile* profile) {
AccessibilityButtonInfo info(profile, GetViewName(view));
AccessibilityButtonInfo info(
profile, GetViewName(view), GetViewContext(view));
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendLinkNotification(
views::View* view,
int type,
Profile* profile) {
AccessibilityLinkInfo info(profile, GetViewName(view));
AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view));
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendMenuNotification(
views::View* view,
int type,
......@@ -194,11 +199,13 @@ void AccessibilityEventRouterViews::SendMenuNotification(
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendMenuItemNotification(
views::View* view,
int type,
Profile* profile) {
std::string name = GetViewName(view);
std::string context = GetViewContext(view);
bool has_submenu = false;
int index = -1;
......@@ -217,10 +224,12 @@ void AccessibilityEventRouterViews::SendMenuItemNotification(
RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count);
}
AccessibilityMenuItemInfo info(profile, name, has_submenu, index, count);
AccessibilityMenuItemInfo info(
profile, name, context, has_submenu, index, count);
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendTextfieldNotification(
views::View* view,
int type,
......@@ -228,14 +237,16 @@ void AccessibilityEventRouterViews::SendTextfieldNotification(
ui::AccessibleViewState state;
view->GetAccessibleState(&state);
std::string name = UTF16ToUTF8(state.name);
std::string context = GetViewContext(view);
bool password =
(state.state & ui::AccessibilityTypes::STATE_PROTECTED) != 0;
AccessibilityTextBoxInfo info(profile, name, password);
AccessibilityTextBoxInfo info(profile, name, context, password);
std::string value = UTF16ToUTF8(state.value);
info.SetValue(value, state.selection_start, state.selection_end);
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendComboboxNotification(
views::View* view,
int type,
......@@ -244,11 +255,13 @@ void AccessibilityEventRouterViews::SendComboboxNotification(
view->GetAccessibleState(&state);
std::string name = UTF16ToUTF8(state.name);
std::string value = UTF16ToUTF8(state.value);
std::string context = GetViewContext(view);
AccessibilityComboBoxInfo info(
profile, name, value, state.index, state.count);
profile, name, context, value, state.index, state.count);
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendCheckboxNotification(
views::View* view,
int type,
......@@ -257,11 +270,16 @@ void AccessibilityEventRouterViews::SendCheckboxNotification(
view->GetAccessibleState(&state);
std::string name = UTF16ToUTF8(state.name);
std::string value = UTF16ToUTF8(state.value);
std::string context = GetViewContext(view);
AccessibilityCheckboxInfo info(
profile, name, state.state == ui::AccessibilityTypes::STATE_CHECKED);
profile,
name,
context,
state.state == ui::AccessibilityTypes::STATE_CHECKED);
SendAccessibilityNotification(type, &info);
}
// static
void AccessibilityEventRouterViews::SendWindowNotification(
views::View* view,
int type,
......@@ -283,12 +301,68 @@ void AccessibilityEventRouterViews::SendWindowNotification(
SendAccessibilityNotification(type, &info);
}
// static
std::string AccessibilityEventRouterViews::GetViewName(views::View* view) {
ui::AccessibleViewState state;
view->GetAccessibleState(&state);
return UTF16ToUTF8(state.name);
}
// static
std::string AccessibilityEventRouterViews::GetViewContext(views::View* view) {
for (views::View* parent = view->parent();
parent;
parent = parent->parent()) {
ui::AccessibleViewState state;
parent->GetAccessibleState(&state);
// Two cases are handled right now. More could be added in the future
// depending on how the UI evolves.
// A control in a toolbar should use the toolbar's accessible name
// as the context.
if (state.role == ui::AccessibilityTypes::ROLE_TOOLBAR &&
!state.name.empty()) {
return UTF16ToUTF8(state.name);
}
// A control inside of an alert (like an infobar) should grab the
// first static text descendant as the context; that's the prompt.
if (state.role == ui::AccessibilityTypes::ROLE_ALERT) {
views::View* static_text_child = FindDescendantWithAccessibleRole(
parent, ui::AccessibilityTypes::ROLE_STATICTEXT);
if (static_text_child) {
ui::AccessibleViewState state;
static_text_child->GetAccessibleState(&state);
if (!state.name.empty())
return UTF16ToUTF8(state.name);
}
return std::string();
}
}
return std::string();
}
// static
views::View* AccessibilityEventRouterViews::FindDescendantWithAccessibleRole(
views::View* view, ui::AccessibilityTypes::Role role) {
ui::AccessibleViewState state;
view->GetAccessibleState(&state);
if (state.role == role)
return view;
for (int i = 0; i < view->child_count(); i++) {
views::View* child = view->child_at(i);
views::View* result = FindDescendantWithAccessibleRole(child, role);
if (result)
return result;
}
return NULL;
}
// static
bool AccessibilityEventRouterViews::IsMenuEvent(
views::View* view,
int type) {
......@@ -310,6 +384,7 @@ bool AccessibilityEventRouterViews::IsMenuEvent(
return false;
}
// static
void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount(
views::View* menu,
views::View* item,
......@@ -332,6 +407,7 @@ void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount(
}
}
// static
std::string AccessibilityEventRouterViews::RecursiveGetStaticText(
views::View* view) {
ui::AccessibleViewState state;
......
......@@ -77,44 +77,72 @@ class AccessibilityEventRouterViews {
// Checks the type of the view and calls one of the more specific
// Send*Notification methods, below.
void DispatchAccessibilityNotification(
views::View* view, int type);
views::View* view,
int type);
// Each of these methods constructs an AccessibilityControlInfo object
// and sends a notification of a specific accessibility event.
void SendButtonNotification(
views::View* view, int type, Profile* profile);
void SendLinkNotification(
views::View* view, int type, Profile* profile);
void SendMenuNotification(
views::View* view, int type, Profile* profile);
void SendMenuItemNotification(
views::View* view, int type, Profile* profile);
void SendTextfieldNotification(
views::View* view, int type, Profile* profile);
void SendComboboxNotification(
views::View* view, int type, Profile* profile);
void SendCheckboxNotification(
views::View* view, int type, Profile* profile);
void SendWindowNotification(
views::View* view, int type, Profile* profile);
static void SendButtonNotification(
views::View* view,
int type,
Profile* profile);
static void SendLinkNotification(
views::View* view,
int type,
Profile* profile);
static void SendMenuNotification(
views::View* view,
int type,
Profile* profile);
static void SendMenuItemNotification(
views::View* view,
int type,
Profile* profile);
static void SendTextfieldNotification(
views::View* view,
int type,
Profile* profile);
static void SendComboboxNotification(
views::View* view,
int type,
Profile* profile);
static void SendCheckboxNotification(
views::View* view,
int type,
Profile* profile);
static void SendWindowNotification(
views::View* view,
int type,
Profile* profile);
// Return the name of a view.
std::string GetViewName(views::View* 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::AccessibilityTypes::Role role);
// Return true if it's an event on a menu.
bool IsMenuEvent(views::View* view, int type);
static bool IsMenuEvent(views::View* view,
int 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);
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.
std::string RecursiveGetStaticText(views::View* view);
static std::string RecursiveGetStaticText(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
......
......@@ -14,7 +14,9 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/native_widget.h"
......@@ -84,6 +86,25 @@ class AccessibilityWindowDelegate : public views::WidgetDelegate {
views::View* contents_;
};
class ViewWithNameAndRole : public views::View {
public:
explicit ViewWithNameAndRole(const string16& name,
ui::AccessibilityTypes::Role role)
: name_(name),
role_(role) {
}
void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
views::View::GetAccessibleState(state);
state->name = name_;
state->role = role_;
}
private:
string16 name_;
ui::AccessibilityTypes::Role role_;
};
class AccessibilityEventRouterViewsTest
: public testing::Test,
public content::NotificationObserver {
......@@ -114,11 +135,13 @@ class AccessibilityEventRouterViewsTest
content::Details<const AccessibilityControlInfo>(details).ptr();
focus_event_count_++;
last_control_name_ = info->name();
last_control_context_ = info->context();
}
MessageLoopForUI message_loop_;
int focus_event_count_;
std::string last_control_name_;
std::string last_control_context_;
};
TEST_F(AccessibilityEventRouterViewsTest, TestFocusNotification) {
......@@ -184,4 +207,90 @@ TEST_F(AccessibilityEventRouterViewsTest, TestFocusNotification) {
window->CloseNow();
}
TEST_F(AccessibilityEventRouterViewsTest, TestToolbarContext) {
const char kToolbarNameASCII[] = "MyToolbar";
const char kButtonNameASCII[] = "MyButton";
// Create a toolbar with a button.
views::View* contents = new ViewWithNameAndRole(
ASCIIToUTF16(kToolbarNameASCII),
ui::AccessibilityTypes::ROLE_TOOLBAR);
views::NativeTextButton* button = new views::NativeTextButton(
NULL, ASCIIToUTF16(kButtonNameASCII));
contents->AddChildView(button);
// Put the view in a window.
views::Widget* window = CreateWindowWithContents(contents);
// Start listening to ACCESSIBILITY_CONTROL_FOCUSED notifications.
content::NotificationRegistrar registrar;
registrar.Add(this,
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
content::NotificationService::AllSources());
// Switch on accessibility event notifications.
ExtensionAccessibilityEventRouter* accessibility_event_router =
ExtensionAccessibilityEventRouter::GetInstance();
accessibility_event_router->SetAccessibilityEnabled(true);
// Create a profile and associate it with this window.
TestingProfile profile;
window->SetNativeWindowProperty(Profile::kProfileKey, &profile);
// Set focus to the button.
focus_event_count_ = 0;
button->RequestFocus();
// Test that we got the event with the expected name and context.
EXPECT_EQ(1, focus_event_count_);
EXPECT_EQ(kButtonNameASCII, last_control_name_);
EXPECT_EQ(kToolbarNameASCII, last_control_context_);
window->CloseNow();
}
TEST_F(AccessibilityEventRouterViewsTest, TestAlertContext) {
const char kAlertTextASCII[] = "MyAlertText";
const char kButtonNameASCII[] = "MyButton";
// Create an alert with static text and a button, similar to an infobar.
views::View* contents = new ViewWithNameAndRole(
string16(),
ui::AccessibilityTypes::ROLE_ALERT);
views::Label* label = new views::Label(ASCIIToUTF16(kAlertTextASCII));
contents->AddChildView(label);
views::NativeTextButton* button = new views::NativeTextButton(
NULL, ASCIIToUTF16(kButtonNameASCII));
contents->AddChildView(button);
// Put the view in a window.
views::Widget* window = CreateWindowWithContents(contents);
// Start listening to ACCESSIBILITY_CONTROL_FOCUSED notifications.
content::NotificationRegistrar registrar;
registrar.Add(this,
chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
content::NotificationService::AllSources());
// Switch on accessibility event notifications.
ExtensionAccessibilityEventRouter* accessibility_event_router =
ExtensionAccessibilityEventRouter::GetInstance();
accessibility_event_router->SetAccessibilityEnabled(true);
// Create a profile and associate it with this window.
TestingProfile profile;
window->SetNativeWindowProperty(Profile::kProfileKey, &profile);
// Set focus to the button.
focus_event_count_ = 0;
button->RequestFocus();
// Test that we got the event with the expected name and context.
EXPECT_EQ(1, focus_event_count_);
EXPECT_EQ(kButtonNameASCII, last_control_name_);
EXPECT_EQ(kAlertTextASCII, last_control_context_);
window->CloseNow();
}
#endif // defined(TOOLKIT_VIEWS)
......@@ -17,6 +17,11 @@
"type": "string",
"description": "The localized name of the object, like OK or Password. Do not rely on an exact string match because the text will be in the user's language and may change in the future."
},
"context": {
"type": "string",
"description": "The localized name of the context for the object, like the name of the surrounding toolbar or group of controls.",
"optional": true
},
"details": {
"description": "Other details like the state, depending on the type of object.",
"optional": true,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment