| 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 "extensions/renderer/dispatcher.h" | 5 #include "extensions/renderer/dispatcher.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 // TODO(kalman): Make the bindings registration have zero overhead then run | 1353 // TODO(kalman): Make the bindings registration have zero overhead then run |
| 1354 // the same code regardless of context type. | 1354 // the same code regardless of context type. |
| 1355 switch (context->context_type()) { | 1355 switch (context->context_type()) { |
| 1356 case Feature::UNSPECIFIED_CONTEXT: | 1356 case Feature::UNSPECIFIED_CONTEXT: |
| 1357 case Feature::WEB_PAGE_CONTEXT: | 1357 case Feature::WEB_PAGE_CONTEXT: |
| 1358 case Feature::BLESSED_WEB_PAGE_CONTEXT: | 1358 case Feature::BLESSED_WEB_PAGE_CONTEXT: |
| 1359 // Hard-code registration of any APIs that are exposed to webpage-like | 1359 // Hard-code registration of any APIs that are exposed to webpage-like |
| 1360 // contexts, because it's too expensive to run the full bindings code. | 1360 // contexts, because it's too expensive to run the full bindings code. |
| 1361 // All of the same permission checks will still apply. | 1361 // All of the same permission checks will still apply. |
| 1362 if (context->GetAvailability("app").is_available()) | 1362 if (context->GetAvailability("app").is_available()) |
| 1363 RegisterBinding("app", context); | 1363 RegisterBinding("app", "app", context); |
| 1364 if (context->GetAvailability("webstore").is_available()) | 1364 if (context->GetAvailability("webstore").is_available()) |
| 1365 RegisterBinding("webstore", context); | 1365 RegisterBinding("webstore", "webstore", context); |
| 1366 if (context->GetAvailability("dashboardPrivate").is_available()) | 1366 if (context->GetAvailability("dashboardPrivate").is_available()) |
| 1367 RegisterBinding("dashboardPrivate", context); | 1367 RegisterBinding("dashboardPrivate", "dashboardPrivate", context); |
| 1368 if (IsRuntimeAvailableToContext(context)) | 1368 if (IsRuntimeAvailableToContext(context)) |
| 1369 RegisterBinding("runtime", context); | 1369 RegisterBinding("runtime", "runtime", context); |
| 1370 UpdateContentCapabilities(context); | 1370 UpdateContentCapabilities(context); |
| 1371 break; | 1371 break; |
| 1372 | 1372 |
| 1373 case Feature::SERVICE_WORKER_CONTEXT: | 1373 case Feature::SERVICE_WORKER_CONTEXT: |
| 1374 DCHECK(ExtensionsClient::Get() | 1374 DCHECK(ExtensionsClient::Get() |
| 1375 ->ExtensionAPIEnabledInExtensionServiceWorkers()); | 1375 ->ExtensionAPIEnabledInExtensionServiceWorkers()); |
| 1376 // Intentional fallthrough. | 1376 // Intentional fallthrough. |
| 1377 case Feature::BLESSED_EXTENSION_CONTEXT: | 1377 case Feature::BLESSED_EXTENSION_CONTEXT: |
| 1378 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 1378 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
| 1379 case Feature::CONTENT_SCRIPT_CONTEXT: | 1379 case Feature::CONTENT_SCRIPT_CONTEXT: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1393 if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr) | 1393 if (api_feature_provider->GetParent(map_entry.second.get()) != nullptr) |
| 1394 continue; | 1394 continue; |
| 1395 | 1395 |
| 1396 // Skip chrome.test if this isn't a test. | 1396 // Skip chrome.test if this isn't a test. |
| 1397 if (map_entry.first == "test" && | 1397 if (map_entry.first == "test" && |
| 1398 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 1398 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1399 ::switches::kTestType)) { | 1399 ::switches::kTestType)) { |
| 1400 continue; | 1400 continue; |
| 1401 } | 1401 } |
| 1402 | 1402 |
| 1403 if (context->IsAnyFeatureAvailableToContext(*map_entry.second)) { | 1403 if (context->IsAnyFeatureAvailableToContext( |
| 1404 *map_entry.second, CheckAliasStatus::NOT_ALLOWED)) { |
| 1405 // Check if the API feature is indeed an alias. If it is, the API |
| 1406 // should use source API bindings as its own. |
| 1407 const std::string& source = map_entry.second->source(); |
| 1404 // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread | 1408 // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread |
| 1405 // safety issue? | 1409 // safety issue? |
| 1406 RegisterBinding(map_entry.first, context); | 1410 RegisterBinding(source.empty() ? map_entry.first : source, |
| 1411 map_entry.first, context); |
| 1407 } | 1412 } |
| 1408 } | 1413 } |
| 1409 break; | 1414 break; |
| 1410 } | 1415 } |
| 1411 } | 1416 } |
| 1412 } | 1417 } |
| 1413 | 1418 |
| 1414 void Dispatcher::RegisterBinding(const std::string& api_name, | 1419 void Dispatcher::RegisterBinding(const std::string& api_name, |
| 1420 const std::string& api_bind_name, |
| 1415 ScriptContext* context) { | 1421 ScriptContext* context) { |
| 1416 std::string bind_name; | 1422 std::string bind_name; |
| 1417 v8::Local<v8::Object> bind_object = | 1423 v8::Local<v8::Object> bind_object = |
| 1418 GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context); | 1424 GetOrCreateBindObjectIfAvailable(api_bind_name, &bind_name, context); |
| 1419 | 1425 |
| 1420 // Empty if the bind object failed to be created, probably because the | 1426 // Empty if the bind object failed to be created, probably because the |
| 1421 // extension overrode chrome with a non-object, e.g. window.chrome = true. | 1427 // extension overrode chrome with a non-object, e.g. window.chrome = true. |
| 1422 if (bind_object.IsEmpty()) | 1428 if (bind_object.IsEmpty()) |
| 1423 return; | 1429 return; |
| 1424 | 1430 |
| 1425 v8::Local<v8::String> v8_bind_name = | 1431 v8::Local<v8::String> v8_bind_name = |
| 1426 v8::String::NewFromUtf8(context->isolate(), bind_name.c_str()); | 1432 v8::String::NewFromUtf8(context->isolate(), bind_name.c_str()); |
| 1427 if (bind_object->HasRealNamedProperty(v8_bind_name)) { | 1433 if (bind_object->HasRealNamedProperty(v8_bind_name)) { |
| 1428 // The bind object may already have the property if the API has been | 1434 // The bind object may already have the property if the API has been |
| 1429 // registered before (or if the extension has put something there already, | 1435 // registered before (or if the extension has put something there already, |
| 1430 // but, whatevs). | 1436 // but, whatevs). |
| 1431 // | 1437 // |
| 1432 // In the former case, we need to re-register the bindings for the APIs | 1438 // In the former case, we need to re-register the bindings for the APIs |
| 1433 // which the extension now has permissions for (if any), but not touch any | 1439 // which the extension now has permissions for (if any), but not touch any |
| 1434 // others so that we don't destroy state such as event listeners. | 1440 // others so that we don't destroy state such as event listeners. |
| 1435 // | 1441 // |
| 1436 // TODO(kalman): Only register available APIs to make this all moot. | 1442 // TODO(kalman): Only register available APIs to make this all moot. |
| 1437 if (bind_object->HasRealNamedCallbackProperty(v8_bind_name)) | 1443 if (bind_object->HasRealNamedCallbackProperty(v8_bind_name)) |
| 1438 return; // lazy binding still there, nothing to do | 1444 return; // lazy binding still there, nothing to do |
| 1439 if (bind_object->Get(v8_bind_name)->IsObject()) | 1445 if (bind_object->Get(v8_bind_name)->IsObject()) |
| 1440 return; // binding has already been fully installed | 1446 return; // binding has already been fully installed |
| 1441 } | 1447 } |
| 1442 | 1448 |
| 1443 ModuleSystem* module_system = context->module_system(); | 1449 ModuleSystem* module_system = context->module_system(); |
| 1444 if (!source_map_.Contains(api_name)) { | 1450 if (!source_map_.Contains(api_name)) { |
| 1445 module_system->RegisterNativeHandler( | 1451 module_system->RegisterNativeHandler( |
| 1446 api_name, | 1452 api_bind_name, |
| 1447 std::unique_ptr<NativeHandler>( | 1453 std::unique_ptr<NativeHandler>( |
| 1448 new BindingGeneratingNativeHandler(context, api_name, "binding"))); | 1454 new BindingGeneratingNativeHandler(context, api_name, "binding"))); |
| 1449 module_system->SetNativeLazyField( | 1455 module_system->SetNativeLazyField(bind_object, bind_name, api_bind_name, |
| 1450 bind_object, bind_name, api_name, "binding"); | 1456 "binding"); |
| 1451 } else { | 1457 } else { |
| 1452 module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); | 1458 module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); |
| 1453 } | 1459 } |
| 1454 } | 1460 } |
| 1455 | 1461 |
| 1456 // NOTE: please use the naming convention "foo_natives" for these. | 1462 // NOTE: please use the naming convention "foo_natives" for these. |
| 1457 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, | 1463 void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
| 1458 ScriptContext* context, | 1464 ScriptContext* context, |
| 1459 RequestSender* request_sender, | 1465 RequestSender* request_sender, |
| 1460 V8SchemaRegistry* v8_schema_registry) { | 1466 V8SchemaRegistry* v8_schema_registry) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 // If app.window is available and app is not, delete app and install | 1582 // If app.window is available and app is not, delete app and install |
| 1577 // app.window on a new object so app does not have to be loaded. | 1583 // app.window on a new object so app does not have to be loaded. |
| 1578 const FeatureProvider* api_feature_provider = | 1584 const FeatureProvider* api_feature_provider = |
| 1579 FeatureProvider::GetAPIFeatures(); | 1585 FeatureProvider::GetAPIFeatures(); |
| 1580 std::string ancestor_name; | 1586 std::string ancestor_name; |
| 1581 bool only_ancestor_available = false; | 1587 bool only_ancestor_available = false; |
| 1582 | 1588 |
| 1583 for (size_t i = 0; i < split.size() - 1; ++i) { | 1589 for (size_t i = 0; i < split.size() - 1; ++i) { |
| 1584 ancestor_name += (i ? "." : "") + split[i]; | 1590 ancestor_name += (i ? "." : "") + split[i]; |
| 1585 if (api_feature_provider->GetFeature(ancestor_name) && | 1591 if (api_feature_provider->GetFeature(ancestor_name) && |
| 1586 context->GetAvailability(ancestor_name).is_available() && | 1592 context->GetAvailability(ancestor_name, CheckAliasStatus::NOT_ALLOWED) |
| 1587 !context->GetAvailability(api_name).is_available()) { | 1593 .is_available() && |
| 1594 !context->GetAvailability(api_name, CheckAliasStatus::NOT_ALLOWED) |
| 1595 .is_available()) { |
| 1588 only_ancestor_available = true; | 1596 only_ancestor_available = true; |
| 1589 break; | 1597 break; |
| 1590 } | 1598 } |
| 1591 | 1599 |
| 1592 if (bind_object.IsEmpty()) { | 1600 if (bind_object.IsEmpty()) { |
| 1593 bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); | 1601 bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); |
| 1594 if (bind_object.IsEmpty()) | 1602 if (bind_object.IsEmpty()) |
| 1595 return v8::Local<v8::Object>(); | 1603 return v8::Local<v8::Object>(); |
| 1596 } | 1604 } |
| 1597 bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); | 1605 bind_object = GetOrCreateObject(bind_object, split[i], context->isolate()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 // The "guestViewDeny" module must always be loaded last. It registers | 1658 // The "guestViewDeny" module must always be loaded last. It registers |
| 1651 // error-providing custom elements for the GuestView types that are not | 1659 // error-providing custom elements for the GuestView types that are not |
| 1652 // available, and thus all of those types must have been checked and loaded | 1660 // available, and thus all of those types must have been checked and loaded |
| 1653 // (or not loaded) beforehand. | 1661 // (or not loaded) beforehand. |
| 1654 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { | 1662 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { |
| 1655 module_system->Require("guestViewDeny"); | 1663 module_system->Require("guestViewDeny"); |
| 1656 } | 1664 } |
| 1657 } | 1665 } |
| 1658 | 1666 |
| 1659 } // namespace extensions | 1667 } // namespace extensions |
| OLD | NEW |