| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/renderer/extensions/automation_internal_custom_bindings.h" | 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/common/extensions/api/automation_api_constants.h" | 16 #include "chrome/common/extensions/api/automation_api_constants.h" |
| 17 #include "chrome/common/extensions/chrome_extension_messages.h" | 17 #include "chrome/common/extensions/chrome_extension_messages.h" |
| 18 #include "chrome/common/extensions/manifest_handlers/automation.h" | 18 #include "chrome/common/extensions/manifest_handlers/automation.h" |
| 19 #include "content/public/renderer/render_frame.h" | 19 #include "content/public/renderer/render_frame.h" |
| 20 #include "content/public/renderer/render_thread.h" | 20 #include "content/public/renderer/render_thread.h" |
| 21 #include "content/public/renderer/render_view.h" | 21 #include "content/public/renderer/render_view.h" |
| 22 #include "extensions/common/extension.h" | 22 #include "extensions/common/extension.h" |
| 23 #include "extensions/common/manifest.h" | 23 #include "extensions/common/manifest.h" |
| 24 #include "extensions/renderer/extension_bindings_system.h" |
| 24 #include "extensions/renderer/script_context.h" | 25 #include "extensions/renderer/script_context.h" |
| 25 #include "ipc/message_filter.h" | 26 #include "ipc/message_filter.h" |
| 26 #include "ui/accessibility/ax_enums.h" | 27 #include "ui/accessibility/ax_enums.h" |
| 27 #include "ui/accessibility/ax_node.h" | 28 #include "ui/accessibility/ax_node.h" |
| 28 #include "ui/gfx/geometry/rect_conversions.h" | 29 #include "ui/gfx/geometry/rect_conversions.h" |
| 29 | 30 |
| 30 namespace extensions { | 31 namespace extensions { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 } | 412 } |
| 412 | 413 |
| 413 AutomationInternalCustomBindings* owner_; | 414 AutomationInternalCustomBindings* owner_; |
| 414 bool removed_; | 415 bool removed_; |
| 415 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 416 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 416 | 417 |
| 417 DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); | 418 DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); |
| 418 }; | 419 }; |
| 419 | 420 |
| 420 AutomationInternalCustomBindings::AutomationInternalCustomBindings( | 421 AutomationInternalCustomBindings::AutomationInternalCustomBindings( |
| 421 ScriptContext* context) | 422 ScriptContext* context, |
| 423 ExtensionBindingsSystem* bindings_system) |
| 422 : ObjectBackedNativeHandler(context), | 424 : ObjectBackedNativeHandler(context), |
| 423 is_active_profile_(true), | 425 is_active_profile_(true), |
| 424 tree_change_observer_overall_filter_(0) { | 426 tree_change_observer_overall_filter_(0), |
| 425 // It's safe to use base::Unretained(this) here because these bindings | 427 bindings_system_(bindings_system) { |
| 426 // will only be called on a valid AutomationInternalCustomBindings instance | 428 // It's safe to use base::Unretained(this) here because these bindings |
| 427 // and none of the functions have any side effects. | 429 // will only be called on a valid AutomationInternalCustomBindings instance |
| 430 // and none of the functions have any side effects. |
| 428 #define ROUTE_FUNCTION(FN) \ | 431 #define ROUTE_FUNCTION(FN) \ |
| 429 RouteFunction(#FN, "automation", \ | 432 RouteFunction(#FN, "automation", \ |
| 430 base::Bind(&AutomationInternalCustomBindings::FN, \ | 433 base::Bind(&AutomationInternalCustomBindings::FN, \ |
| 431 base::Unretained(this))) | 434 base::Unretained(this))) |
| 432 ROUTE_FUNCTION(IsInteractPermitted); | 435 ROUTE_FUNCTION(IsInteractPermitted); |
| 433 ROUTE_FUNCTION(GetSchemaAdditions); | 436 ROUTE_FUNCTION(GetSchemaAdditions); |
| 434 ROUTE_FUNCTION(GetRoutingID); | 437 ROUTE_FUNCTION(GetRoutingID); |
| 435 ROUTE_FUNCTION(StartCachingAccessibilityTrees); | 438 ROUTE_FUNCTION(StartCachingAccessibilityTrees); |
| 436 ROUTE_FUNCTION(DestroyAccessibilityTree); | 439 ROUTE_FUNCTION(DestroyAccessibilityTree); |
| 437 ROUTE_FUNCTION(AddTreeChangeObserver); | 440 ROUTE_FUNCTION(AddTreeChangeObserver); |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 cache->owner = this; | 1131 cache->owner = this; |
| 1129 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); | 1132 tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache)); |
| 1130 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); | 1133 axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache)); |
| 1131 } else { | 1134 } else { |
| 1132 cache = iter->second; | 1135 cache = iter->second; |
| 1133 } | 1136 } |
| 1134 | 1137 |
| 1135 // Update the internal state whether it's the active profile or not. | 1138 // Update the internal state whether it's the active profile or not. |
| 1136 cache->location_offset = params.location_offset; | 1139 cache->location_offset = params.location_offset; |
| 1137 deleted_node_ids_.clear(); | 1140 deleted_node_ids_.clear(); |
| 1138 v8::Isolate* isolate = GetIsolate(); | |
| 1139 v8::HandleScope handle_scope(isolate); | |
| 1140 v8::Context::Scope context_scope(context()->v8_context()); | |
| 1141 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 1U)); | |
| 1142 if (!cache->tree.Unserialize(params.update)) { | 1141 if (!cache->tree.Unserialize(params.update)) { |
| 1143 LOG(ERROR) << cache->tree.error(); | 1142 LOG(ERROR) << cache->tree.error(); |
| 1144 args->Set(0U, v8::Number::New(isolate, tree_id)); | 1143 base::ListValue args; |
| 1145 context()->DispatchEvent( | 1144 args.AppendInteger(tree_id); |
| 1146 "automationInternal.onAccessibilityTreeSerializationError", args); | 1145 bindings_system_->DispatchEventInContext( |
| 1146 "automationInternal.onAccessibilityTreeSerializationError", &args, |
| 1147 nullptr, context()); |
| 1147 return; | 1148 return; |
| 1148 } | 1149 } |
| 1149 | 1150 |
| 1150 // Don't send any events if it's not the active profile. | 1151 // Don't send any events if it's not the active profile. |
| 1151 if (!is_active_profile) | 1152 if (!is_active_profile) |
| 1152 return; | 1153 return; |
| 1153 | 1154 |
| 1154 SendNodesRemovedEvent(&cache->tree, deleted_node_ids_); | 1155 SendNodesRemovedEvent(&cache->tree, deleted_node_ids_); |
| 1155 deleted_node_ids_.clear(); | 1156 deleted_node_ids_.clear(); |
| 1156 | 1157 |
| 1157 v8::Local<v8::Object> event_params(v8::Object::New(GetIsolate())); | 1158 { |
| 1158 event_params->Set(CreateV8String(isolate, "treeID"), | 1159 auto event_params = base::MakeUnique<base::DictionaryValue>(); |
| 1159 v8::Integer::New(GetIsolate(), params.tree_id)); | 1160 event_params->SetInteger("treeID", params.tree_id); |
| 1160 event_params->Set(CreateV8String(isolate, "targetID"), | 1161 event_params->SetInteger("targetID", params.id); |
| 1161 v8::Integer::New(GetIsolate(), params.id)); | 1162 event_params->SetString("eventType", ToString(params.event_type)); |
| 1162 event_params->Set(CreateV8String(isolate, "eventType"), | 1163 event_params->SetString("eventFrom", ToString(params.event_from)); |
| 1163 CreateV8String(isolate, ToString(params.event_type))); | 1164 event_params->SetInteger("mouseX", params.mouse_location.x()); |
| 1164 event_params->Set(CreateV8String(isolate, "eventFrom"), | 1165 event_params->SetInteger("mouseY", params.mouse_location.y()); |
| 1165 CreateV8String(isolate, ToString(params.event_from))); | 1166 base::ListValue args; |
| 1166 event_params->Set(CreateV8String(isolate, "mouseX"), | 1167 args.Append(std::move(event_params)); |
| 1167 v8::Integer::New(GetIsolate(), params.mouse_location.x())); | 1168 bindings_system_->DispatchEventInContext( |
| 1168 event_params->Set(CreateV8String(isolate, "mouseY"), | 1169 "automationInternal.onAccessibilityEvent", &args, nullptr, context()); |
| 1169 v8::Integer::New(GetIsolate(), params.mouse_location.y())); | 1170 } |
| 1170 args->Set(0U, event_params); | |
| 1171 context()->DispatchEvent("automationInternal.onAccessibilityEvent", args); | |
| 1172 } | 1171 } |
| 1173 | 1172 |
| 1174 void AutomationInternalCustomBindings::OnAccessibilityLocationChange( | 1173 void AutomationInternalCustomBindings::OnAccessibilityLocationChange( |
| 1175 const ExtensionMsg_AccessibilityLocationChangeParams& params) { | 1174 const ExtensionMsg_AccessibilityLocationChangeParams& params) { |
| 1176 int tree_id = params.tree_id; | 1175 int tree_id = params.tree_id; |
| 1177 auto iter = tree_id_to_tree_cache_map_.find(tree_id); | 1176 auto iter = tree_id_to_tree_cache_map_.find(tree_id); |
| 1178 if (iter == tree_id_to_tree_cache_map_.end()) | 1177 if (iter == tree_id_to_tree_cache_map_.end()) |
| 1179 return; | 1178 return; |
| 1180 TreeCache* cache = iter->second; | 1179 TreeCache* cache = iter->second; |
| 1181 ui::AXNode* node = cache->tree.GetFromId(params.id); | 1180 ui::AXNode* node = cache->tree.GetFromId(params.id); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 | 1320 |
| 1322 if (!has_filter) | 1321 if (!has_filter) |
| 1323 return; | 1322 return; |
| 1324 | 1323 |
| 1325 auto iter = axtree_to_tree_cache_map_.find(tree); | 1324 auto iter = axtree_to_tree_cache_map_.find(tree); |
| 1326 if (iter == axtree_to_tree_cache_map_.end()) | 1325 if (iter == axtree_to_tree_cache_map_.end()) |
| 1327 return; | 1326 return; |
| 1328 | 1327 |
| 1329 int tree_id = iter->second->tree_id; | 1328 int tree_id = iter->second->tree_id; |
| 1330 | 1329 |
| 1331 v8::Isolate* isolate = GetIsolate(); | |
| 1332 v8::HandleScope handle_scope(isolate); | |
| 1333 v8::Context::Scope context_scope(context()->v8_context()); | |
| 1334 | |
| 1335 for (const auto& observer : tree_change_observers_) { | 1330 for (const auto& observer : tree_change_observers_) { |
| 1336 switch (observer.filter) { | 1331 switch (observer.filter) { |
| 1337 case api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES: | 1332 case api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES: |
| 1338 default: | 1333 default: |
| 1339 continue; | 1334 continue; |
| 1340 case api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES: | 1335 case api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES: |
| 1341 if (!node->data().HasStringAttribute( | 1336 if (!node->data().HasStringAttribute( |
| 1342 ui::AX_ATTR_CONTAINER_LIVE_STATUS) && | 1337 ui::AX_ATTR_CONTAINER_LIVE_STATUS) && |
| 1343 node->data().role != ui::AX_ROLE_ALERT) { | 1338 node->data().role != ui::AX_ROLE_ALERT) { |
| 1344 continue; | 1339 continue; |
| 1345 } | 1340 } |
| 1346 break; | 1341 break; |
| 1347 case api::automation::TREE_CHANGE_OBSERVER_FILTER_TEXTMARKERCHANGES: | 1342 case api::automation::TREE_CHANGE_OBSERVER_FILTER_TEXTMARKERCHANGES: |
| 1348 if (!node->data().HasIntListAttribute(ui::AX_ATTR_MARKER_TYPES)) | 1343 if (!node->data().HasIntListAttribute(ui::AX_ATTR_MARKER_TYPES)) |
| 1349 continue; | 1344 continue; |
| 1350 break; | 1345 break; |
| 1351 case api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES: | 1346 case api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES: |
| 1352 break; | 1347 break; |
| 1353 } | 1348 } |
| 1354 | 1349 |
| 1355 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 4U)); | 1350 base::ListValue args; |
| 1356 args->Set(0U, v8::Integer::New(GetIsolate(), observer.id)); | 1351 args.AppendInteger(observer.id); |
| 1357 args->Set(1U, v8::Integer::New(GetIsolate(), tree_id)); | 1352 args.AppendInteger(tree_id); |
| 1358 args->Set(2U, v8::Integer::New(GetIsolate(), node->id())); | 1353 args.AppendInteger(node->id()); |
| 1359 args->Set(3U, CreateV8String(isolate, ToString(change_type))); | 1354 args.AppendString(ToString(change_type)); |
| 1360 context()->DispatchEvent("automationInternal.onTreeChange", args); | 1355 bindings_system_->DispatchEventInContext("automationInternal.onTreeChange", |
| 1356 &args, nullptr, context()); |
| 1361 } | 1357 } |
| 1362 } | 1358 } |
| 1363 | 1359 |
| 1364 void AutomationInternalCustomBindings::SendChildTreeIDEvent(ui::AXTree* tree, | 1360 void AutomationInternalCustomBindings::SendChildTreeIDEvent(ui::AXTree* tree, |
| 1365 ui::AXNode* node) { | 1361 ui::AXNode* node) { |
| 1366 auto iter = axtree_to_tree_cache_map_.find(tree); | 1362 auto iter = axtree_to_tree_cache_map_.find(tree); |
| 1367 if (iter == axtree_to_tree_cache_map_.end()) | 1363 if (iter == axtree_to_tree_cache_map_.end()) |
| 1368 return; | 1364 return; |
| 1369 | 1365 |
| 1370 int tree_id = iter->second->tree_id; | 1366 int tree_id = iter->second->tree_id; |
| 1371 | 1367 |
| 1372 v8::Isolate* isolate = GetIsolate(); | 1368 base::ListValue args; |
| 1373 v8::HandleScope handle_scope(isolate); | 1369 args.AppendInteger(tree_id); |
| 1374 v8::Context::Scope context_scope(context()->v8_context()); | 1370 args.AppendInteger(node->id()); |
| 1375 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); | 1371 bindings_system_->DispatchEventInContext("automationInternal.onChildTreeID", |
| 1376 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); | 1372 &args, nullptr, context()); |
| 1377 args->Set(1U, v8::Integer::New(GetIsolate(), node->id())); | |
| 1378 context()->DispatchEvent("automationInternal.onChildTreeID", args); | |
| 1379 } | 1373 } |
| 1380 | 1374 |
| 1381 void AutomationInternalCustomBindings::SendNodesRemovedEvent( | 1375 void AutomationInternalCustomBindings::SendNodesRemovedEvent( |
| 1382 ui::AXTree* tree, | 1376 ui::AXTree* tree, |
| 1383 const std::vector<int>& ids) { | 1377 const std::vector<int>& ids) { |
| 1384 auto iter = axtree_to_tree_cache_map_.find(tree); | 1378 auto iter = axtree_to_tree_cache_map_.find(tree); |
| 1385 if (iter == axtree_to_tree_cache_map_.end()) | 1379 if (iter == axtree_to_tree_cache_map_.end()) |
| 1386 return; | 1380 return; |
| 1387 | 1381 |
| 1388 int tree_id = iter->second->tree_id; | 1382 int tree_id = iter->second->tree_id; |
| 1389 | 1383 |
| 1390 v8::Isolate* isolate = GetIsolate(); | 1384 base::ListValue args; |
| 1391 v8::HandleScope handle_scope(isolate); | 1385 args.AppendInteger(tree_id); |
| 1392 v8::Context::Scope context_scope(context()->v8_context()); | 1386 { |
| 1393 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); | 1387 auto nodes = base::MakeUnique<base::ListValue>(); |
| 1394 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); | 1388 for (auto id : ids) |
| 1395 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); | 1389 nodes->AppendInteger(id); |
| 1396 args->Set(1U, nodes); | 1390 args.Append(std::move(nodes)); |
| 1397 for (size_t i = 0; i < ids.size(); ++i) | 1391 } |
| 1398 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); | 1392 |
| 1399 context()->DispatchEvent("automationInternal.onNodesRemoved", args); | 1393 bindings_system_->DispatchEventInContext("automationInternal.onNodesRemoved", |
| 1394 &args, nullptr, context()); |
| 1400 } | 1395 } |
| 1401 | 1396 |
| 1402 } // namespace extensions | 1397 } // namespace extensions |
| OLD | NEW |