[safe-browsing] Database full hash matches like prefix match.
[chromium-blink-merge.git] / chrome / browser / accessibility / accessibility_extension_api.cc
blob26020dc2acd09dd3dfb0bbd09e0e994cd1104315
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/accessibility/accessibility_extension_api.h"
7 #include "base/json/json_writer.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/values.h"
10 #include "chrome/browser/accessibility/accessibility_extension_api_constants.h"
11 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
15 #include "chrome/browser/infobars/infobar_service.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/extensions/api/experimental_accessibility.h"
18 #include "components/infobars/core/infobar.h"
19 #include "content/public/browser/browser_accessibility_state.h"
20 #include "extensions/browser/event_router.h"
21 #include "extensions/browser/extension_host.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/browser/lazy_background_task_queue.h"
24 #include "extensions/common/error_utils.h"
25 #include "extensions/common/manifest_handlers/background_info.h"
27 namespace keys = extension_accessibility_api_constants;
28 namespace experimental_accessibility =
29 extensions::api::experimental_accessibility;
31 // Returns the AccessibilityControlInfo serialized into a JSON string,
32 // consisting of an array of a single object of type AccessibilityObject,
33 // as defined in the accessibility extension api's json schema.
34 scoped_ptr<base::ListValue> ControlInfoToEventArguments(
35 const AccessibilityEventInfo* info) {
36 base::DictionaryValue* dict = new base::DictionaryValue();
37 info->SerializeToDict(dict);
39 scoped_ptr<base::ListValue> args(new base::ListValue());
40 args->Append(dict);
41 return args.Pass();
44 ExtensionAccessibilityEventRouter*
45 ExtensionAccessibilityEventRouter::GetInstance() {
46 return Singleton<ExtensionAccessibilityEventRouter>::get();
49 ExtensionAccessibilityEventRouter::ExtensionAccessibilityEventRouter()
50 : enabled_(false) {
53 ExtensionAccessibilityEventRouter::~ExtensionAccessibilityEventRouter() {
54 control_event_callback_.Reset();
57 void ExtensionAccessibilityEventRouter::SetAccessibilityEnabled(bool enabled) {
58 enabled_ = enabled;
61 bool ExtensionAccessibilityEventRouter::IsAccessibilityEnabled() const {
62 return enabled_;
65 void ExtensionAccessibilityEventRouter::SetControlEventCallbackForTesting(
66 ControlEventCallback control_event_callback) {
67 DCHECK(control_event_callback_.is_null());
68 control_event_callback_ = control_event_callback;
71 void ExtensionAccessibilityEventRouter::ClearControlEventCallback() {
72 control_event_callback_.Reset();
75 void ExtensionAccessibilityEventRouter::HandleWindowEvent(
76 ui::AXEvent event,
77 const AccessibilityWindowInfo* info) {
78 if (!control_event_callback_.is_null())
79 control_event_callback_.Run(event, info);
81 if (event == ui::AX_EVENT_ALERT)
82 OnWindowOpened(info);
85 void ExtensionAccessibilityEventRouter::HandleMenuEvent(
86 ui::AXEvent event,
87 const AccessibilityMenuInfo* info) {
88 switch (event) {
89 case ui::AX_EVENT_MENU_START:
90 case ui::AX_EVENT_MENU_POPUP_START:
91 OnMenuOpened(info);
92 break;
93 case ui::AX_EVENT_MENU_END:
94 case ui::AX_EVENT_MENU_POPUP_END:
95 OnMenuClosed(info);
96 break;
97 case ui::AX_EVENT_FOCUS:
98 OnControlFocused(info);
99 break;
100 default:
101 NOTREACHED();
105 void ExtensionAccessibilityEventRouter::HandleControlEvent(
106 ui::AXEvent event,
107 const AccessibilityControlInfo* info) {
108 if (!control_event_callback_.is_null())
109 control_event_callback_.Run(event, info);
111 switch (event) {
112 case ui::AX_EVENT_TEXT_CHANGED:
113 case ui::AX_EVENT_SELECTION_CHANGED:
114 OnTextChanged(info);
115 break;
116 case ui::AX_EVENT_VALUE_CHANGED:
117 case ui::AX_EVENT_ALERT:
118 OnControlAction(info);
119 break;
120 case ui::AX_EVENT_FOCUS:
121 OnControlFocused(info);
122 break;
123 default:
124 NOTREACHED();
128 void ExtensionAccessibilityEventRouter::OnWindowOpened(
129 const AccessibilityWindowInfo* info) {
130 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
131 DispatchEvent(info->profile(),
132 experimental_accessibility::OnWindowOpened::kEventName,
133 args.Pass());
136 void ExtensionAccessibilityEventRouter::OnControlFocused(
137 const AccessibilityControlInfo* info) {
138 last_focused_control_dict_.Clear();
139 info->SerializeToDict(&last_focused_control_dict_);
140 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
141 DispatchEvent(info->profile(),
142 experimental_accessibility::OnControlFocused::kEventName,
143 args.Pass());
146 void ExtensionAccessibilityEventRouter::OnControlAction(
147 const AccessibilityControlInfo* info) {
148 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
149 DispatchEvent(info->profile(),
150 experimental_accessibility::OnControlAction::kEventName,
151 args.Pass());
154 void ExtensionAccessibilityEventRouter::OnTextChanged(
155 const AccessibilityControlInfo* info) {
156 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
157 DispatchEvent(info->profile(),
158 experimental_accessibility::OnTextChanged::kEventName,
159 args.Pass());
162 void ExtensionAccessibilityEventRouter::OnMenuOpened(
163 const AccessibilityMenuInfo* info) {
164 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
165 DispatchEvent(info->profile(),
166 experimental_accessibility::OnMenuOpened::kEventName,
167 args.Pass());
170 void ExtensionAccessibilityEventRouter::OnMenuClosed(
171 const AccessibilityMenuInfo* info) {
172 scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
173 DispatchEvent(info->profile(),
174 experimental_accessibility::OnMenuClosed::kEventName,
175 args.Pass());
178 void ExtensionAccessibilityEventRouter::OnChromeVoxLoadStateChanged(
179 Profile* profile,
180 bool loading,
181 bool make_announcements) {
182 scoped_ptr<base::ListValue> event_args(new base::ListValue());
183 event_args->Append(base::Value::CreateBooleanValue(loading));
184 event_args->Append(base::Value::CreateBooleanValue(make_announcements));
185 ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(profile,
186 experimental_accessibility::OnChromeVoxLoadStateChanged::kEventName,
187 event_args.Pass());
190 // Static.
191 void ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(
192 Profile* profile,
193 const char* event_name,
194 scoped_ptr<base::ListValue> event_args) {
195 extensions::ExtensionSystem* system =
196 extensions::ExtensionSystem::Get(profile);
197 if (!system)
198 return;
199 scoped_ptr<extensions::Event> event(new extensions::Event(event_name,
200 event_args.Pass()));
201 system->event_router()->DispatchEventWithLazyListener(
202 extension_misc::kChromeVoxExtensionId, event.Pass());
205 void ExtensionAccessibilityEventRouter::DispatchEvent(
206 Profile* profile,
207 const char* event_name,
208 scoped_ptr<base::ListValue> event_args) {
209 if (!enabled_ || !profile)
210 return;
211 extensions::EventRouter* event_router = extensions::EventRouter::Get(profile);
212 if (!event_router)
213 return;
215 scoped_ptr<extensions::Event> event(new extensions::Event(
216 event_name, event_args.Pass()));
217 event_router->BroadcastEvent(event.Pass());
220 bool AccessibilitySetAccessibilityEnabledFunction::RunSync() {
221 bool enabled;
222 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
223 ExtensionAccessibilityEventRouter::GetInstance()
224 ->SetAccessibilityEnabled(enabled);
225 return true;
228 bool AccessibilitySetNativeAccessibilityEnabledFunction::RunSync() {
229 bool enabled;
230 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
231 if (enabled) {
232 content::BrowserAccessibilityState::GetInstance()->
233 EnableAccessibility();
234 } else {
235 content::BrowserAccessibilityState::GetInstance()->
236 DisableAccessibility();
238 return true;
241 bool AccessibilityGetFocusedControlFunction::RunSync() {
242 // Get the serialized dict from the last focused control and return it.
243 // However, if the dict is empty, that means we haven't seen any focus
244 // events yet, so return null instead.
245 ExtensionAccessibilityEventRouter *accessibility_event_router =
246 ExtensionAccessibilityEventRouter::GetInstance();
247 base::DictionaryValue *last_focused_control_dict =
248 accessibility_event_router->last_focused_control_dict();
249 if (last_focused_control_dict->size()) {
250 SetResult(last_focused_control_dict->DeepCopyWithoutEmptyChildren());
251 } else {
252 SetResult(base::Value::CreateNullValue());
254 return true;
257 bool AccessibilityGetAlertsForTabFunction::RunSync() {
258 int tab_id;
259 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id));
261 TabStripModel* tab_strip = NULL;
262 content::WebContents* contents = NULL;
263 int tab_index = -1;
264 if (!extensions::ExtensionTabUtil::GetTabById(tab_id,
265 GetProfile(),
266 include_incognito(),
267 NULL,
268 &tab_strip,
269 &contents,
270 &tab_index)) {
271 error_ = extensions::ErrorUtils::FormatErrorMessage(
272 extensions::tabs_constants::kTabNotFoundError,
273 base::IntToString(tab_id));
274 return false;
277 base::ListValue* alerts_value = new base::ListValue;
279 InfoBarService* infobar_service = InfoBarService::FromWebContents(contents);
280 for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
281 // TODO(hashimoto): Make other kind of alerts available. crosbug.com/24281
282 ConfirmInfoBarDelegate* confirm_infobar_delegate =
283 infobar_service->infobar_at(i)->delegate()->AsConfirmInfoBarDelegate();
284 if (confirm_infobar_delegate) {
285 base::DictionaryValue* alert_value = new base::DictionaryValue;
286 const base::string16 message_text =
287 confirm_infobar_delegate->GetMessageText();
288 alert_value->SetString(keys::kMessageKey, message_text);
289 alerts_value->Append(alert_value);
293 SetResult(alerts_value);
294 return true;