| 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> |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 bool removed_; | 410 bool removed_; |
| 411 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 411 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 412 | 412 |
| 413 DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); | 413 DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); |
| 414 }; | 414 }; |
| 415 | 415 |
| 416 AutomationInternalCustomBindings::AutomationInternalCustomBindings( | 416 AutomationInternalCustomBindings::AutomationInternalCustomBindings( |
| 417 ScriptContext* context) | 417 ScriptContext* context) |
| 418 : ObjectBackedNativeHandler(context), | 418 : ObjectBackedNativeHandler(context), |
| 419 is_active_profile_(true), | 419 is_active_profile_(true), |
| 420 tree_change_observer_overall_filter_( | 420 tree_change_observer_overall_filter_(0) { |
| 421 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES) { | |
| 422 // It's safe to use base::Unretained(this) here because these bindings | 421 // It's safe to use base::Unretained(this) here because these bindings |
| 423 // will only be called on a valid AutomationInternalCustomBindings instance | 422 // will only be called on a valid AutomationInternalCustomBindings instance |
| 424 // and none of the functions have any side effects. | 423 // and none of the functions have any side effects. |
| 425 #define ROUTE_FUNCTION(FN) \ | 424 #define ROUTE_FUNCTION(FN) \ |
| 426 RouteFunction(#FN, "automation", \ | 425 RouteFunction(#FN, "automation", \ |
| 427 base::Bind(&AutomationInternalCustomBindings::FN, \ | 426 base::Bind(&AutomationInternalCustomBindings::FN, \ |
| 428 base::Unretained(this))) | 427 base::Unretained(this))) |
| 429 ROUTE_FUNCTION(IsInteractPermitted); | 428 ROUTE_FUNCTION(IsInteractPermitted); |
| 430 ROUTE_FUNCTION(GetSchemaAdditions); | 429 ROUTE_FUNCTION(GetSchemaAdditions); |
| 431 ROUTE_FUNCTION(GetRoutingID); | 430 ROUTE_FUNCTION(GetRoutingID); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 observer.id = args[0]->Int32Value(); | 779 observer.id = args[0]->Int32Value(); |
| 781 std::string filter_str = *v8::String::Utf8Value(args[1]); | 780 std::string filter_str = *v8::String::Utf8Value(args[1]); |
| 782 observer.filter = api::automation::ParseTreeChangeObserverFilter(filter_str); | 781 observer.filter = api::automation::ParseTreeChangeObserverFilter(filter_str); |
| 783 | 782 |
| 784 tree_change_observers_.push_back(observer); | 783 tree_change_observers_.push_back(observer); |
| 785 UpdateOverallTreeChangeObserverFilter(); | 784 UpdateOverallTreeChangeObserverFilter(); |
| 786 } | 785 } |
| 787 | 786 |
| 788 void AutomationInternalCustomBindings::RemoveTreeChangeObserver( | 787 void AutomationInternalCustomBindings::RemoveTreeChangeObserver( |
| 789 const v8::FunctionCallbackInfo<v8::Value>& args) { | 788 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 790 if (args.Length() != 1 || !args[0]->IsNumber()) { | 789 // The argument is an integer key for an object which is automatically |
| 790 // converted to a string. |
| 791 if (args.Length() != 1 || !args[0]->IsString()) { |
| 791 ThrowInvalidArgumentsException(this); | 792 ThrowInvalidArgumentsException(this); |
| 792 return; | 793 return; |
| 793 } | 794 } |
| 794 | 795 |
| 795 int observer_id = args[0]->Int32Value(); | 796 int observer_id = args[0]->Int32Value(); |
| 796 | 797 |
| 797 for (auto iter = tree_change_observers_.begin(); | 798 for (auto iter = tree_change_observers_.begin(); |
| 798 iter != tree_change_observers_.end(); ++iter) { | 799 iter != tree_change_observers_.end(); ++iter) { |
| 799 if (iter->id == observer_id) { | 800 if (iter->id == observer_id) { |
| 800 tree_change_observers_.erase(iter); | 801 tree_change_observers_.erase(iter); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 } | 944 } |
| 944 if (cache->tree.data().focus_id == node->id()) { | 945 if (cache->tree.data().focus_id == node->id()) { |
| 945 state->Set(CreateV8String(isolate, "focused"), | 946 state->Set(CreateV8String(isolate, "focused"), |
| 946 v8::Boolean::New(isolate, true)); | 947 v8::Boolean::New(isolate, true)); |
| 947 } | 948 } |
| 948 | 949 |
| 949 args.GetReturnValue().Set(state); | 950 args.GetReturnValue().Set(state); |
| 950 } | 951 } |
| 951 | 952 |
| 952 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { | 953 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { |
| 953 tree_change_observer_overall_filter_ = | 954 tree_change_observer_overall_filter_ = 0; |
| 954 api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES; | 955 for (const auto& observer : tree_change_observers_) |
| 955 for (const auto& observer : tree_change_observers_) { | 956 tree_change_observer_overall_filter_ |= 1 << observer.filter; |
| 956 tree_change_observer_overall_filter_ = | |
| 957 std::max(observer.filter, tree_change_observer_overall_filter_); | |
| 958 } | |
| 959 } | 957 } |
| 960 | 958 |
| 961 ui::AXNode* AutomationInternalCustomBindings::GetParent( | 959 ui::AXNode* AutomationInternalCustomBindings::GetParent( |
| 962 ui::AXNode* node, | 960 ui::AXNode* node, |
| 963 TreeCache** in_out_cache) { | 961 TreeCache** in_out_cache) { |
| 964 if (node->parent()) | 962 if (node->parent()) |
| 965 return node->parent(); | 963 return node->parent(); |
| 966 | 964 |
| 967 int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id; | 965 int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id; |
| 968 if (parent_tree_id < 0) | 966 if (parent_tree_id < 0) |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 ui::AXNode* node) { | 1198 ui::AXNode* node) { |
| 1201 // Don't send tree change events when it's not the active profile. | 1199 // Don't send tree change events when it's not the active profile. |
| 1202 if (!is_active_profile_) | 1200 if (!is_active_profile_) |
| 1203 return; | 1201 return; |
| 1204 | 1202 |
| 1205 // Always notify the custom bindings when there's a node with a child tree | 1203 // Always notify the custom bindings when there's a node with a child tree |
| 1206 // ID that might need to be loaded. | 1204 // ID that might need to be loaded. |
| 1207 if (node->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) | 1205 if (node->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) |
| 1208 SendChildTreeIDEvent(tree, node); | 1206 SendChildTreeIDEvent(tree, node); |
| 1209 | 1207 |
| 1210 switch (tree_change_observer_overall_filter_) { | 1208 bool has_filter = false; |
| 1211 case api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES: | 1209 if (tree_change_observer_overall_filter_ & |
| 1212 default: | 1210 (1 << |
| 1213 return; | 1211 api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES)) { |
| 1214 case api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES: | 1212 if (node->data().HasStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS) || |
| 1215 if (!node->data().HasStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS) && | 1213 node->data().role == ui::AX_ROLE_ALERT) { |
| 1216 node->data().role != ui::AX_ROLE_ALERT) { | 1214 has_filter = true; |
| 1217 return; | 1215 } |
| 1218 } | |
| 1219 break; | |
| 1220 case api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES: | |
| 1221 break; | |
| 1222 } | 1216 } |
| 1223 | 1217 |
| 1218 if (tree_change_observer_overall_filter_ & |
| 1219 (1 << api::automation::TREE_CHANGE_OBSERVER_FILTER_TEXTMARKERCHANGES)) { |
| 1220 if (node->data().HasIntListAttribute(ui::AX_ATTR_MARKER_TYPES)) |
| 1221 has_filter = true; |
| 1222 } |
| 1223 |
| 1224 if (tree_change_observer_overall_filter_ & |
| 1225 (1 << api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES)) |
| 1226 has_filter = true; |
| 1227 |
| 1228 if (!has_filter) |
| 1229 return; |
| 1230 |
| 1224 auto iter = axtree_to_tree_cache_map_.find(tree); | 1231 auto iter = axtree_to_tree_cache_map_.find(tree); |
| 1225 if (iter == axtree_to_tree_cache_map_.end()) | 1232 if (iter == axtree_to_tree_cache_map_.end()) |
| 1226 return; | 1233 return; |
| 1227 | 1234 |
| 1228 int tree_id = iter->second->tree_id; | 1235 int tree_id = iter->second->tree_id; |
| 1229 | 1236 |
| 1230 v8::Isolate* isolate = GetIsolate(); | 1237 v8::Isolate* isolate = GetIsolate(); |
| 1231 v8::HandleScope handle_scope(isolate); | 1238 v8::HandleScope handle_scope(isolate); |
| 1232 v8::Context::Scope context_scope(context()->v8_context()); | 1239 v8::Context::Scope context_scope(context()->v8_context()); |
| 1233 | 1240 |
| 1234 for (const auto& observer : tree_change_observers_) { | 1241 for (const auto& observer : tree_change_observers_) { |
| 1235 switch (observer.filter) { | 1242 switch (observer.filter) { |
| 1236 case api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES: | 1243 case api::automation::TREE_CHANGE_OBSERVER_FILTER_NOTREECHANGES: |
| 1237 default: | 1244 default: |
| 1238 continue; | 1245 continue; |
| 1239 case api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES: | 1246 case api::automation::TREE_CHANGE_OBSERVER_FILTER_LIVEREGIONTREECHANGES: |
| 1240 if (!node->data().HasStringAttribute( | 1247 if (!node->data().HasStringAttribute( |
| 1241 ui::AX_ATTR_CONTAINER_LIVE_STATUS) && | 1248 ui::AX_ATTR_CONTAINER_LIVE_STATUS) && |
| 1242 node->data().role != ui::AX_ROLE_ALERT) { | 1249 node->data().role != ui::AX_ROLE_ALERT) { |
| 1243 continue; | 1250 continue; |
| 1244 } | 1251 } |
| 1245 break; | 1252 break; |
| 1253 case api::automation::TREE_CHANGE_OBSERVER_FILTER_TEXTMARKERCHANGES: |
| 1254 if (!node->data().HasIntListAttribute(ui::AX_ATTR_MARKER_TYPES)) |
| 1255 continue; |
| 1256 break; |
| 1246 case api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES: | 1257 case api::automation::TREE_CHANGE_OBSERVER_FILTER_ALLTREECHANGES: |
| 1247 break; | 1258 break; |
| 1248 } | 1259 } |
| 1249 | 1260 |
| 1250 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 4U)); | 1261 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 4U)); |
| 1251 args->Set(0U, v8::Integer::New(GetIsolate(), observer.id)); | 1262 args->Set(0U, v8::Integer::New(GetIsolate(), observer.id)); |
| 1252 args->Set(1U, v8::Integer::New(GetIsolate(), tree_id)); | 1263 args->Set(1U, v8::Integer::New(GetIsolate(), tree_id)); |
| 1253 args->Set(2U, v8::Integer::New(GetIsolate(), node->id())); | 1264 args->Set(2U, v8::Integer::New(GetIsolate(), node->id())); |
| 1254 args->Set(3U, CreateV8String(isolate, ToString(change_type))); | 1265 args->Set(3U, CreateV8String(isolate, ToString(change_type))); |
| 1255 context()->DispatchEvent("automationInternal.onTreeChange", args); | 1266 context()->DispatchEvent("automationInternal.onTreeChange", args); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); | 1299 v8::Local<v8::Array> args(v8::Array::New(GetIsolate(), 2U)); |
| 1289 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); | 1300 args->Set(0U, v8::Integer::New(GetIsolate(), tree_id)); |
| 1290 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); | 1301 v8::Local<v8::Array> nodes(v8::Array::New(GetIsolate(), ids.size())); |
| 1291 args->Set(1U, nodes); | 1302 args->Set(1U, nodes); |
| 1292 for (size_t i = 0; i < ids.size(); ++i) | 1303 for (size_t i = 0; i < ids.size(); ++i) |
| 1293 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); | 1304 nodes->Set(i, v8::Integer::New(GetIsolate(), ids[i])); |
| 1294 context()->DispatchEvent("automationInternal.onNodesRemoved", args); | 1305 context()->DispatchEvent("automationInternal.onNodesRemoved", args); |
| 1295 } | 1306 } |
| 1296 | 1307 |
| 1297 } // namespace extensions | 1308 } // namespace extensions |
| OLD | NEW |