12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/accessibility_ui.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/accessibility_tree_formatter.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_manager.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/browser_accessibility_state_impl.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_view_base.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/web_contents/web_contents_impl.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/view_message_enums.h"
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/grit/content_resources.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/favicon_status.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_widget_host.h"
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/render_widget_host_iterator.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/escape.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kDataFile[] = "targets-data.json";
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kProcessIdField[]  = "processId";
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kRouteIdField[]  = "routeId";
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kUrlField[]  = "url";
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kNameField[]  = "name";
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kFaviconUrlField[] = "favicon_url";
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kPidField[]  = "pid";
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kAccessibilityModeField[] = "a11y_mode";
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::DictionaryValue* BuildTargetDescriptor(
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& name,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& favicon_url,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int process_id,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int route_id,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AccessibilityMode accessibility_mode,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessHandle handle = base::kNullProcessHandle) {
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue* target_data = new base::DictionaryValue();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetInteger(kProcessIdField, process_id);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetInteger(kRouteIdField, route_id);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetString(kUrlField, url.spec());
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetString(kNameField, net::EscapeForHTML(name));
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetInteger(kPidField, base::GetProcId(handle));
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetString(kFaviconUrlField, favicon_url.spec());
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_data->SetInteger(kAccessibilityModeField,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          accessibility_mode);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return target_data;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::DictionaryValue* BuildTargetDescriptor(RenderViewHost* rvh) {
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WebContents::FromRenderViewHost(rvh));
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AccessibilityMode accessibility_mode = web_contents->GetAccessibilityMode();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string title;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL favicon_url;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_contents) {
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // TODO(nasko): Fix the following code to use a consistent set of data
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // across the URL, title, and favicon.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url = web_contents->GetURL();
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    title = base::UTF16ToUTF8(web_contents->GetTitle());
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NavigationController& controller = web_contents->GetController();
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NavigationEntry* entry = controller.GetVisibleEntry();
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry != NULL && entry->GetURL().is_valid())
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      favicon_url = entry->GetFavicon().url;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return BuildTargetDescriptor(url,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               title,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               favicon_url,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               rvh->GetProcess()->GetID(),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               rvh->GetRoutingID(),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               accessibility_mode);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool HandleRequestCallback(BrowserContext* current_context,
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           const std::string& path,
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           const WebUIDataSource::GotDataCallback& callback) {
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (path != kDataFile)
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<base::ListValue> rvh_list(new base::ListValue());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<RenderWidgetHostIterator> widgets(
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RenderWidgetHost::GetRenderWidgetHosts());
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  while (RenderWidgetHost* widget = widgets->GetNextHost()) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore processes that don't have a connection, such as crashed tabs.
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!widget->GetProcess()->HasConnection())
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!widget->IsRenderView())
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserContext* context = rwhi->GetProcess()->GetBrowserContext();
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (context != current_context)
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      continue;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    RenderViewHost* rvh = RenderViewHost::From(widget);
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rvh_list->Append(BuildTargetDescriptor(rvh));
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data->Set("list", rvh_list.release());
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  data->SetInteger(
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "global_a11y_mode",
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode());
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string json_string;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::JSONWriter::Write(data.get(), &json_string);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(base::RefCountedString::TakeString(&json_string));
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) {
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Set up the chrome://accessibility source.
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WebUIDataSource* html_source =
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      WebUIDataSource::Create(kChromeUIAccessibilityHost);
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->SetUseJsonJSFormatV2();
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  web_ui->RegisterMessageCallback(
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      "toggleAccessibility",
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&AccessibilityUI::ToggleAccessibility,
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(this)));
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  web_ui->RegisterMessageCallback(
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      "toggleGlobalAccessibility",
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&AccessibilityUI::ToggleGlobalAccessibility,
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(this)));
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  web_ui->RegisterMessageCallback(
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      "requestAccessibilityTree",
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&AccessibilityUI::RequestAccessibilityTree,
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(this)));
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Add required resources.
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->SetJsonPath("strings.js");
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->AddResourcePath("accessibility.css", IDR_ACCESSIBILITY_CSS);
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->AddResourcePath("accessibility.js", IDR_ACCESSIBILITY_JS);
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->SetDefaultResource(IDR_ACCESSIBILITY_HTML);
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  html_source->SetRequestFilter(
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&HandleRequestCallback,
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 web_ui->GetWebContents()->GetBrowserContext()));
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  BrowserContext* browser_context =
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      web_ui->GetWebContents()->GetBrowserContext();
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WebUIDataSource::Add(browser_context, html_source);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)AccessibilityUI::~AccessibilityUI() {}
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string process_id_str;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string route_id_str;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int process_id;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int route_id;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK_EQ(2U, args->GetSize());
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(args->GetString(0, &process_id_str));
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(args->GetString(1, &route_id_str));
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(base::StringToInt(process_id_str, &process_id));
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(base::StringToInt(route_id_str, &route_id));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!rvh)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WebContents::FromRenderViewHost(rvh));
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AccessibilityMode mode = web_contents->GetAccessibilityMode();
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if ((mode & AccessibilityModeComplete) != AccessibilityModeComplete) {
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    web_contents->AddAccessibilityMode(AccessibilityModeComplete);
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    web_contents->SetAccessibilityMode(
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode());
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccessibilityUI::ToggleGlobalAccessibility(const base::ListValue* args) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserAccessibilityStateImpl* state =
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserAccessibilityStateImpl::GetInstance();
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AccessibilityMode mode = state->accessibility_mode();
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if ((mode & AccessibilityModeComplete) != AccessibilityModeComplete)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state->EnableAccessibility();
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state->DisableAccessibility();
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string process_id_str;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string route_id_str;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int process_id;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int route_id;
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK_EQ(2U, args->GetSize());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(args->GetString(0, &process_id_str));
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(args->GetString(1, &route_id_str));
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(base::StringToInt(process_id_str, &process_id));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(base::StringToInt(route_id_str, &route_id));
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!rvh) {
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result->SetInteger(kProcessIdField, process_id);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result->SetInteger(kRouteIdField, route_id);
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    result->Set("error", new base::StringValue("Renderer no longer exists."));
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_ui()->CallJavascriptFunction("accessibility.showTree", *(result.get()));
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> result(BuildTargetDescriptor(rvh));
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AccessibilityTreeFormatter> formatter(
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AccessibilityTreeFormatter::Create(web_contents));
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 accessibility_contents_utf16;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<AccessibilityTreeFormatter::Filter> filters;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  filters.push_back(AccessibilityTreeFormatter::Filter(
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::ASCIIToUTF16("*"),
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AccessibilityTreeFormatter::Filter::ALLOW));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  formatter->SetFilters(filters);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  formatter->FormatAccessibilityTree(&accessibility_contents_utf16);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result->Set("tree",
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              new base::StringValue(
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::UTF16ToUTF8(accessibility_contents_utf16)));
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->CallJavascriptFunction("accessibility.showTree", *(result.get()));
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
243