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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/common/extensions/chrome_extension_messages.h" |
10 #include "chrome/common/extensions/manifest_handlers/automation.h" | 11 #include "chrome/common/extensions/manifest_handlers/automation.h" |
11 #include "content/public/child/v8_value_converter.h" | 12 #include "content/public/child/v8_value_converter.h" |
| 13 #include "content/public/renderer/render_thread.h" |
| 14 #include "content/public/renderer/render_view.h" |
12 #include "extensions/common/extension.h" | 15 #include "extensions/common/extension.h" |
13 #include "extensions/common/manifest.h" | 16 #include "extensions/common/manifest.h" |
14 #include "extensions/renderer/script_context.h" | 17 #include "extensions/renderer/script_context.h" |
| 18 #include "ipc/message_filter.h" |
15 #include "ui/accessibility/ax_enums.h" | 19 #include "ui/accessibility/ax_enums.h" |
| 20 #include "ui/accessibility/ax_node.h" |
16 | 21 |
17 namespace { | 22 namespace { |
18 | 23 |
19 // Helper to convert an enum to a V8 object. | 24 // Helper to convert an enum to a V8 object. |
20 template <typename EnumType> | 25 template <typename EnumType> |
21 v8::Local<v8::Object> ToEnumObject(v8::Isolate* isolate, | 26 v8::Local<v8::Object> ToEnumObject(v8::Isolate* isolate, |
22 EnumType start_after, | 27 EnumType start_after, |
23 EnumType end_at) { | 28 EnumType end_at) { |
24 v8::Local<v8::Object> object = v8::Object::New(isolate); | 29 v8::Local<v8::Object> object = v8::Object::New(isolate); |
25 for (int i = start_after + 1; i <= end_at; ++i) { | 30 for (int i = start_after + 1; i <= end_at; ++i) { |
26 v8::Local<v8::String> value = v8::String::NewFromUtf8( | 31 v8::Local<v8::String> value = v8::String::NewFromUtf8( |
27 isolate, ui::ToString(static_cast<EnumType>(i)).c_str()); | 32 isolate, ui::ToString(static_cast<EnumType>(i)).c_str()); |
28 object->Set(value, value); | 33 object->Set(value, value); |
29 } | 34 } |
30 return object; | 35 return object; |
31 } | 36 } |
32 | 37 |
33 } // namespace | 38 } // namespace |
34 | 39 |
35 namespace extensions { | 40 namespace extensions { |
36 | 41 |
| 42 class AutomationMessageFilter : public IPC::MessageFilter { |
| 43 public: |
| 44 explicit AutomationMessageFilter(AutomationInternalCustomBindings* owner) |
| 45 : owner_(owner), |
| 46 removed_(false) { |
| 47 DCHECK(owner); |
| 48 content::RenderThread::Get()->AddFilter(this); |
| 49 } |
| 50 |
| 51 void Detach() { |
| 52 owner_ = nullptr; |
| 53 Remove(); |
| 54 } |
| 55 |
| 56 // IPC::MessageFilter |
| 57 bool OnMessageReceived(const IPC::Message& message) override { |
| 58 if (owner_) |
| 59 return owner_->OnMessageReceived(message); |
| 60 else |
| 61 return false; |
| 62 } |
| 63 |
| 64 void OnFilterRemoved() override { |
| 65 removed_ = true; |
| 66 } |
| 67 |
| 68 private: |
| 69 ~AutomationMessageFilter() override { |
| 70 Remove(); |
| 71 } |
| 72 |
| 73 void Remove() { |
| 74 if (!removed_) { |
| 75 removed_ = true; |
| 76 content::RenderThread::Get()->RemoveFilter(this); |
| 77 } |
| 78 } |
| 79 |
| 80 AutomationInternalCustomBindings* owner_; |
| 81 bool removed_; |
| 82 |
| 83 DISALLOW_COPY_AND_ASSIGN(AutomationMessageFilter); |
| 84 }; |
| 85 |
37 AutomationInternalCustomBindings::AutomationInternalCustomBindings( | 86 AutomationInternalCustomBindings::AutomationInternalCustomBindings( |
38 ScriptContext* context) : ObjectBackedNativeHandler(context) { | 87 ScriptContext* context) : ObjectBackedNativeHandler(context) { |
| 88 // It's safe to use base::Unretained(this) here because these bindings |
| 89 // will only be called on a valid AutomationInternalCustomBindings instance |
| 90 // and none of the functions have any side effects. |
39 RouteFunction( | 91 RouteFunction( |
40 "IsInteractPermitted", | 92 "IsInteractPermitted", |
41 base::Bind(&AutomationInternalCustomBindings::IsInteractPermitted, | 93 base::Bind(&AutomationInternalCustomBindings::IsInteractPermitted, |
42 base::Unretained(this))); | 94 base::Unretained(this))); |
43 RouteFunction( | 95 RouteFunction( |
44 "GetSchemaAdditions", | 96 "GetSchemaAdditions", |
45 base::Bind(&AutomationInternalCustomBindings::GetSchemaAdditions, | 97 base::Bind(&AutomationInternalCustomBindings::GetSchemaAdditions, |
46 base::Unretained(this))); | 98 base::Unretained(this))); |
| 99 RouteFunction( |
| 100 "GetRoutingID", |
| 101 base::Bind(&AutomationInternalCustomBindings::GetRoutingID, |
| 102 base::Unretained(this))); |
| 103 |
| 104 message_filter_ = new AutomationMessageFilter(this); |
47 } | 105 } |
48 | 106 |
49 AutomationInternalCustomBindings::~AutomationInternalCustomBindings() { | 107 AutomationInternalCustomBindings::~AutomationInternalCustomBindings() { |
| 108 message_filter_->Detach(); |
| 109 } |
| 110 |
| 111 bool AutomationInternalCustomBindings::OnMessageReceived( |
| 112 const IPC::Message& message) { |
| 113 IPC_BEGIN_MESSAGE_MAP(AutomationInternalCustomBindings, message) |
| 114 IPC_MESSAGE_HANDLER(ExtensionMsg_AccessibilityEvent, OnAccessibilityEvent) |
| 115 IPC_END_MESSAGE_MAP() |
| 116 |
| 117 // Always return false in case there are multiple |
| 118 // AutomationInternalCustomBindings instances attached to the same thread. |
| 119 return false; |
50 } | 120 } |
51 | 121 |
52 void AutomationInternalCustomBindings::IsInteractPermitted( | 122 void AutomationInternalCustomBindings::IsInteractPermitted( |
53 const v8::FunctionCallbackInfo<v8::Value>& args) { | 123 const v8::FunctionCallbackInfo<v8::Value>& args) { |
54 const Extension* extension = context()->extension(); | 124 const Extension* extension = context()->extension(); |
55 CHECK(extension); | 125 CHECK(extension); |
56 const AutomationInfo* automation_info = AutomationInfo::Get(extension); | 126 const AutomationInfo* automation_info = AutomationInfo::Get(extension); |
57 CHECK(automation_info); | 127 CHECK(automation_info); |
58 args.GetReturnValue().Set( | 128 args.GetReturnValue().Set( |
59 v8::Boolean::New(GetIsolate(), automation_info->interact)); | 129 v8::Boolean::New(GetIsolate(), automation_info->interact)); |
60 } | 130 } |
61 | 131 |
| 132 void AutomationInternalCustomBindings::GetRoutingID( |
| 133 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 134 int routing_id = context()->GetRenderView()->GetRoutingID(); |
| 135 args.GetReturnValue().Set(v8::Integer::New(GetIsolate(), routing_id)); |
| 136 } |
| 137 |
62 void AutomationInternalCustomBindings::GetSchemaAdditions( | 138 void AutomationInternalCustomBindings::GetSchemaAdditions( |
63 const v8::FunctionCallbackInfo<v8::Value>& args) { | 139 const v8::FunctionCallbackInfo<v8::Value>& args) { |
64 v8::Local<v8::Object> additions = v8::Object::New(GetIsolate()); | 140 v8::Local<v8::Object> additions = v8::Object::New(GetIsolate()); |
65 | 141 |
66 additions->Set( | 142 additions->Set( |
67 v8::String::NewFromUtf8(GetIsolate(), "EventType"), | 143 v8::String::NewFromUtf8(GetIsolate(), "EventType"), |
68 ToEnumObject(GetIsolate(), ui::AX_EVENT_NONE, ui::AX_EVENT_LAST)); | 144 ToEnumObject(GetIsolate(), ui::AX_EVENT_NONE, ui::AX_EVENT_LAST)); |
69 | 145 |
70 additions->Set( | 146 additions->Set( |
71 v8::String::NewFromUtf8(GetIsolate(), "RoleType"), | 147 v8::String::NewFromUtf8(GetIsolate(), "RoleType"), |
72 ToEnumObject(GetIsolate(), ui::AX_ROLE_NONE, ui::AX_ROLE_LAST)); | 148 ToEnumObject(GetIsolate(), ui::AX_ROLE_NONE, ui::AX_ROLE_LAST)); |
73 | 149 |
74 additions->Set( | 150 additions->Set( |
75 v8::String::NewFromUtf8(GetIsolate(), "StateType"), | 151 v8::String::NewFromUtf8(GetIsolate(), "StateType"), |
76 ToEnumObject(GetIsolate(), ui::AX_STATE_NONE, ui::AX_STATE_LAST)); | 152 ToEnumObject(GetIsolate(), ui::AX_STATE_NONE, ui::AX_STATE_LAST)); |
77 | 153 |
78 additions->Set( | 154 additions->Set( |
79 v8::String::NewFromUtf8(GetIsolate(), "TreeChangeType"), | 155 v8::String::NewFromUtf8(GetIsolate(), "TreeChangeType"), |
80 ToEnumObject(GetIsolate(), ui::AX_MUTATION_NONE, ui::AX_MUTATION_LAST)); | 156 ToEnumObject(GetIsolate(), ui::AX_MUTATION_NONE, ui::AX_MUTATION_LAST)); |
81 | 157 |
82 args.GetReturnValue().Set(additions); | 158 args.GetReturnValue().Set(additions); |
83 } | 159 } |
84 | 160 |
| 161 void AutomationInternalCustomBindings::OnAccessibilityEvent( |
| 162 const ExtensionMsg_AccessibilityEventParams& params) { |
| 163 // TODO(dmazzoni): finish implementing this. |
| 164 } |
| 165 |
85 } // namespace extensions | 166 } // namespace extensions |
OLD | NEW |