15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/accessibility/accessibility_extension_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/accessibility/accessibility_extension_api_constants.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/extension_host.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/infobars/infobar.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/common/extensions/api/experimental_accessibility.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_accessibility_state.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/lazy_background_task_queue.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extension_accessibility_api_constants;
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace experimental_accessibility =
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    extensions::api::experimental_accessibility;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the AccessibilityControlInfo serialized into a JSON string,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// consisting of an array of a single object of type AccessibilityObject,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as defined in the accessibility extension api's json schema.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ListValue> ControlInfoToEventArguments(
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityEventInfo* info) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* dict = new DictionaryValue();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SerializeToDict(dict);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(new ListValue());
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->Append(dict);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return args.Pass();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionAccessibilityEventRouter*
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionAccessibilityEventRouter::GetInstance() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<ExtensionAccessibilityEventRouter>::get();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionAccessibilityEventRouter::ExtensionAccessibilityEventRouter()
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : enabled_(false) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionAccessibilityEventRouter::~ExtensionAccessibilityEventRouter() {
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  control_event_callback_.Reset();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::SetAccessibilityEnabled(bool enabled) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enabled_ = enabled;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionAccessibilityEventRouter::IsAccessibilityEnabled() const {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return enabled_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::SetControlEventCallbackForTesting(
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ControlEventCallback control_event_callback) {
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(control_event_callback_.is_null());
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  control_event_callback_ = control_event_callback;
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::ClearControlEventCallback() {
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  control_event_callback_.Reset();
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::HandleWindowEvent(
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::AccessibilityTypes::Event event,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityWindowInfo* info) {
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!control_event_callback_.is_null())
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    control_event_callback_.Run(event, info);
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (event == ui::AccessibilityTypes::EVENT_ALERT)
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    OnWindowOpened(info);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::HandleMenuEvent(
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::AccessibilityTypes::Event event,
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AccessibilityMenuInfo* info) {
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (event) {
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_MENUSTART:
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_MENUPOPUPSTART:
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OnMenuOpened(info);
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_MENUEND:
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_MENUPOPUPEND:
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OnMenuClosed(info);
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ui::AccessibilityTypes::EVENT_FOCUS:
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      OnControlFocused(info);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    default:
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NOTREACHED();
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::HandleControlEvent(
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::AccessibilityTypes::Event event,
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AccessibilityControlInfo* info) {
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!control_event_callback_.is_null())
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    control_event_callback_.Run(event, info);
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (event) {
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_TEXT_CHANGED:
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_SELECTION_CHANGED:
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OnTextChanged(info);
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_VALUE_CHANGED:
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ui::AccessibilityTypes::EVENT_ALERT:
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OnControlAction(info);
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ui::AccessibilityTypes::EVENT_FOCUS:
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OnControlFocused(info);
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    default:
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NOTREACHED();
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnWindowOpened(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityWindowInfo* info) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnWindowOpened::kEventName,
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnControlFocused(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityControlInfo* info) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_focused_control_dict_.Clear();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SerializeToDict(&last_focused_control_dict_);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnControlFocused::kEventName,
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnControlAction(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityControlInfo* info) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnControlAction::kEventName,
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnTextChanged(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityControlInfo* info) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnTextChanged::kEventName,
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnMenuOpened(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityMenuInfo* info) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnMenuOpened::kEventName,
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::OnMenuClosed(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessibilityMenuInfo* info) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ListValue> args(ControlInfoToEventArguments(info));
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(info->profile(),
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                experimental_accessibility::OnMenuClosed::kEventName,
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionAccessibilityEventRouter::OnChromeVoxLoadStateChanged(
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Profile* profile,
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool loading,
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool make_announcements) {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> event_args(new base::ListValue());
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_args->Append(base::Value::CreateBooleanValue(loading));
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_args->Append(base::Value::CreateBooleanValue(make_announcements));
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(profile,
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      experimental_accessibility::OnChromeVoxLoadStateChanged::kEventName,
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      event_args.Pass());
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Static.
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Profile* profile,
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char* event_name,
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<base::ListValue> event_args) {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extensions::ExtensionSystem* system =
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile);
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!system)
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<extensions::Event> event(new extensions::Event(event_name,
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                            event_args.Pass()));
201f5859ba46034e02ada5ef522d9d9c09fbbddccd8Ben Murdoch  system->event_router()->DispatchEventWithLazyListener(
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_misc::kChromeVoxExtensionId, event.Pass());
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAccessibilityEventRouter::DispatchEvent(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* event_name,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::ListValue> event_args) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enabled_ && profile &&
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions::ExtensionSystem::Get(profile)->event_router()) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<extensions::Event> event(new extensions::Event(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event_name, event_args.Pass()));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extensions::ExtensionSystem::Get(profile)->event_router()->
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BroadcastEvent(event.Pass());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AccessibilitySetAccessibilityEnabledFunction::RunImpl() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionAccessibilityEventRouter::GetInstance()
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->SetAccessibilityEnabled(enabled);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool AccessibilitySetNativeAccessibilityEnabledFunction::RunImpl() {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool enabled;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (enabled) {
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::BrowserAccessibilityState::GetInstance()->
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        EnableAccessibility();
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::BrowserAccessibilityState::GetInstance()->
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        DisableAccessibility();
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AccessibilityGetFocusedControlFunction::RunImpl() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the serialized dict from the last focused control and return it.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, if the dict is empty, that means we haven't seen any focus
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // events yet, so return null instead.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionAccessibilityEventRouter *accessibility_event_router =
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionAccessibilityEventRouter::GetInstance();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue *last_focused_control_dict =
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accessibility_event_router->last_focused_control_dict();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (last_focused_control_dict->size()) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResult(last_focused_control_dict->DeepCopyWithoutEmptyChildren());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResult(Value::CreateNullValue());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AccessibilityGetAlertsForTabFunction::RunImpl() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab_id;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModel* tab_strip = NULL;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* contents = NULL;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab_index = -1;
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!extensions::ExtensionTabUtil::GetTabById(tab_id,
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                GetProfile(),
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                include_incognito(),
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                NULL,
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                &tab_strip,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                &contents,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                &tab_index)) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = extensions::ErrorUtils::FormatErrorMessage(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions::tabs_constants::kTabNotFoundError,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::IntToString(tab_id));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListValue* alerts_value = new ListValue;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InfoBarService* infobar_service = InfoBarService::FromWebContents(contents);
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(hashimoto): Make other kind of alerts available.  crosbug.com/24281
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConfirmInfoBarDelegate* confirm_infobar_delegate =
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        infobar_service->infobar_at(i)->delegate()->AsConfirmInfoBarDelegate();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (confirm_infobar_delegate) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DictionaryValue* alert_value = new DictionaryValue;
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16 message_text =
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          confirm_infobar_delegate->GetMessageText();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alert_value->SetString(keys::kMessageKey, message_text);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alerts_value->Append(alert_value);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetResult(alerts_value);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
294