Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: extensions/renderer/api_binding_hooks.cc

Issue 2575173002: [Extensions Bindings] Add a bridge to use current custom bindings (Closed)
Patch Set: update test Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "extensions/renderer/api_binding_hooks.h" 5 #include "extensions/renderer/api_binding_hooks.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/supports_user_data.h" 9 #include "base/supports_user_data.h"
10 #include "gin/arguments.h" 10 #include "gin/arguments.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 77 }
78 78
79 v8::Isolate* isolate; 79 v8::Isolate* isolate;
80 80
81 std::map<std::string, v8::Global<v8::Object>> hook_interfaces; 81 std::map<std::string, v8::Global<v8::Object>> hook_interfaces;
82 }; 82 };
83 83
84 gin::WrapperInfo JSHookInterface::kWrapperInfo = 84 gin::WrapperInfo JSHookInterface::kWrapperInfo =
85 {gin::kEmbedderNativeGin}; 85 {gin::kEmbedderNativeGin};
86 86
87 // Creates and returns JS object for the hook interface to allow for
88 // registering custom hooks from JS.
89 v8::Local<v8::Object> CreateJSHookInterface(const std::string& api_name,
90 v8::Local<v8::Context> context) {
91 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
92 DCHECK(per_context_data);
93 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>(
94 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey));
95 if (!data) {
96 auto api_data =
97 base::MakeUnique<APIHooksPerContextData>(context->GetIsolate());
98 data = api_data.get();
99 per_context_data->SetUserData(kExtensionAPIHooksPerContextKey,
100 api_data.release());
101 }
102
103 DCHECK(data->hook_interfaces.find(api_name) == data->hook_interfaces.end());
104
105 gin::Handle<JSHookInterface> hooks =
106 gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name));
107 CHECK(!hooks.IsEmpty());
108 v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>();
109 data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object);
110
111 return hooks_object;
112 }
113
114 } // namespace 87 } // namespace
115 88
116 APIBindingHooks::APIBindingHooks(const binding::RunJSFunction& run_js) 89 APIBindingHooks::APIBindingHooks(const binding::RunJSFunction& run_js)
117 : run_js_(run_js) {} 90 : run_js_(run_js) {}
118 APIBindingHooks::~APIBindingHooks() {} 91 APIBindingHooks::~APIBindingHooks() {}
119 92
120 void APIBindingHooks::RegisterHandleRequest(const std::string& method_name, 93 void APIBindingHooks::RegisterHandleRequest(const std::string& method_name,
121 const HandleRequestHook& hook) { 94 const HandleRequestHook& hook) {
122 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!"; 95 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!";
123 request_hooks_[method_name] = hook; 96 request_hooks_[method_name] = hook;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 CHECK(hook_interface); 135 CHECK(hook_interface);
163 136
164 auto js_hook_iter = hook_interface->js_hooks()->find(method_name); 137 auto js_hook_iter = hook_interface->js_hooks()->find(method_name);
165 if (js_hook_iter == hook_interface->js_hooks()->end()) 138 if (js_hook_iter == hook_interface->js_hooks()->end())
166 return false; 139 return false;
167 140
168 // Found a JS handler. 141 // Found a JS handler.
169 std::vector<v8::Local<v8::Value>> v8_args; 142 std::vector<v8::Local<v8::Value>> v8_args;
170 // TODO(devlin): Right now, this doesn't support exceptions or return values, 143 // TODO(devlin): Right now, this doesn't support exceptions or return values,
171 // which we will need to at some point. 144 // which we will need to at some point.
172 if (arguments->GetRemaining(&v8_args)) { 145 if (arguments->Length() == 0 || arguments->GetRemaining(&v8_args)) {
173 v8::Local<v8::Function> handler = 146 v8::Local<v8::Function> handler =
174 js_hook_iter->second.Get(context->GetIsolate()); 147 js_hook_iter->second.Get(context->GetIsolate());
175 run_js_.Run(handler, context, v8_args.size(), v8_args.data()); 148 run_js_.Run(handler, context, v8_args.size(), v8_args.data());
176 } 149 }
177 150
178 return true; 151 return true;
179 } 152 }
180 153
181 void APIBindingHooks::InitializeInContext( 154 void APIBindingHooks::InitializeInContext(
182 v8::Local<v8::Context> context, 155 v8::Local<v8::Context> context,
183 const std::string& api_name) { 156 const std::string& api_name) {
184 if (js_hooks_source_.IsEmpty()) 157 if (js_hooks_source_.IsEmpty())
185 return; 158 return;
186 159
187 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate()); 160 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate());
188 v8::Local<v8::String> resource_name = 161 v8::Local<v8::String> resource_name =
189 js_resource_name_.Get(context->GetIsolate()); 162 js_resource_name_.Get(context->GetIsolate());
190 v8::Local<v8::Script> script; 163 v8::Local<v8::Script> script;
191 v8::ScriptOrigin origin(resource_name); 164 v8::ScriptOrigin origin(resource_name);
192 if (!v8::Script::Compile(context, source, &origin).ToLocal(&script)) 165 if (!v8::Script::Compile(context, source, &origin).ToLocal(&script))
193 return; 166 return;
194 v8::Local<v8::Value> func_as_value = script->Run(); 167 v8::Local<v8::Value> func_as_value = script->Run();
195 v8::Local<v8::Function> function; 168 v8::Local<v8::Function> function;
196 if (!gin::ConvertFromV8(context->GetIsolate(), func_as_value, &function)) 169 if (!gin::ConvertFromV8(context->GetIsolate(), func_as_value, &function))
197 return; 170 return;
198 v8::Local<v8::Object> api_hooks = CreateJSHookInterface(api_name, context); 171 v8::Local<v8::Value> api_hooks = GetJSHookInterface(api_name, context);
199 v8::Local<v8::Value> args[] = {api_hooks}; 172 v8::Local<v8::Value> args[] = {api_hooks};
200 run_js_.Run(function, context, arraysize(args), args); 173 run_js_.Run(function, context, arraysize(args), args);
201 } 174 }
202 175
176 v8::Local<v8::Object> APIBindingHooks::GetJSHookInterface(
177 const std::string& api_name,
178 v8::Local<v8::Context> context) {
179 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
180 DCHECK(per_context_data);
181 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>(
182 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey));
183 if (!data) {
184 auto api_data =
185 base::MakeUnique<APIHooksPerContextData>(context->GetIsolate());
186 data = api_data.get();
187 per_context_data->SetUserData(kExtensionAPIHooksPerContextKey,
188 api_data.release());
189 }
190
191 auto iter = data->hook_interfaces.find(api_name);
192 if (iter != data->hook_interfaces.end())
193 return iter->second.Get(context->GetIsolate());
194
195 gin::Handle<JSHookInterface> hooks =
196 gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name));
197 CHECK(!hooks.IsEmpty());
198 v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>();
199 data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object);
200
201 return hooks_object;
202 }
203
203 } // namespace extensions 204 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698