Give names to all utility processes.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_messages_apitest.cc
blob19c5b20fee0bace8257e088834696c253a0ae4d7
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/base64.h"
6 #include "base/files/file_path.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/values.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
18 #include "chrome/browser/extensions/extension_apitest.h"
19 #include "chrome/browser/extensions/test_extension_dir.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/test/browser_test_utils.h"
30 #include "extensions/browser/event_router.h"
31 #include "extensions/browser/extension_prefs.h"
32 #include "extensions/browser/extension_system.h"
33 #include "extensions/common/api/runtime.h"
34 #include "extensions/common/extension_builder.h"
35 #include "extensions/common/value_builder.h"
36 #include "net/cert/asn1_util.h"
37 #include "net/cert/jwk_serializer.h"
38 #include "net/dns/mock_host_resolver.h"
39 #include "net/ssl/channel_id_service.h"
40 #include "net/test/embedded_test_server/embedded_test_server.h"
41 #include "net/url_request/url_request_context.h"
42 #include "net/url_request/url_request_context_getter.h"
43 #include "url/gurl.h"
45 namespace extensions {
46 namespace {
48 class MessageSender : public content::NotificationObserver {
49 public:
50 MessageSender() {
51 registrar_.Add(this,
52 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD,
53 content::NotificationService::AllSources());
56 private:
57 static scoped_ptr<base::ListValue> BuildEventArguments(
58 const bool last_message,
59 const std::string& data) {
60 base::DictionaryValue* event = new base::DictionaryValue();
61 event->SetBoolean("lastMessage", last_message);
62 event->SetString("data", data);
63 scoped_ptr<base::ListValue> arguments(new base::ListValue());
64 arguments->Append(event);
65 return arguments.Pass();
68 static scoped_ptr<Event> BuildEvent(scoped_ptr<base::ListValue> event_args,
69 Profile* profile,
70 GURL event_url) {
71 scoped_ptr<Event> event(new Event("test.onMessage", event_args.Pass()));
72 event->restrict_to_browser_context = profile;
73 event->event_url = event_url;
74 return event.Pass();
77 void Observe(int type,
78 const content::NotificationSource& source,
79 const content::NotificationDetails& details) override {
80 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD,
81 type);
82 EventRouter* event_router =
83 EventRouter::Get(content::Source<Profile>(source).ptr());
85 // Sends four messages to the extension. All but the third message sent
86 // from the origin http://b.com/ are supposed to arrive.
87 event_router->BroadcastEvent(BuildEvent(
88 BuildEventArguments(false, "no restriction"),
89 content::Source<Profile>(source).ptr(),
90 GURL()));
91 event_router->BroadcastEvent(BuildEvent(
92 BuildEventArguments(false, "http://a.com/"),
93 content::Source<Profile>(source).ptr(),
94 GURL("http://a.com/")));
95 event_router->BroadcastEvent(BuildEvent(
96 BuildEventArguments(false, "http://b.com/"),
97 content::Source<Profile>(source).ptr(),
98 GURL("http://b.com/")));
99 event_router->BroadcastEvent(BuildEvent(
100 BuildEventArguments(true, "last message"),
101 content::Source<Profile>(source).ptr(),
102 GURL()));
105 content::NotificationRegistrar registrar_;
108 // Tests that message passing between extensions and content scripts works.
109 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
110 ASSERT_TRUE(StartEmbeddedTestServer());
111 ASSERT_TRUE(RunExtensionTest("messaging/connect")) << message_;
114 // Tests that message passing from one extension to another works.
115 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) {
116 ASSERT_TRUE(LoadExtension(
117 test_data_dir_.AppendASCII("..").AppendASCII("good")
118 .AppendASCII("Extensions")
119 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
120 .AppendASCII("1.0")));
122 ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
125 // Tests that messages with event_urls are only passed to extensions with
126 // appropriate permissions.
127 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) {
128 MessageSender sender;
129 ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_;
132 // Tests connecting from a panel to its extension.
133 class PanelMessagingTest : public ExtensionApiTest {
134 void SetUpCommandLine(base::CommandLine* command_line) override {
135 ExtensionApiTest::SetUpCommandLine(command_line);
136 command_line->AppendSwitch(switches::kEnablePanels);
140 IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) {
141 ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_;
144 // XXX(kalman): All web messaging tests disabled on windows due to extreme
145 // flakiness. See http://crbug.com/350517.
146 #if !defined(OS_WIN)
148 // Tests externally_connectable between a web page and an extension.
150 // TODO(kalman): Test between extensions. This is already tested in this file,
151 // but not with externally_connectable set in the manifest.
153 // TODO(kalman): Test with host permissions.
154 class ExternallyConnectableMessagingTest : public ExtensionApiTest {
155 protected:
156 // Result codes from the test. These must match up with |results| in
157 // c/t/d/extensions/api_test/externally_connectable/assertions.json.
158 enum Result {
159 OK = 0,
160 NAMESPACE_NOT_DEFINED = 1,
161 FUNCTION_NOT_DEFINED = 2,
162 COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3,
163 OTHER_ERROR = 4,
164 INCORRECT_RESPONSE_SENDER = 5,
165 INCORRECT_RESPONSE_MESSAGE = 6,
168 bool AppendIframe(const GURL& src) {
169 bool result;
170 CHECK(content::ExecuteScriptAndExtractBool(
171 browser()->tab_strip_model()->GetActiveWebContents(),
172 "actions.appendIframe('" + src.spec() + "');", &result));
173 return result;
176 Result CanConnectAndSendMessagesToMainFrame(const Extension* extension,
177 const char* message = NULL) {
178 return CanConnectAndSendMessagesToFrame(
179 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
180 extension,
181 message);
184 Result CanConnectAndSendMessagesToIFrame(const Extension* extension,
185 const char* message = NULL) {
186 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
187 browser()->tab_strip_model()->GetActiveWebContents(),
188 base::Bind(&content::FrameIsChildOfMainFrame));
189 return CanConnectAndSendMessagesToFrame(frame, extension, message);
192 Result CanConnectAndSendMessagesToFrame(content::RenderFrameHost* frame,
193 const Extension* extension,
194 const char* message) {
195 int result;
196 std::string command = base::StringPrintf(
197 "assertions.canConnectAndSendMessages('%s', %s, %s)",
198 extension->id().c_str(),
199 extension->is_platform_app() ? "true" : "false",
200 message ? base::StringPrintf("'%s'", message).c_str() : "undefined");
201 CHECK(content::ExecuteScriptAndExtractInt(frame, command, &result));
202 return static_cast<Result>(result);
205 testing::AssertionResult AreAnyNonWebApisDefinedForMainFrame() {
206 return AreAnyNonWebApisDefinedForFrame(
207 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
210 testing::AssertionResult AreAnyNonWebApisDefinedForIFrame() {
211 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
212 browser()->tab_strip_model()->GetActiveWebContents(),
213 base::Bind(&content::FrameIsChildOfMainFrame));
214 return AreAnyNonWebApisDefinedForFrame(frame);
217 testing::AssertionResult AreAnyNonWebApisDefinedForFrame(
218 content::RenderFrameHost* frame) {
219 // All runtime API methods are non-web except for sendRequest and connect.
220 const char* const non_messaging_apis[] = {
221 "getBackgroundPage",
222 "getManifest",
223 "getURL",
224 "reload",
225 "requestUpdateCheck",
226 "restart",
227 "connectNative",
228 "sendNativeMessage",
229 "onStartup",
230 "onInstalled",
231 "onSuspend",
232 "onSuspendCanceled",
233 "onUpdateAvailable",
234 "onBrowserUpdateAvailable",
235 "onConnect",
236 "onConnectExternal",
237 "onMessage",
238 "onMessageExternal",
239 "onRestartRequired",
240 // Note: no "id" here because this test method is used for hosted apps,
241 // which do have access to runtime.id.
244 // Turn the array into a JS array, which effectively gets eval()ed.
245 std::string as_js_array;
246 for (size_t i = 0; i < arraysize(non_messaging_apis); ++i) {
247 as_js_array += as_js_array.empty() ? "[" : ",";
248 as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]);
250 as_js_array += "]";
252 bool any_defined;
253 CHECK(content::ExecuteScriptAndExtractBool(
254 frame,
255 "assertions.areAnyRuntimePropertiesDefined(" + as_js_array + ")",
256 &any_defined));
257 return any_defined ?
258 testing::AssertionSuccess() : testing::AssertionFailure();
261 std::string GetTlsChannelIdFromPortConnect(const Extension* extension,
262 bool include_tls_channel_id,
263 const char* message = NULL) {
264 return GetTlsChannelIdFromAssertion("getTlsChannelIdFromPortConnect",
265 extension,
266 include_tls_channel_id,
267 message);
270 std::string GetTlsChannelIdFromSendMessage(const Extension* extension,
271 bool include_tls_channel_id,
272 const char* message = NULL) {
273 return GetTlsChannelIdFromAssertion("getTlsChannelIdFromSendMessage",
274 extension,
275 include_tls_channel_id,
276 message);
279 GURL GetURLForPath(const std::string& host, const std::string& path) {
280 std::string port = base::IntToString(embedded_test_server()->port());
281 GURL::Replacements replacements;
282 replacements.SetHostStr(host);
283 replacements.SetPortStr(port);
284 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements);
287 GURL chromium_org_url() {
288 return GetURLForPath("www.chromium.org", "/chromium.org.html");
291 GURL google_com_url() {
292 return GetURLForPath("www.google.com", "/google.com.html");
295 scoped_refptr<const Extension> LoadChromiumConnectableExtension() {
296 scoped_refptr<const Extension> extension =
297 LoadExtensionIntoDir(&web_connectable_dir_,
298 base::StringPrintf(
300 " \"name\": \"chromium_connectable\","
301 " %s,"
302 " \"externally_connectable\": {"
303 " \"matches\": [\"*://*.chromium.org:*/*\"]"
304 " }"
305 "}",
306 common_manifest()));
307 CHECK(extension.get());
308 return extension;
311 scoped_refptr<const Extension> LoadChromiumConnectableApp(
312 bool with_event_handlers = true) {
313 scoped_refptr<const Extension> extension =
314 LoadExtensionIntoDir(&web_connectable_dir_,
316 " \"app\": {"
317 " \"background\": {"
318 " \"scripts\": [\"background.js\"]"
319 " }"
320 " },"
321 " \"externally_connectable\": {"
322 " \"matches\": [\"*://*.chromium.org:*/*\"]"
323 " },"
324 " \"manifest_version\": 2,"
325 " \"name\": \"app_connectable\","
326 " \"version\": \"1.0\""
327 "}",
328 with_event_handlers);
329 CHECK(extension.get());
330 return extension;
333 scoped_refptr<const Extension> LoadNotConnectableExtension() {
334 scoped_refptr<const Extension> extension =
335 LoadExtensionIntoDir(&not_connectable_dir_,
336 base::StringPrintf(
338 " \"name\": \"not_connectable\","
339 " %s"
340 "}",
341 common_manifest()));
342 CHECK(extension.get());
343 return extension;
346 scoped_refptr<const Extension>
347 LoadChromiumConnectableExtensionWithTlsChannelId() {
348 return LoadExtensionIntoDir(&tls_channel_id_connectable_dir_,
349 connectable_with_tls_channel_id_manifest());
352 scoped_refptr<const Extension> LoadChromiumHostedApp() {
353 scoped_refptr<const Extension> hosted_app =
354 LoadExtensionIntoDir(&hosted_app_dir_,
355 base::StringPrintf(
357 " \"name\": \"chromium_hosted_app\","
358 " \"version\": \"1.0\","
359 " \"manifest_version\": 2,"
360 " \"app\": {"
361 " \"urls\": [\"%s\"],"
362 " \"launch\": {"
363 " \"web_url\": \"%s\""
364 " }\n"
365 " }\n"
366 "}",
367 chromium_org_url().spec().c_str(),
368 chromium_org_url().spec().c_str()));
369 CHECK(hosted_app.get());
370 return hosted_app;
373 void InitializeTestServer() {
374 base::FilePath test_data;
375 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
376 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII(
377 "extensions/api_test/messaging/externally_connectable/sites"));
378 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
379 host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
382 const char* close_background_message() {
383 return "closeBackgroundPage";
386 private:
387 scoped_refptr<const Extension> LoadExtensionIntoDir(
388 TestExtensionDir* dir,
389 const std::string& manifest,
390 bool with_event_handlers = true) {
391 dir->WriteManifest(manifest);
392 if (with_event_handlers) {
393 dir->WriteFile(
394 FILE_PATH_LITERAL("background.js"),
395 base::StringPrintf(
396 "function maybeClose(message) {\n"
397 " if (message.indexOf('%s') >= 0)\n"
398 " window.setTimeout(function() { window.close() }, 0);\n"
399 "}\n"
400 "chrome.runtime.onMessageExternal.addListener(\n"
401 " function(message, sender, reply) {\n"
402 " reply({ message: message, sender: sender });\n"
403 " maybeClose(message);\n"
404 "});\n"
405 "chrome.runtime.onConnectExternal.addListener(function(port) {\n"
406 " port.onMessage.addListener(function(message) {\n"
407 " port.postMessage({ message: message, sender: port.sender "
408 "});\n"
409 " maybeClose(message);\n"
410 " });\n"
411 "});\n",
412 close_background_message()));
413 } else {
414 dir->WriteFile(FILE_PATH_LITERAL("background.js"), "");
416 return LoadExtension(dir->unpacked_path());
419 const char* common_manifest() {
420 return "\"version\": \"1.0\","
421 "\"background\": {"
422 " \"scripts\": [\"background.js\"],"
423 " \"persistent\": false"
424 "},"
425 "\"manifest_version\": 2";
428 std::string connectable_with_tls_channel_id_manifest() {
429 return base::StringPrintf(
431 " \"name\": \"chromium_connectable_with_tls_channel_id\","
432 " %s,"
433 " \"externally_connectable\": {"
434 " \"matches\": [\"*://*.chromium.org:*/*\"],"
435 " \"accepts_tls_channel_id\": true"
436 " }"
437 "}",
438 common_manifest());
441 std::string GetTlsChannelIdFromAssertion(const char* method,
442 const Extension* extension,
443 bool include_tls_channel_id,
444 const char* message) {
445 std::string result;
446 std::string args = "'" + extension->id() + "', ";
447 args += include_tls_channel_id ? "true" : "false";
448 if (message)
449 args += std::string(", '") + message + "'";
450 CHECK(content::ExecuteScriptAndExtractString(
451 browser()->tab_strip_model()->GetActiveWebContents(),
452 base::StringPrintf("assertions.%s(%s)", method, args.c_str()),
453 &result));
454 return result;
457 TestExtensionDir web_connectable_dir_;
458 TestExtensionDir not_connectable_dir_;
459 TestExtensionDir tls_channel_id_connectable_dir_;
460 TestExtensionDir hosted_app_dir_;
463 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) {
464 InitializeTestServer();
466 scoped_refptr<const Extension> extension =
467 ExtensionBuilder()
468 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
469 .SetManifest(DictionaryBuilder()
470 .Set("name", "Fake extension")
471 .Set("version", "1")
472 .Set("manifest_version", 2))
473 .Build();
475 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
476 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
477 CanConnectAndSendMessagesToMainFrame(extension.get()));
478 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
480 ui_test_utils::NavigateToURL(browser(), google_com_url());
481 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
482 CanConnectAndSendMessagesToMainFrame(extension.get()));
483 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
486 // Tests two extensions on the same sites: one web connectable, one not.
487 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
488 WebConnectableAndNotConnectable) {
489 InitializeTestServer();
491 // Install the web connectable extension. chromium.org can connect to it,
492 // google.com can't.
493 scoped_refptr<const Extension> chromium_connectable =
494 LoadChromiumConnectableExtension();
496 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
497 EXPECT_EQ(OK,
498 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
499 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
501 ui_test_utils::NavigateToURL(browser(), google_com_url());
502 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
503 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
504 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
506 // Install the non-connectable extension. Nothing can connect to it.
507 scoped_refptr<const Extension> not_connectable =
508 LoadNotConnectableExtension();
510 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
511 // Namespace will be defined here because |chromium_connectable| can connect
512 // to it - so this will be the "cannot establish connection" error.
513 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
514 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
515 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
517 ui_test_utils::NavigateToURL(browser(), google_com_url());
518 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
519 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
520 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
523 // See http://crbug.com/297866
524 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
525 DISABLED_BackgroundPageClosesOnMessageReceipt) {
526 InitializeTestServer();
528 // Install the web connectable extension.
529 scoped_refptr<const Extension> chromium_connectable =
530 LoadChromiumConnectableExtension();
532 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
533 // If the background page closes after receipt of the message, it will still
534 // reply to this message...
535 EXPECT_EQ(OK,
536 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get(),
537 close_background_message()));
538 // and be re-opened by receipt of a subsequent message.
539 EXPECT_EQ(OK,
540 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
543 // Tests a web connectable extension that doesn't receive TLS channel id.
544 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
545 WebConnectableWithoutTlsChannelId) {
546 InitializeTestServer();
548 // Install the web connectable extension. chromium.org can connect to it,
549 // google.com can't.
550 scoped_refptr<const Extension> chromium_connectable =
551 LoadChromiumConnectableExtension();
552 ASSERT_TRUE(chromium_connectable.get());
554 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
555 // The web connectable extension doesn't request the TLS channel ID, so it
556 // doesn't get it, whether or not the page asks for it.
557 EXPECT_EQ(std::string(),
558 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
559 EXPECT_EQ(std::string(),
560 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
561 EXPECT_EQ(std::string(),
562 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
563 EXPECT_EQ(std::string(),
564 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
567 // Tests a web connectable extension that receives TLS channel id with a site
568 // that can't connect to it.
569 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
570 WebConnectableWithTlsChannelIdWithNonMatchingSite) {
571 InitializeTestServer();
573 scoped_refptr<const Extension> chromium_connectable =
574 LoadChromiumConnectableExtensionWithTlsChannelId();
575 ASSERT_TRUE(chromium_connectable.get());
577 ui_test_utils::NavigateToURL(browser(), google_com_url());
578 // The extension requests the TLS channel ID, but it doesn't get it for a
579 // site that can't connect to it, regardless of whether the page asks for it.
580 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
581 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
582 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
583 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
584 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
585 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
586 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
587 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
590 // Tests a web connectable extension that receives TLS channel id on a site
591 // that can connect to it, but with no TLS channel ID having been generated.
592 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
593 WebConnectableWithTlsChannelIdWithEmptyTlsChannelId) {
594 InitializeTestServer();
596 scoped_refptr<const Extension> chromium_connectable =
597 LoadChromiumConnectableExtensionWithTlsChannelId();
598 ASSERT_TRUE(chromium_connectable.get());
600 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
602 // Since the extension requests the TLS channel ID, it gets it for a site that
603 // can connect to it, but only if the page also asks to include it.
604 EXPECT_EQ(std::string(),
605 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
606 EXPECT_EQ(std::string(),
607 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
608 // If the page does ask for it, it isn't empty.
609 std::string tls_channel_id =
610 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
611 // Because the TLS channel ID has never been generated for this domain,
612 // no TLS channel ID is reported.
613 EXPECT_EQ(std::string(), tls_channel_id);
616 // Flaky on Linux and Windows. http://crbug.com/315264
617 // Tests a web connectable extension that receives TLS channel id, but
618 // immediately closes its background page upon receipt of a message.
619 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
620 DISABLED_WebConnectableWithEmptyTlsChannelIdAndClosedBackgroundPage) {
621 InitializeTestServer();
623 scoped_refptr<const Extension> chromium_connectable =
624 LoadChromiumConnectableExtensionWithTlsChannelId();
626 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
627 // If the page does ask for it, it isn't empty, even if the background page
628 // closes upon receipt of the connect.
629 std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
630 chromium_connectable.get(), true, close_background_message());
631 // Because the TLS channel ID has never been generated for this domain,
632 // no TLS channel ID is reported.
633 EXPECT_EQ(std::string(), tls_channel_id);
634 // A subsequent connect will still succeed, even if the background page was
635 // previously closed.
636 tls_channel_id =
637 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
638 // And the empty value is still retrieved.
639 EXPECT_EQ(std::string(), tls_channel_id);
642 // Tests that enabling and disabling an extension makes the runtime bindings
643 // appear and disappear.
645 // TODO(kalman): Test with multiple extensions that can be accessed by the same
646 // host.
647 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
648 EnablingAndDisabling) {
649 InitializeTestServer();
651 scoped_refptr<const Extension> chromium_connectable =
652 LoadChromiumConnectableExtension();
653 scoped_refptr<const Extension> not_connectable =
654 LoadNotConnectableExtension();
656 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
657 EXPECT_EQ(OK,
658 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
659 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
660 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
662 DisableExtension(chromium_connectable->id());
663 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
664 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
666 EnableExtension(chromium_connectable->id());
667 EXPECT_EQ(OK,
668 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
669 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
670 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
673 // Tests connection from incognito tabs when the user denies the connection
674 // request. Spanning mode only. A separate test for apps and extensions.
676 // TODO(kalman): ensure that we exercise split vs spanning incognito logic
677 // somewhere. This is a test that should be shared with the content script logic
678 // so it's not really our specific concern for web connectable.
680 // TODO(kalman): test messages from incognito extensions too.
681 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
682 FromIncognitoDenyApp) {
683 InitializeTestServer();
685 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
686 ASSERT_TRUE(app->is_platform_app());
688 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
689 profile()->GetOffTheRecordProfile(),
690 chromium_org_url());
691 content::RenderFrameHost* incognito_frame = incognito_browser->
692 tab_strip_model()->GetActiveWebContents()->GetMainFrame();
695 IncognitoConnectability::ScopedAlertTracker alert_tracker(
696 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
698 // No connection because incognito-enabled hasn't been set for the app, and
699 // the user denied our interactive request.
700 EXPECT_EQ(
701 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
702 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
703 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
705 // Try again. User has already denied so alert not shown.
706 EXPECT_EQ(
707 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
708 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
709 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
712 // It's not possible to allow an app in incognito.
713 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
714 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
715 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
718 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
719 FromIncognitoDenyExtension) {
720 InitializeTestServer();
722 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
724 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
725 profile()->GetOffTheRecordProfile(), chromium_org_url());
726 content::RenderFrameHost* incognito_frame =
727 incognito_browser->tab_strip_model()
728 ->GetActiveWebContents()
729 ->GetMainFrame();
732 IncognitoConnectability::ScopedAlertTracker alert_tracker(
733 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
735 // The alert doesn't show for extensions.
736 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
737 CanConnectAndSendMessagesToFrame(
738 incognito_frame, extension.get(), NULL));
739 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
742 // Allowing the extension in incognito mode will bypass the deny.
743 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
744 EXPECT_EQ(
746 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
749 // Tests connection from incognito tabs when the extension doesn't have an event
750 // handler for the connection event.
751 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
752 FromIncognitoNoEventHandlerInApp) {
753 InitializeTestServer();
755 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false);
756 ASSERT_TRUE(app->is_platform_app());
758 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
759 profile()->GetOffTheRecordProfile(), chromium_org_url());
760 content::RenderFrameHost* incognito_frame =
761 incognito_browser->tab_strip_model()
762 ->GetActiveWebContents()
763 ->GetMainFrame();
766 IncognitoConnectability::ScopedAlertTracker alert_tracker(
767 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
769 // No connection because incognito-enabled hasn't been set for the app, and
770 // the app hasn't installed event handlers.
771 EXPECT_EQ(
772 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
773 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
774 // No dialog should have been shown.
775 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
779 // Tests connection from incognito tabs when the user accepts the connection
780 // request. Spanning mode only. Separate tests for apps and extensions.
782 // TODO(kalman): see comment above about split mode.
783 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
784 FromIncognitoAllowApp) {
785 InitializeTestServer();
787 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
788 ASSERT_TRUE(app->is_platform_app());
790 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
791 profile()->GetOffTheRecordProfile(),
792 chromium_org_url());
793 content::RenderFrameHost* incognito_frame = incognito_browser->
794 tab_strip_model()->GetActiveWebContents()->GetMainFrame();
797 IncognitoConnectability::ScopedAlertTracker alert_tracker(
798 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
800 // Connection allowed even with incognito disabled, because the user
801 // accepted the interactive request.
802 EXPECT_EQ(
803 OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
804 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
806 // Try again. User has already allowed.
807 EXPECT_EQ(
808 OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
809 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
812 // Apps can't be allowed in incognito mode, but it's moot because it's
813 // already allowed.
814 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
815 EXPECT_EQ(OK,
816 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
819 // Tests connection from incognito tabs when there are multiple tabs open to the
820 // same origin. The user should only need to accept the connection request once.
821 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
822 FromIncognitoPromptApp) {
823 InitializeTestServer();
825 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
826 ASSERT_TRUE(app->is_platform_app());
828 // Open an incognito browser with two tabs displaying "chromium.org".
829 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
830 profile()->GetOffTheRecordProfile(), chromium_org_url());
831 content::RenderFrameHost* incognito_frame1 =
832 incognito_browser->tab_strip_model()
833 ->GetActiveWebContents()
834 ->GetMainFrame();
835 InfoBarService* infobar_service1 = InfoBarService::FromWebContents(
836 incognito_browser->tab_strip_model()->GetActiveWebContents());
838 CHECK(ui_test_utils::OpenURLOffTheRecord(profile()->GetOffTheRecordProfile(),
839 chromium_org_url()) ==
840 incognito_browser);
841 content::RenderFrameHost* incognito_frame2 =
842 incognito_browser->tab_strip_model()
843 ->GetActiveWebContents()
844 ->GetMainFrame();
845 InfoBarService* infobar_service2 = InfoBarService::FromWebContents(
846 incognito_browser->tab_strip_model()->GetActiveWebContents());
847 EXPECT_EQ(2, incognito_browser->tab_strip_model()->count());
848 EXPECT_NE(incognito_frame1, incognito_frame2);
850 // Trigger a infobars in both tabs by trying to send messages.
851 std::string script =
852 base::StringPrintf("assertions.trySendMessage('%s')", app->id().c_str());
853 CHECK(content::ExecuteScript(incognito_frame1, script));
854 CHECK(content::ExecuteScript(incognito_frame2, script));
855 EXPECT_EQ(1U, infobar_service1->infobar_count());
856 EXPECT_EQ(1U, infobar_service2->infobar_count());
858 // Navigating away will dismiss the infobar on the active tab only.
859 ui_test_utils::NavigateToURL(incognito_browser, google_com_url());
860 EXPECT_EQ(1U, infobar_service1->infobar_count());
861 EXPECT_EQ(0U, infobar_service2->infobar_count());
863 // Navigate back and accept the infobar this time. Both should be dismissed.
865 IncognitoConnectability::ScopedAlertTracker alert_tracker(
866 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
868 ui_test_utils::NavigateToURL(incognito_browser, chromium_org_url());
869 incognito_frame2 = incognito_browser->tab_strip_model()
870 ->GetActiveWebContents()
871 ->GetMainFrame();
872 EXPECT_NE(incognito_frame1, incognito_frame2);
874 EXPECT_EQ(1U, infobar_service1->infobar_count());
875 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame2, app.get(),
876 NULL));
877 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
878 EXPECT_EQ(0U, infobar_service1->infobar_count());
882 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
883 FromIncognitoAllowExtension) {
884 InitializeTestServer();
886 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
888 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
889 profile()->GetOffTheRecordProfile(), chromium_org_url());
890 content::RenderFrameHost* incognito_frame =
891 incognito_browser->tab_strip_model()
892 ->GetActiveWebContents()
893 ->GetMainFrame();
896 IncognitoConnectability::ScopedAlertTracker alert_tracker(
897 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
899 // No alert is shown.
900 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
901 CanConnectAndSendMessagesToFrame(
902 incognito_frame, extension.get(), NULL));
903 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
906 // Allowing the extension in incognito mode is what allows connections.
907 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
908 EXPECT_EQ(
910 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
913 // Tests a connection from an iframe within a tab which doesn't have
914 // permission. Iframe should work.
915 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
916 FromIframeWithPermission) {
917 InitializeTestServer();
919 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
921 ui_test_utils::NavigateToURL(browser(), google_com_url());
922 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
923 CanConnectAndSendMessagesToMainFrame(extension.get()));
924 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
926 ASSERT_TRUE(AppendIframe(chromium_org_url()));
928 EXPECT_EQ(OK, CanConnectAndSendMessagesToIFrame(extension.get()));
929 EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
932 // Tests connection from an iframe without permission within a tab that does.
933 // Iframe shouldn't work.
934 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
935 FromIframeWithoutPermission) {
936 InitializeTestServer();
938 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
940 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
941 EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
942 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
944 ASSERT_TRUE(AppendIframe(google_com_url()));
946 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
947 CanConnectAndSendMessagesToIFrame(extension.get()));
948 EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
951 // Tests externally_connectable between a web page and an extension with a
952 // TLS channel ID created for the origin.
953 class ExternallyConnectableMessagingWithTlsChannelIdTest :
954 public ExternallyConnectableMessagingTest {
955 public:
956 ExternallyConnectableMessagingWithTlsChannelIdTest()
957 : tls_channel_id_created_(false, false) {
960 std::string CreateTlsChannelId() {
961 scoped_refptr<net::URLRequestContextGetter> request_context_getter(
962 profile()->GetRequestContext());
963 std::string channel_id_private_key;
964 std::string channel_id_cert;
965 net::ChannelIDService::RequestHandle request_handle;
966 content::BrowserThread::PostTask(
967 content::BrowserThread::IO,
968 FROM_HERE,
969 base::Bind(
970 &ExternallyConnectableMessagingWithTlsChannelIdTest::
971 CreateDomainBoundCertOnIOThread,
972 base::Unretained(this),
973 base::Unretained(&channel_id_private_key),
974 base::Unretained(&channel_id_cert),
975 base::Unretained(&request_handle),
976 request_context_getter));
977 tls_channel_id_created_.Wait();
978 // Create the expected value.
979 base::StringPiece spki;
980 net::asn1::ExtractSPKIFromDERCert(channel_id_cert, &spki);
981 base::DictionaryValue jwk_value;
982 net::JwkSerializer::ConvertSpkiFromDerToJwk(spki, &jwk_value);
983 std::string tls_channel_id_value;
984 base::JSONWriter::Write(&jwk_value, &tls_channel_id_value);
985 return tls_channel_id_value;
988 private:
989 void CreateDomainBoundCertOnIOThread(
990 std::string* channel_id_private_key,
991 std::string* channel_id_cert,
992 net::ChannelIDService::RequestHandle* request_handle,
993 scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
994 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
995 net::ChannelIDService* channel_id_service =
996 request_context_getter->GetURLRequestContext()->
997 channel_id_service();
998 int status = channel_id_service->GetOrCreateChannelID(
999 chromium_org_url().host(),
1000 channel_id_private_key,
1001 channel_id_cert,
1002 base::Bind(&ExternallyConnectableMessagingWithTlsChannelIdTest::
1003 GotDomainBoundCert,
1004 base::Unretained(this)),
1005 request_handle);
1006 if (status == net::ERR_IO_PENDING)
1007 return;
1008 GotDomainBoundCert(status);
1011 void GotDomainBoundCert(int status) {
1012 ASSERT_TRUE(status == net::OK);
1013 tls_channel_id_created_.Signal();
1016 base::WaitableEvent tls_channel_id_created_;
1019 // Tests a web connectable extension that receives TLS channel id on a site
1020 // that can connect to it, with a TLS channel ID having been generated.
1021 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
1022 WebConnectableWithNonEmptyTlsChannelId) {
1023 InitializeTestServer();
1024 std::string expected_tls_channel_id_value = CreateTlsChannelId();
1026 scoped_refptr<const Extension> chromium_connectable =
1027 LoadChromiumConnectableExtensionWithTlsChannelId();
1028 ASSERT_TRUE(chromium_connectable.get());
1030 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1032 // Since the extension requests the TLS channel ID, it gets it for a site that
1033 // can connect to it, but only if the page also asks to send it.
1034 EXPECT_EQ(std::string(),
1035 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
1036 EXPECT_EQ(std::string(),
1037 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
1039 // If the page does ask to send the TLS channel ID, it's sent and non-empty.
1040 std::string tls_channel_id_from_port_connect =
1041 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1042 EXPECT_NE(0u, tls_channel_id_from_port_connect.size());
1044 // The same value is received by both connect and sendMessage.
1045 std::string tls_channel_id_from_send_message =
1046 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1047 EXPECT_EQ(tls_channel_id_from_port_connect, tls_channel_id_from_send_message);
1049 // And since a TLS channel ID exists for the domain, the value received is
1050 // parseable as a JWK. (In particular, it has the same value we created by
1051 // converting the public key to JWK with net::ConvertSpkiFromDerToJwk.)
1052 std::string tls_channel_id(tls_channel_id_from_port_connect);
1053 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1055 // The TLS channel ID shouldn't change from one connection to the next...
1056 std::string tls_channel_id2 =
1057 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1058 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1059 tls_channel_id2 =
1060 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1061 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1063 // nor should it change when navigating away, revisiting the page and
1064 // requesting it again.
1065 ui_test_utils::NavigateToURL(browser(), google_com_url());
1066 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1067 tls_channel_id2 =
1068 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1069 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1070 tls_channel_id2 =
1071 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1072 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1075 // Tests a web connectable extension that receives TLS channel id, but
1076 // immediately closes its background page upon receipt of a message.
1077 // Same flakiness seen in http://crbug.com/297866
1078 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
1079 DISABLED_WebConnectableWithNonEmptyTlsChannelIdAndClosedBackgroundPage) {
1080 InitializeTestServer();
1081 std::string expected_tls_channel_id_value = CreateTlsChannelId();
1083 scoped_refptr<const Extension> chromium_connectable =
1084 LoadChromiumConnectableExtensionWithTlsChannelId();
1086 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1087 // If the page does ask for it, it isn't empty, even if the background page
1088 // closes upon receipt of the connect.
1089 std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
1090 chromium_connectable.get(), true, close_background_message());
1091 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1092 // A subsequent connect will still succeed, even if the background page was
1093 // previously closed.
1094 tls_channel_id =
1095 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1096 // And the expected value is still retrieved.
1097 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1100 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingUserGesture) {
1101 const char kManifest[] = "{"
1102 " \"name\": \"user_gesture\","
1103 " \"version\": \"1.0\","
1104 " \"background\": {"
1105 " \"scripts\": [\"background.js\"]"
1106 " },"
1107 " \"manifest_version\": 2"
1108 "}";
1110 TestExtensionDir receiver_dir;
1111 receiver_dir.WriteManifest(kManifest);
1112 receiver_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
1113 "chrome.runtime.onMessageExternal.addListener(\n"
1114 " function(msg, sender, reply) {\n"
1115 " reply({result:chrome.test.isProcessingUserGesture()});\n"
1116 " });");
1117 const Extension* receiver = LoadExtension(receiver_dir.unpacked_path());
1118 ASSERT_TRUE(receiver);
1120 TestExtensionDir sender_dir;
1121 sender_dir.WriteManifest(kManifest);
1122 sender_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");
1123 const Extension* sender = LoadExtension(sender_dir.unpacked_path());
1124 ASSERT_TRUE(sender);
1126 EXPECT_EQ("false",
1127 ExecuteScriptInBackgroundPage(sender->id(),
1128 base::StringPrintf(
1129 "chrome.test.runWithoutUserGesture(function() {\n"
1130 " chrome.runtime.sendMessage('%s', {}, function(response) {\n"
1131 " window.domAutomationController.send('' + response.result);\n"
1132 " });\n"
1133 "});", receiver->id().c_str())));
1135 EXPECT_EQ("true",
1136 ExecuteScriptInBackgroundPage(sender->id(),
1137 base::StringPrintf(
1138 "chrome.test.runWithUserGesture(function() {\n"
1139 " chrome.runtime.sendMessage('%s', {}, function(response) {\n"
1140 " window.domAutomationController.send('' + response.result);\n"
1141 " });\n"
1142 "});", receiver->id().c_str())));
1145 // Tests that a hosted app on a connectable site doesn't interfere with the
1146 // connectability of that site.
1147 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, HostedAppOnWebsite) {
1148 InitializeTestServer();
1150 scoped_refptr<const Extension> app = LoadChromiumHostedApp();
1152 // The presence of the hosted app shouldn't give the ability to send messages.
1153 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1154 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
1155 CanConnectAndSendMessagesToMainFrame(app.get()));
1156 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
1158 // Once a connectable extension is installed, it should.
1159 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
1160 EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
1161 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
1164 // Tests that an invalid extension ID specified in a hosted app does not crash
1165 // the hosted app's renderer.
1167 // This is a regression test for http://crbug.com/326250#c12.
1168 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
1169 InvalidExtensionIDFromHostedApp) {
1170 InitializeTestServer();
1172 // The presence of the chromium hosted app triggers this bug. The chromium
1173 // connectable extension needs to be installed to set up the runtime bindings.
1174 LoadChromiumHostedApp();
1175 LoadChromiumConnectableExtension();
1177 scoped_refptr<const Extension> invalid =
1178 ExtensionBuilder()
1179 // A bit scary that this works...
1180 .SetID("invalid")
1181 .SetManifest(DictionaryBuilder()
1182 .Set("name", "Fake extension")
1183 .Set("version", "1")
1184 .Set("manifest_version", 2))
1185 .Build();
1187 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1188 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
1189 CanConnectAndSendMessagesToMainFrame(invalid.get()));
1192 #endif // !defined(OS_WIN) - http://crbug.com/350517.
1194 } // namespace
1196 }; // namespace extensions