diff options
author | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 16:53:45 +0000 |
---|---|---|
committer | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-29 16:53:45 +0000 |
commit | 1dbc10e1ded96c967fa804dd040d1425f6bda127 (patch) | |
tree | 59c48915d88cc088e65d31a71f5eab57dd164913 | |
parent | 7415e329ce844348328e54a99d36f31dc72d890c (diff) | |
download | chromium_src-1dbc10e1ded96c967fa804dd040d1425f6bda127.zip chromium_src-1dbc10e1ded96c967fa804dd040d1425f6bda127.tar.gz chromium_src-1dbc10e1ded96c967fa804dd040d1425f6bda127.tar.bz2 |
Merge 243959 "Register bindings for blessed web contexts (aka ho..."
> Register bindings for blessed web contexts (aka hosted app contexts) by hand
> rather than automatically; this allows them to be treated like web contexts
> rather than extension contexts, which allows the more complex bindings rules
> for making the messaging APIs (chrome.runtime.connect/sendMessage) available.
> Make them available.
>
> BUG=326250
> R=koz@chromium.org
>
> Review URL: https://codereview.chromium.org/114803007
TBR=kalman@chromium.org
Review URL: https://codereview.chromium.org/135393006
git-svn-id: svn://svn.chromium.org/chrome/branches/1750/src@247703 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_messages_apitest.cc | 41 | ||||
-rw-r--r-- | chrome/common/extensions/api/_api_features.json | 3 | ||||
-rw-r--r-- | chrome/renderer/extensions/chrome_v8_context.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/extensions/dispatcher.cc | 4 | ||||
-rw-r--r-- | chrome/renderer/extensions/runtime_custom_bindings.cc | 8 |
5 files changed, 62 insertions, 5 deletions
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc index 5853612..c1505cf 100644 --- a/chrome/browser/extensions/extension_messages_apitest.cc +++ b/chrome/browser/extensions/extension_messages_apitest.cc @@ -226,7 +226,8 @@ class ExternallyConnectableMessagingTest : public ExtensionApiTest { "onMessage", "onMessageExternal", "onRestartRequired", - "id", + // Note: no "id" here because this test method is used for hosted apps, + // which do have access to runtime.id. }; // Turn the array into a JS array, which effectively gets eval()ed. @@ -313,6 +314,25 @@ class ExternallyConnectableMessagingTest : public ExtensionApiTest { connectable_with_tls_channel_id_manifest()); } + const Extension* LoadChromiumHostedApp() { + const Extension* hosted_app = + LoadExtensionIntoDir(&hosted_app_dir_, base::StringPrintf( + "{" + " \"name\": \"chromium_hosted_app\"," + " \"version\": \"1.0\"," + " \"manifest_version\": 2," + " \"app\": {" + " \"urls\": [\"%s\"]," + " \"launch\": {" + " \"web_url\": \"%s\"" + " }\n" + " }\n" + "}", chromium_org_url().spec().c_str(), + chromium_org_url().spec().c_str())); + CHECK(hosted_app); + return hosted_app; + } + void InitializeTestServer() { base::FilePath test_data; EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); @@ -392,6 +412,7 @@ class ExternallyConnectableMessagingTest : public ExtensionApiTest { TestExtensionDir web_connectable_dir_; TestExtensionDir not_connectable_dir_; TestExtensionDir tls_channel_id_connectable_dir_; + TestExtensionDir hosted_app_dir_; }; IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) { @@ -903,5 +924,23 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingUserGesture) { "});", receiver->id().c_str()))); } +// Tests that a hosted app on a connectable site doesn't interfere with the +// connectability of that site. +IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, HostedAppOnWebsite) { + InitializeTestServer(); + + LoadChromiumHostedApp(); + + // The presence of the hosted app shouldn't give the ability to send messages. + ui_test_utils::NavigateToURL(browser(), chromium_org_url()); + EXPECT_EQ(NAMESPACE_NOT_DEFINED, CanConnectAndSendMessages("")); + EXPECT_FALSE(AreAnyNonWebApisDefined()); + + // Once a connectable extension is installed, it should. + const Extension* extension = LoadChromiumConnectableExtension(); + EXPECT_EQ(OK, CanConnectAndSendMessages(extension->id())); + EXPECT_FALSE(AreAnyNonWebApisDefined()); +} + } // namespace }; // namespace extensions diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index eb87ca2..70aa897 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -4,6 +4,9 @@ // See c/c/e/features/* to understand this file, in particular feature.h, // simple_feature.h, and base_feature_provider.h. +// +// Note that specifying "web_page", "blessed_web_page", or "all" as a context +// type will require manually updating chrome/renderer/resources/dispatcher.cc. { "activityLogPrivate": { diff --git a/chrome/renderer/extensions/chrome_v8_context.cc b/chrome/renderer/extensions/chrome_v8_context.cc index e6e8d18..66d14c0 100644 --- a/chrome/renderer/extensions/chrome_v8_context.cc +++ b/chrome/renderer/extensions/chrome_v8_context.cc @@ -106,8 +106,17 @@ bool ChromeV8Context::IsAnyFeatureAvailableToContext( Feature::Availability ChromeV8Context::GetAvailability( const std::string& api_name) { + // Hack: Hosted apps should have the availability of messaging APIs based on + // the URL of the page (which might have access depending on some extension + // with externally_connectable), not whether the app has access to messaging + // (which it won't). + const Extension* extension = extension_.get(); + if (extension && extension->is_hosted_app() && + (api_name == "runtime.connect" || api_name == "runtime.sendMessage")) { + extension = NULL; + } return ExtensionAPI::GetSharedInstance()->IsAvailable(api_name, - extension_.get(), + extension, context_type_, GetURL()); } diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc index bc3aad0..86f3283 100644 --- a/chrome/renderer/extensions/dispatcher.cc +++ b/chrome/renderer/extensions/dispatcher.cc @@ -707,7 +707,8 @@ void Dispatcher::AddOrRemoveBindingsForContext(ChromeV8Context* context) { // the same code regardless of context type. switch (context->context_type()) { case Feature::UNSPECIFIED_CONTEXT: - case Feature::WEB_PAGE_CONTEXT: { + case Feature::WEB_PAGE_CONTEXT: + case Feature::BLESSED_WEB_PAGE_CONTEXT: { // Web page context; it's too expensive to run the full bindings code. // Hard-code that the app and webstore APIs are available... RegisterBinding("app", context); @@ -732,7 +733,6 @@ void Dispatcher::AddOrRemoveBindingsForContext(ChromeV8Context* context) { } case Feature::BLESSED_EXTENSION_CONTEXT: - case Feature::BLESSED_WEB_PAGE_CONTEXT: case Feature::UNBLESSED_EXTENSION_CONTEXT: case Feature::CONTENT_SCRIPT_CONTEXT: { // Extension context; iterate through all the APIs and bind the available diff --git a/chrome/renderer/extensions/runtime_custom_bindings.cc b/chrome/renderer/extensions/runtime_custom_bindings.cc index e2030d1..0db2a40 100644 --- a/chrome/renderer/extensions/runtime_custom_bindings.cc +++ b/chrome/renderer/extensions/runtime_custom_bindings.cc @@ -58,7 +58,13 @@ void RuntimeCustomBindings::OpenChannelToExtension( CHECK(args[0]->IsString() && args[1]->IsString() && args[2]->IsBoolean()); ExtensionMsg_ExternalConnectionInfo info; - info.source_id = context()->GetExtensionID(); + + // For messaging APIs, hosted apps should be considered a web page so hide + // its extension ID. + const Extension* extension = context()->extension(); + if (extension && !extension->is_hosted_app()) + info.source_id = extension->id(); + info.target_id = *v8::String::Utf8Value(args[0]->ToString()); info.source_url = context()->GetURL(); std::string channel_name = *v8::String::Utf8Value(args[1]->ToString()); |