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

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

Issue 2494653005: Support API aliases (Closed)
Patch Set: . 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/js_extension_bindings_system.h" 5 #include "extensions/renderer/js_extension_bindings_system.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
9 #include "content/public/child/v8_value_converter.h" 9 #include "content/public/child/v8_value_converter.h"
10 #include "content/public/common/content_switches.h" 10 #include "content/public/common/content_switches.h"
11 #include "extensions/common/extension.h" 11 #include "extensions/common/extension.h"
12 #include "extensions/common/extension_api.h"
12 #include "extensions/common/extension_urls.h" 13 #include "extensions/common/extension_urls.h"
13 #include "extensions/common/extensions_client.h" 14 #include "extensions/common/extensions_client.h"
14 #include "extensions/common/features/feature.h" 15 #include "extensions/common/features/feature.h"
15 #include "extensions/common/features/feature_provider.h" 16 #include "extensions/common/features/feature_provider.h"
16 #include "extensions/common/manifest_constants.h" 17 #include "extensions/common/manifest_constants.h"
17 #include "extensions/common/manifest_handlers/externally_connectable.h" 18 #include "extensions/common/manifest_handlers/externally_connectable.h"
18 #include "extensions/renderer/binding_generating_native_handler.h" 19 #include "extensions/renderer/binding_generating_native_handler.h"
19 #include "extensions/renderer/renderer_extension_registry.h" 20 #include "extensions/renderer/renderer_extension_registry.h"
20 #include "extensions/renderer/resource_bundle_source_map.h" 21 #include "extensions/renderer/resource_bundle_source_map.h"
21 #include "extensions/renderer/script_context.h" 22 #include "extensions/renderer/script_context.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 // TODO(kalman): Make the bindings registration have zero overhead then run 172 // TODO(kalman): Make the bindings registration have zero overhead then run
172 // the same code regardless of context type. 173 // the same code regardless of context type.
173 switch (context->context_type()) { 174 switch (context->context_type()) {
174 case Feature::UNSPECIFIED_CONTEXT: 175 case Feature::UNSPECIFIED_CONTEXT:
175 case Feature::WEB_PAGE_CONTEXT: 176 case Feature::WEB_PAGE_CONTEXT:
176 case Feature::BLESSED_WEB_PAGE_CONTEXT: 177 case Feature::BLESSED_WEB_PAGE_CONTEXT:
177 // Hard-code registration of any APIs that are exposed to webpage-like 178 // Hard-code registration of any APIs that are exposed to webpage-like
178 // contexts, because it's too expensive to run the full bindings code. 179 // contexts, because it's too expensive to run the full bindings code.
179 // All of the same permission checks will still apply. 180 // All of the same permission checks will still apply.
180 if (context->GetAvailability("app").is_available()) 181 if (context->GetAvailability("app").is_available())
181 RegisterBinding("app", context); 182 RegisterBinding("app", "app", context);
182 if (context->GetAvailability("webstore").is_available()) 183 if (context->GetAvailability("webstore").is_available())
183 RegisterBinding("webstore", context); 184 RegisterBinding("webstore", "webstore", context);
184 if (context->GetAvailability("dashboardPrivate").is_available()) 185 if (context->GetAvailability("dashboardPrivate").is_available())
185 RegisterBinding("dashboardPrivate", context); 186 RegisterBinding("dashboardPrivate", "dashboardPrivate", context);
186 if (IsRuntimeAvailableToContext(context)) 187 if (IsRuntimeAvailableToContext(context))
187 RegisterBinding("runtime", context); 188 RegisterBinding("runtime", "runtime", context);
188 break; 189 break;
189 190
190 case Feature::SERVICE_WORKER_CONTEXT: 191 case Feature::SERVICE_WORKER_CONTEXT:
191 DCHECK(ExtensionsClient::Get() 192 DCHECK(ExtensionsClient::Get()
192 ->ExtensionAPIEnabledInExtensionServiceWorkers()); 193 ->ExtensionAPIEnabledInExtensionServiceWorkers());
193 // Intentional fallthrough. 194 // Intentional fallthrough.
194 case Feature::BLESSED_EXTENSION_CONTEXT: 195 case Feature::BLESSED_EXTENSION_CONTEXT:
195 case Feature::UNBLESSED_EXTENSION_CONTEXT: 196 case Feature::UNBLESSED_EXTENSION_CONTEXT:
196 case Feature::CONTENT_SCRIPT_CONTEXT: 197 case Feature::CONTENT_SCRIPT_CONTEXT:
197 case Feature::WEBUI_CONTEXT: { 198 case Feature::WEBUI_CONTEXT: {
(...skipping 12 matching lines...) Expand all
210 if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr) 211 if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr)
211 continue; 212 continue;
212 213
213 // Skip chrome.test if this isn't a test. 214 // Skip chrome.test if this isn't a test.
214 if (map_entry.first == "test" && 215 if (map_entry.first == "test" &&
215 !base::CommandLine::ForCurrentProcess()->HasSwitch( 216 !base::CommandLine::ForCurrentProcess()->HasSwitch(
216 ::switches::kTestType)) { 217 ::switches::kTestType)) {
217 continue; 218 continue;
218 } 219 }
219 220
220 if (context->IsAnyFeatureAvailableToContext(*map_entry.second)) { 221 if (context->IsAnyFeatureAvailableToContext(
222 *map_entry.second, CheckAliasStatus::NOT_ALLOWED)) {
223 // Check if the API feature is indeed an alias. If it is, the API
224 // should use source API bindings as its own.
225 const std::string& source = map_entry.second->source();
221 // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread 226 // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread
222 // safety issue? 227 // safety issue?
223 RegisterBinding(map_entry.first, context); 228 RegisterBinding(source.empty() ? map_entry.first : source,
229 map_entry.first, context);
224 } 230 }
225 } 231 }
226 break; 232 break;
227 } 233 }
228 } 234 }
229 } 235 }
230 236
231 void JsExtensionBindingsSystem::HandleResponse(int request_id, 237 void JsExtensionBindingsSystem::HandleResponse(int request_id,
232 bool success, 238 bool success,
233 const base::ListValue& response, 239 const base::ListValue& response,
(...skipping 25 matching lines...) Expand all
259 arguments.push_back( 265 arguments.push_back(
260 converter->ToV8Value(filtering_info, context->v8_context())); 266 converter->ToV8Value(filtering_info, context->v8_context()));
261 } 267 }
262 } 268 }
263 269
264 context->module_system()->CallModuleMethodSafe( 270 context->module_system()->CallModuleMethodSafe(
265 kEventBindings, kEventDispatchFunction, arguments.size(), 271 kEventBindings, kEventDispatchFunction, arguments.size(),
266 arguments.data()); 272 arguments.data());
267 } 273 }
268 274
269 void JsExtensionBindingsSystem::RegisterBinding(const std::string& api_name, 275 void JsExtensionBindingsSystem::RegisterBinding(
270 ScriptContext* context) { 276 const std::string& api_name,
277 const std::string& api_bind_name,
278 ScriptContext* context) {
271 std::string bind_name; 279 std::string bind_name;
272 v8::Local<v8::Object> bind_object = 280 v8::Local<v8::Object> bind_object =
273 GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context); 281 GetOrCreateBindObjectIfAvailable(api_bind_name, &bind_name, context);
274 282
275 // Empty if the bind object failed to be created, probably because the 283 // Empty if the bind object failed to be created, probably because the
276 // extension overrode chrome with a non-object, e.g. window.chrome = true. 284 // extension overrode chrome with a non-object, e.g. window.chrome = true.
277 if (bind_object.IsEmpty()) 285 if (bind_object.IsEmpty())
278 return; 286 return;
279 287
280 v8::Local<v8::String> v8_bind_name = 288 v8::Local<v8::String> v8_bind_name =
281 v8::String::NewFromUtf8(context->isolate(), bind_name.c_str()); 289 v8::String::NewFromUtf8(context->isolate(), bind_name.c_str());
282 if (bind_object->HasRealNamedProperty(v8_bind_name)) { 290 if (bind_object->HasRealNamedProperty(v8_bind_name)) {
283 // The bind object may already have the property if the API has been 291 // The bind object may already have the property if the API has been
284 // registered before (or if the extension has put something there already, 292 // registered before (or if the extension has put something there already,
285 // but, whatevs). 293 // but, whatevs).
286 // 294 //
287 // In the former case, we need to re-register the bindings for the APIs 295 // In the former case, we need to re-register the bindings for the APIs
288 // which the extension now has permissions for (if any), but not touch any 296 // which the extension now has permissions for (if any), but not touch any
289 // others so that we don't destroy state such as event listeners. 297 // others so that we don't destroy state such as event listeners.
290 // 298 //
291 // TODO(kalman): Only register available APIs to make this all moot. 299 // TODO(kalman): Only register available APIs to make this all moot.
292 if (bind_object->HasRealNamedCallbackProperty(v8_bind_name)) 300 if (bind_object->HasRealNamedCallbackProperty(v8_bind_name))
293 return; // lazy binding still there, nothing to do 301 return; // lazy binding still there, nothing to do
294 if (bind_object->Get(v8_bind_name)->IsObject()) 302 if (bind_object->Get(v8_bind_name)->IsObject())
295 return; // binding has already been fully installed 303 return; // binding has already been fully installed
296 } 304 }
297 305
298 ModuleSystem* module_system = context->module_system(); 306 ModuleSystem* module_system = context->module_system();
299 if (!source_map_->Contains(api_name)) { 307 if (!source_map_->Contains(api_name)) {
300 module_system->RegisterNativeHandler( 308 module_system->RegisterNativeHandler(
301 api_name, 309 api_bind_name,
302 std::unique_ptr<NativeHandler>( 310 std::unique_ptr<NativeHandler>(
303 new BindingGeneratingNativeHandler(context, api_name, "binding"))); 311 new BindingGeneratingNativeHandler(context, api_name, "binding")));
304 module_system->SetNativeLazyField(bind_object, bind_name, api_name, 312 module_system->SetNativeLazyField(bind_object, bind_name, api_bind_name,
305 "binding"); 313 "binding");
306 } else { 314 } else {
307 module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); 315 module_system->SetLazyField(bind_object, bind_name, api_name, "binding");
308 } 316 }
309 } 317 }
310 318
311 } // namespace extensions 319 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/js_extension_bindings_system.h ('k') | extensions/renderer/native_extension_bindings_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698