Commit 9b6a633b authored by kalman@chromium.org's avatar kalman@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243959 0039d316-1c4b-4281-b951-d872f2087c98
parent f6b88d9a
......@@ -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) {
......@@ -896,5 +917,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
......@@ -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": {
......
......@@ -104,8 +104,17 @@ bool ChromeV8Context::IsAnyFeatureAvailableToContext(const Feature& api) {
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());
}
......
......@@ -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
......
......@@ -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());
......
......@@ -65,8 +65,12 @@ class ExtensionAPI {
void RegisterDependencyProvider(const std::string& name,
FeatureProvider* provider);
// Returns true if the specified API is available. Returns true if the feature
// and all of its dependencies are available to the specified context.
// Returns true if the API feature |api| and all of its dependencies are
// available in |context|.
//
// Depending on the configuration of |api| (in _api_features.json), either
// |extension| or |url| (or both) may determine its availability, but this is
// up to the configuration of the individual feature.
Feature::Availability IsAvailable(const Feature& api,
const Extension* extension,
Feature::Context context,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment