| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/accessibility/accessibility_ui.h" | 5 #include "content/browser/accessibility/accessibility_ui.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" |
| 11 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/values.h" | 15 #include "base/values.h" |
| 15 #include "content/browser/accessibility/accessibility_tree_formatter.h" | 16 #include "content/browser/accessibility/accessibility_tree_formatter.h" |
| 16 #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" | 17 #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" |
| 17 #include "content/browser/accessibility/browser_accessibility_manager.h" | 18 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 18 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 19 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| 19 #include "content/browser/renderer_host/render_view_host_impl.h" | 20 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 20 #include "content/browser/renderer_host/render_widget_host_impl.h" | 21 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 21 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 22 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| 22 #include "content/browser/web_contents/web_contents_impl.h" | 23 #include "content/browser/web_contents/web_contents_impl.h" |
| 23 #include "content/browser/webui/web_ui_data_source_impl.h" | 24 #include "content/browser/webui/web_ui_data_source_impl.h" |
| 24 #include "content/common/view_message_enums.h" | 25 #include "content/common/view_message_enums.h" |
| 25 #include "content/grit/content_resources.h" | 26 #include "content/grit/content_resources.h" |
| 26 #include "content/public/browser/favicon_status.h" | 27 #include "content/public/browser/favicon_status.h" |
| 27 #include "content/public/browser/navigation_entry.h" | 28 #include "content/public/browser/navigation_entry.h" |
| 28 #include "content/public/browser/render_process_host.h" | 29 #include "content/public/browser/render_process_host.h" |
| 29 #include "content/public/browser/render_view_host.h" | 30 #include "content/public/browser/render_view_host.h" |
| 30 #include "content/public/browser/render_widget_host.h" | 31 #include "content/public/browser/render_widget_host.h" |
| 31 #include "content/public/browser/render_widget_host_iterator.h" | 32 #include "content/public/browser/render_widget_host_iterator.h" |
| 32 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 33 #include "content/public/browser/web_ui_data_source.h" | 34 #include "content/public/browser/web_ui_data_source.h" |
| 35 #include "content/public/common/content_switches.h" |
| 34 #include "content/public/common/url_constants.h" | 36 #include "content/public/common/url_constants.h" |
| 35 #include "net/base/escape.h" | 37 #include "net/base/escape.h" |
| 36 | 38 |
| 37 static const char kDataFile[] = "targets-data.json"; | 39 static const char kDataFile[] = "targets-data.json"; |
| 38 | 40 |
| 39 static const char kProcessIdField[] = "processId"; | 41 static const char kProcessIdField[] = "processId"; |
| 40 static const char kRouteIdField[] = "routeId"; | 42 static const char kRouteIdField[] = "routeId"; |
| 41 static const char kUrlField[] = "url"; | 43 static const char kUrlField[] = "url"; |
| 42 static const char kNameField[] = "name"; | 44 static const char kNameField[] = "name"; |
| 43 static const char kFaviconUrlField[] = "favicon_url"; | 45 static const char kFaviconUrlField[] = "favicon_url"; |
| 44 static const char kPidField[] = "pid"; | 46 static const char kPidField[] = "pid"; |
| 45 static const char kAccessibilityModeField[] = "a11y_mode"; | 47 static const char kAccessibilityModeField[] = "a11y_mode"; |
| 46 | 48 |
| 49 // Global flags |
| 50 static const char kInternal[] = "internal"; |
| 51 static const char kNative[] = "native"; |
| 52 static const char kWeb[] = "web"; |
| 53 static const char kText[] = "text"; |
| 54 static const char kScreenReader[] = "screenreader"; |
| 55 static const char kHTML[] = "html"; |
| 56 |
| 57 // Possible global flag values |
| 58 static const char kOff[]= "off"; |
| 59 static const char kOn[] = "on"; |
| 60 static const char kDisabled[] = "disabled"; |
| 61 |
| 47 namespace content { | 62 namespace content { |
| 48 | 63 |
| 49 namespace { | 64 namespace { |
| 50 | 65 |
| 51 bool g_show_internal_accessibility_tree = false; | 66 bool g_show_internal_accessibility_tree = false; |
| 52 | 67 |
| 53 std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor( | 68 std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor( |
| 54 const GURL& url, | 69 const GURL& url, |
| 55 const std::string& name, | 70 const std::string& name, |
| 56 const GURL& favicon_url, | 71 const GURL& favicon_url, |
| 57 int process_id, | 72 int process_id, |
| 58 int route_id, | 73 int route_id, |
| 59 AccessibilityMode accessibility_mode, | 74 AccessibilityMode accessibility_mode, |
| 60 base::ProcessHandle handle = base::kNullProcessHandle) { | 75 base::ProcessHandle handle = base::kNullProcessHandle) { |
| 61 std::unique_ptr<base::DictionaryValue> target_data( | 76 std::unique_ptr<base::DictionaryValue> target_data( |
| 62 new base::DictionaryValue()); | 77 new base::DictionaryValue()); |
| 63 target_data->SetInteger(kProcessIdField, process_id); | 78 target_data->SetInteger(kProcessIdField, process_id); |
| 64 target_data->SetInteger(kRouteIdField, route_id); | 79 target_data->SetInteger(kRouteIdField, route_id); |
| 65 target_data->SetString(kUrlField, url.spec()); | 80 target_data->SetString(kUrlField, url.spec()); |
| 66 target_data->SetString(kNameField, net::EscapeForHTML(name)); | 81 target_data->SetString(kNameField, net::EscapeForHTML(name)); |
| 67 target_data->SetInteger(kPidField, base::GetProcId(handle)); | 82 target_data->SetInteger(kPidField, base::GetProcId(handle)); |
| 68 target_data->SetString(kFaviconUrlField, favicon_url.spec()); | 83 target_data->SetString(kFaviconUrlField, favicon_url.spec()); |
| 69 target_data->SetInteger(kAccessibilityModeField, | 84 target_data->SetBoolean( |
| 70 accessibility_mode); | 85 kAccessibilityModeField, |
| 86 0 != (accessibility_mode & ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS)); |
| 71 return target_data; | 87 return target_data; |
| 72 } | 88 } |
| 73 | 89 |
| 74 std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor( | 90 std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor( |
| 75 RenderViewHost* rvh) { | 91 RenderViewHost* rvh) { |
| 76 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | 92 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( |
| 77 WebContents::FromRenderViewHost(rvh)); | 93 WebContents::FromRenderViewHost(rvh)); |
| 78 AccessibilityMode accessibility_mode = AccessibilityModeOff; | 94 AccessibilityMode accessibility_mode = AccessibilityModeOff; |
| 79 | 95 |
| 80 std::string title; | 96 std::string title; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 continue; | 138 continue; |
| 123 BrowserContext* context = rvh->GetProcess()->GetBrowserContext(); | 139 BrowserContext* context = rvh->GetProcess()->GetBrowserContext(); |
| 124 if (context != current_context) | 140 if (context != current_context) |
| 125 continue; | 141 continue; |
| 126 | 142 |
| 127 rvh_list->Append(BuildTargetDescriptor(rvh)); | 143 rvh_list->Append(BuildTargetDescriptor(rvh)); |
| 128 } | 144 } |
| 129 | 145 |
| 130 base::DictionaryValue data; | 146 base::DictionaryValue data; |
| 131 data.Set("list", rvh_list.release()); | 147 data.Set("list", rvh_list.release()); |
| 132 data.SetInteger( | 148 AccessibilityMode mode = |
| 133 "global_a11y_mode", | 149 BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode(); |
| 134 BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()); | 150 bool disabled = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 135 data.SetBoolean( | 151 switches::kDisableRendererAccessibility); |
| 136 "global_internal_tree_mode", | 152 bool native = 0 != (mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS); |
| 137 g_show_internal_accessibility_tree); | 153 bool web = 0 != (mode & ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS); |
| 154 bool text = 0 != (mode & ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES); |
| 155 bool screenreader = 0 != (mode & ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| 156 bool html = 0 != (mode & ACCESSIBILITY_MODE_FLAG_HTML); |
| 157 |
| 158 // The "native" and "web" flags are disabled if |
| 159 // --disable-renderer-accessibility is set. |
| 160 data.SetString(kNative, disabled ? kDisabled : (native ? kOn : kOff)); |
| 161 data.SetString(kWeb, disabled ? kDisabled : (web ? kOn : kOff)); |
| 162 |
| 163 // The "text", "screenreader", and "html" flags are only meaningful if |
| 164 // "web" is enabled. |
| 165 data.SetString(kText, web ? (text ? kOn : kOff) : kDisabled); |
| 166 data.SetString(kScreenReader, web ? (screenreader ? kOn : kOff) : kDisabled); |
| 167 data.SetString(kHTML, web ? (html ? kOn : kOff) : kDisabled); |
| 168 |
| 169 data.SetString(kInternal, |
| 170 g_show_internal_accessibility_tree ? kOn : kOff); |
| 138 | 171 |
| 139 std::string json_string; | 172 std::string json_string; |
| 140 base::JSONWriter::Write(data, &json_string); | 173 base::JSONWriter::Write(data, &json_string); |
| 141 | 174 |
| 142 callback.Run(base::RefCountedString::TakeString(&json_string)); | 175 callback.Run(base::RefCountedString::TakeString(&json_string)); |
| 143 return true; | 176 return true; |
| 144 } | 177 } |
| 145 | 178 |
| 146 } // namespace | 179 } // namespace |
| 147 | 180 |
| 148 AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) { | 181 AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) { |
| 149 // Set up the chrome://accessibility source. | 182 // Set up the chrome://accessibility source. |
| 150 WebUIDataSourceImpl* html_source = static_cast<WebUIDataSourceImpl*>( | 183 WebUIDataSourceImpl* html_source = static_cast<WebUIDataSourceImpl*>( |
| 151 WebUIDataSource::Create(kChromeUIAccessibilityHost)); | 184 WebUIDataSource::Create(kChromeUIAccessibilityHost)); |
| 152 | 185 |
| 153 web_ui->RegisterMessageCallback( | 186 web_ui->RegisterMessageCallback( |
| 154 "toggleAccessibility", | 187 "toggleAccessibility", |
| 155 base::Bind(&AccessibilityUI::ToggleAccessibility, | 188 base::Bind(&AccessibilityUI::ToggleAccessibility, |
| 156 base::Unretained(this))); | 189 base::Unretained(this))); |
| 157 web_ui->RegisterMessageCallback( | 190 web_ui->RegisterMessageCallback( |
| 158 "toggleGlobalAccessibility", | 191 "setGlobalFlag", |
| 159 base::Bind(&AccessibilityUI::ToggleGlobalAccessibility, | 192 base::Bind(&AccessibilityUI::SetGlobalFlag, |
| 160 base::Unretained(this))); | |
| 161 web_ui->RegisterMessageCallback( | |
| 162 "toggleInternalTree", | |
| 163 base::Bind(&AccessibilityUI::ToggleInternalTree, | |
| 164 base::Unretained(this))); | 193 base::Unretained(this))); |
| 165 web_ui->RegisterMessageCallback( | 194 web_ui->RegisterMessageCallback( |
| 166 "requestAccessibilityTree", | 195 "requestAccessibilityTree", |
| 167 base::Bind(&AccessibilityUI::RequestAccessibilityTree, | 196 base::Bind(&AccessibilityUI::RequestAccessibilityTree, |
| 168 base::Unretained(this))); | 197 base::Unretained(this))); |
| 169 | 198 |
| 170 // Add required resources. | 199 // Add required resources. |
| 171 html_source->SetJsonPath("strings.js"); | 200 html_source->SetJsonPath("strings.js"); |
| 172 html_source->AddResourcePath("accessibility.css", IDR_ACCESSIBILITY_CSS); | 201 html_source->AddResourcePath("accessibility.css", IDR_ACCESSIBILITY_CSS); |
| 173 html_source->AddResourcePath("accessibility.js", IDR_ACCESSIBILITY_JS); | 202 html_source->AddResourcePath("accessibility.js", IDR_ACCESSIBILITY_JS); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 203 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh)); | 232 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh)); |
| 204 AccessibilityMode mode = web_contents->GetAccessibilityMode(); | 233 AccessibilityMode mode = web_contents->GetAccessibilityMode(); |
| 205 if ((mode & ACCESSIBILITY_MODE_COMPLETE) != ACCESSIBILITY_MODE_COMPLETE) { | 234 if ((mode & ACCESSIBILITY_MODE_COMPLETE) != ACCESSIBILITY_MODE_COMPLETE) { |
| 206 web_contents->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); | 235 web_contents->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); |
| 207 } else { | 236 } else { |
| 208 web_contents->SetAccessibilityMode( | 237 web_contents->SetAccessibilityMode( |
| 209 BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()); | 238 BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()); |
| 210 } | 239 } |
| 211 } | 240 } |
| 212 | 241 |
| 213 void AccessibilityUI::ToggleGlobalAccessibility(const base::ListValue* args) { | 242 void AccessibilityUI::SetGlobalFlag(const base::ListValue* args) { |
| 243 std::string flag_name_str; |
| 244 bool enabled; |
| 245 CHECK_EQ(2U, args->GetSize()); |
| 246 CHECK(args->GetString(0, &flag_name_str)); |
| 247 CHECK(args->GetBoolean(1, &enabled)); |
| 248 |
| 249 if (flag_name_str == kInternal) { |
| 250 g_show_internal_accessibility_tree = enabled; |
| 251 LOG(ERROR) << "INTERNAL: " << g_show_internal_accessibility_tree; |
| 252 return; |
| 253 } |
| 254 |
| 255 AccessibilityMode new_mode; |
| 256 if (flag_name_str == kNative) { |
| 257 new_mode = ACCESSIBILITY_MODE_FLAG_NATIVE_APIS; |
| 258 } else if (flag_name_str == kWeb) { |
| 259 new_mode = ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS; |
| 260 } else if (flag_name_str == kText) { |
| 261 new_mode = ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES; |
| 262 } else if (flag_name_str == kScreenReader) { |
| 263 new_mode = ACCESSIBILITY_MODE_FLAG_SCREEN_READER; |
| 264 } else if (flag_name_str == kHTML) { |
| 265 new_mode = ACCESSIBILITY_MODE_FLAG_HTML; |
| 266 } else { |
| 267 NOTREACHED(); |
| 268 return; |
| 269 } |
| 270 |
| 271 // It doesn't make sense to enable one of the flags that depends on |
| 272 // web contents without enabling web contents accessibility too. |
| 273 if (enabled && |
| 274 (new_mode == ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES || |
| 275 new_mode == ACCESSIBILITY_MODE_FLAG_SCREEN_READER || |
| 276 new_mode == ACCESSIBILITY_MODE_FLAG_HTML)) { |
| 277 new_mode |= ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS; |
| 278 } |
| 279 |
| 280 // Similarly if you disable web accessibility we should remove all |
| 281 // flags that depend on it. |
| 282 if (!enabled && new_mode == ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS) { |
| 283 new_mode |= ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES; |
| 284 new_mode |= ACCESSIBILITY_MODE_FLAG_SCREEN_READER; |
| 285 new_mode |= ACCESSIBILITY_MODE_FLAG_HTML; |
| 286 } |
| 287 |
| 214 BrowserAccessibilityStateImpl* state = | 288 BrowserAccessibilityStateImpl* state = |
| 215 BrowserAccessibilityStateImpl::GetInstance(); | 289 BrowserAccessibilityStateImpl::GetInstance(); |
| 216 AccessibilityMode mode = state->accessibility_mode(); | 290 if (enabled) |
| 217 if ((mode & ACCESSIBILITY_MODE_COMPLETE) != ACCESSIBILITY_MODE_COMPLETE) | 291 state->AddAccessibilityModeFlags(new_mode); |
| 218 state->EnableAccessibility(); | |
| 219 else | 292 else |
| 220 state->DisableAccessibility(); | 293 state->RemoveAccessibilityModeFlags(new_mode); |
| 221 } | |
| 222 | |
| 223 void AccessibilityUI::ToggleInternalTree(const base::ListValue* args) { | |
| 224 g_show_internal_accessibility_tree = !g_show_internal_accessibility_tree; | |
| 225 } | 294 } |
| 226 | 295 |
| 227 void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) { | 296 void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) { |
| 228 std::string process_id_str; | 297 std::string process_id_str; |
| 229 std::string route_id_str; | 298 std::string route_id_str; |
| 230 int process_id; | 299 int process_id; |
| 231 int route_id; | 300 int route_id; |
| 232 CHECK_EQ(2U, args->GetSize()); | 301 CHECK_EQ(2U, args->GetSize()); |
| 233 CHECK(args->GetString(0, &process_id_str)); | 302 CHECK(args->GetString(0, &process_id_str)); |
| 234 CHECK(args->GetString(1, &route_id_str)); | 303 CHECK(args->GetString(1, &route_id_str)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 264 web_contents->GetRootBrowserAccessibilityManager()->GetRoot(), | 333 web_contents->GetRootBrowserAccessibilityManager()->GetRoot(), |
| 265 &accessibility_contents_utf16); | 334 &accessibility_contents_utf16); |
| 266 result->Set("tree", | 335 result->Set("tree", |
| 267 new base::StringValue( | 336 new base::StringValue( |
| 268 base::UTF16ToUTF8(accessibility_contents_utf16))); | 337 base::UTF16ToUTF8(accessibility_contents_utf16))); |
| 269 web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree", | 338 web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree", |
| 270 *(result.get())); | 339 *(result.get())); |
| 271 } | 340 } |
| 272 | 341 |
| 273 } // namespace content | 342 } // namespace content |
| OLD | NEW |