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

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

Issue 2583273002: [Extensions Bindings] Allow for argument validation without conversion (Closed)
Patch Set: lazyboy's Created 3 years, 11 months 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
« no previous file with comments | « extensions/renderer/api_binding_hooks.h ('k') | extensions/renderer/api_binding_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "extensions/renderer/api_signature.h"
10 #include "gin/arguments.h" 11 #include "gin/arguments.h"
11 #include "gin/handle.h" 12 #include "gin/handle.h"
12 #include "gin/object_template_builder.h" 13 #include "gin/object_template_builder.h"
13 #include "gin/per_context_data.h" 14 #include "gin/per_context_data.h"
14 #include "gin/wrappable.h" 15 #include "gin/wrappable.h"
15 16
16 namespace extensions { 17 namespace extensions {
17 18
18 namespace { 19 namespace {
19 20
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!"; 96 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!";
96 request_hooks_[method_name] = hook; 97 request_hooks_[method_name] = hook;
97 } 98 }
98 99
99 void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source, 100 void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source,
100 v8::Global<v8::String> resource_name) { 101 v8::Global<v8::String> resource_name) {
101 js_hooks_source_ = std::move(source); 102 js_hooks_source_ = std::move(source);
102 js_resource_name_ = std::move(resource_name); 103 js_resource_name_ = std::move(resource_name);
103 } 104 }
104 105
105 bool APIBindingHooks::HandleRequest(const std::string& api_name, 106 APIBindingHooks::RequestResult APIBindingHooks::HandleRequest(
106 const std::string& method_name, 107 const std::string& api_name,
107 v8::Local<v8::Context> context, 108 const std::string& method_name,
108 const APISignature* signature, 109 v8::Local<v8::Context> context,
109 gin::Arguments* arguments) { 110 const APISignature* signature,
111 gin::Arguments* arguments,
112 const ArgumentSpec::RefMap& type_refs) {
110 // Easy case: a native custom hook. 113 // Easy case: a native custom hook.
111 auto request_hooks_iter = request_hooks_.find(method_name); 114 auto request_hooks_iter = request_hooks_.find(method_name);
112 if (request_hooks_iter != request_hooks_.end()) { 115 if (request_hooks_iter != request_hooks_.end()) {
113 request_hooks_iter->second.Run(signature, arguments); 116 RequestResult result =
114 return true; 117 request_hooks_iter->second.Run(signature, arguments, type_refs);
118 // Right now, it doesn't make sense to register a request handler that
119 // doesn't handle the request.
120 DCHECK_NE(RequestResult::NOT_HANDLED, result);
121 return result;
115 } 122 }
116 123
117 // Harder case: looking up a custom hook registered on the context (since 124 // Harder case: looking up a custom hook registered on the context (since
118 // these are JS, each context has a separate instance). 125 // these are JS, each context has a separate instance).
119 gin::PerContextData* per_context_data = gin::PerContextData::From(context); 126 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
120 DCHECK(per_context_data); 127 DCHECK(per_context_data);
121 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>( 128 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>(
122 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey)); 129 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey));
123 if (!data) 130 if (!data)
124 return false; 131 return RequestResult::NOT_HANDLED;
125 132
126 auto hook_interface_iter = data->hook_interfaces.find(api_name); 133 auto hook_interface_iter = data->hook_interfaces.find(api_name);
127 if (hook_interface_iter == data->hook_interfaces.end()) 134 if (hook_interface_iter == data->hook_interfaces.end())
128 return false; 135 return RequestResult::NOT_HANDLED;
129 136
130 JSHookInterface* hook_interface = nullptr; 137 JSHookInterface* hook_interface = nullptr;
131 gin::Converter<JSHookInterface*>::FromV8( 138 gin::Converter<JSHookInterface*>::FromV8(
132 context->GetIsolate(), 139 context->GetIsolate(),
133 hook_interface_iter->second.Get(context->GetIsolate()), &hook_interface); 140 hook_interface_iter->second.Get(context->GetIsolate()), &hook_interface);
134 CHECK(hook_interface); 141 CHECK(hook_interface);
135 142
136 auto js_hook_iter = hook_interface->js_hooks()->find(method_name); 143 auto js_hook_iter = hook_interface->js_hooks()->find(method_name);
137 if (js_hook_iter == hook_interface->js_hooks()->end()) 144 if (js_hook_iter == hook_interface->js_hooks()->end())
138 return false; 145 return RequestResult::NOT_HANDLED;
139 146
140 // Found a JS handler. 147 // Found a JS handler.
141 std::vector<v8::Local<v8::Value>> v8_args; 148 std::vector<v8::Local<v8::Value>> v8_args;
149 std::string error;
150 if (!signature->ParseArgumentsToV8(arguments, type_refs, &v8_args, &error))
151 return RequestResult::INVALID_INVOCATION;
152
142 // TODO(devlin): Right now, this doesn't support exceptions or return values, 153 // TODO(devlin): Right now, this doesn't support exceptions or return values,
143 // which we will need to at some point. 154 // which we will need to at some point.
144 if (arguments->Length() == 0 || arguments->GetRemaining(&v8_args)) { 155 v8::Local<v8::Function> handler =
145 v8::Local<v8::Function> handler = 156 js_hook_iter->second.Get(context->GetIsolate());
146 js_hook_iter->second.Get(context->GetIsolate()); 157 run_js_.Run(handler, context, v8_args.size(), v8_args.data());
147 run_js_.Run(handler, context, v8_args.size(), v8_args.data());
148 }
149 158
150 return true; 159 return RequestResult::HANDLED;
151 } 160 }
152 161
153 void APIBindingHooks::InitializeInContext( 162 void APIBindingHooks::InitializeInContext(
154 v8::Local<v8::Context> context, 163 v8::Local<v8::Context> context,
155 const std::string& api_name) { 164 const std::string& api_name) {
156 if (js_hooks_source_.IsEmpty()) 165 if (js_hooks_source_.IsEmpty())
157 return; 166 return;
158 167
159 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate()); 168 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate());
160 v8::Local<v8::String> resource_name = 169 v8::Local<v8::String> resource_name =
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 gin::Handle<JSHookInterface> hooks = 203 gin::Handle<JSHookInterface> hooks =
195 gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name)); 204 gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name));
196 CHECK(!hooks.IsEmpty()); 205 CHECK(!hooks.IsEmpty());
197 v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>(); 206 v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>();
198 data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object); 207 data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object);
199 208
200 return hooks_object; 209 return hooks_object;
201 } 210 }
202 211
203 } // namespace extensions 212 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/api_binding_hooks.h ('k') | extensions/renderer/api_binding_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698