15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/base64.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h"
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_reader.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_writer.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/path_service.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_piece.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/synchronization/waitable_event.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/extensions/test_extension_dir.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/api/runtime.h"
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/extension_builder.h"
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/value_builder.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/cert/asn1_util.h"
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/cert/jwk_serializer.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/dns/mock_host_resolver.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_service.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/url_request/url_request_context.h"
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace extensions {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageSender : public content::NotificationObserver {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageSender() {
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registrar_.Add(this,
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content::NotificationService::AllSources());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static scoped_ptr<base::ListValue> BuildEventArguments(
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const bool last_message,
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const std::string& data) {
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* event = new base::DictionaryValue();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->SetBoolean("lastMessage", last_message);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->SetString("data", data);
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<base::ListValue> arguments(new base::ListValue());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arguments->Append(event);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arguments.Pass();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static scoped_ptr<Event> BuildEvent(scoped_ptr<base::ListValue> event_args,
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      Profile* profile,
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      GURL event_url) {
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<Event> event(new Event("test.onMessage", event_args.Pass()));
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    event->restrict_to_browser_context = profile;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->event_url = event_url;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event.Pass();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EventRouter* event_router =
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        EventRouter::Get(content::Source<Profile>(source).ptr());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sends four messages to the extension. All but the third message sent
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from the origin http://b.com/ are supposed to arrive.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "no restriction"),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL()));
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "http://a.com/"),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL("http://a.com/")));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "http://b.com/"),
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL("http://b.com/")));
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(true, "last message"),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL()));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that message passing between extensions and content scripts works.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(StartEmbeddedTestServer());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect")) << message_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that message passing from one extension to another works.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_data_dir_.AppendASCII("..").AppendASCII("good")
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("Extensions")
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("1.0")));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that messages with event_urls are only passed to extensions with
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// appropriate permissions.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageSender sender;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests connecting from a panel to its extension.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PanelMessagingTest : public ExtensionApiTest {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kEnablePanels);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// XXX(kalman): All web messaging tests disabled on windows due to extreme
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// flakiness. See http://crbug.com/350517.
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_WIN)
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests externally_connectable between a web page and an extension.
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(kalman): Test between extensions. This is already tested in this file,
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// but not with externally_connectable set in the manifest.
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(kalman): Test with host permissions.
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ExternallyConnectableMessagingTest : public ExtensionApiTest {
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Result codes from the test. These must match up with |results| in
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // c/t/d/extensions/api_test/externally_connectable/assertions.json.
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  enum Result {
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OK = 0,
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    NAMESPACE_NOT_DEFINED = 1,
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FUNCTION_NOT_DEFINED = 2,
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3,
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OTHER_ERROR = 4,
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    INCORRECT_RESPONSE_SENDER = 5,
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    INCORRECT_RESPONSE_MESSAGE = 6,
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool AppendIframe(const GURL& src) {
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool result;
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(content::ExecuteScriptAndExtractBool(
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        "actions.appendIframe('" + src.spec() + "');", &result));
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return result;
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Result CanConnectAndSendMessagesToMainFrame(const Extension* extension,
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                              const char* message = NULL) {
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return CanConnectAndSendMessagesToFrame(
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        extension,
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        message);
178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Result CanConnectAndSendMessagesToIFrame(const Extension* extension,
181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                           const char* message = NULL) {
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    content::RenderFrameHost* frame = content::FrameMatchingPredicate(
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        browser()->tab_strip_model()->GetActiveWebContents(),
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&content::FrameIsChildOfMainFrame));
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return CanConnectAndSendMessagesToFrame(frame, extension, message);
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Result CanConnectAndSendMessagesToFrame(content::RenderFrameHost* frame,
1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                          const Extension* extension,
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          const char* message) {
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int result;
1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string command = base::StringPrintf(
1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "assertions.canConnectAndSendMessages('%s', %s, %s)",
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        extension->id().c_str(),
1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        extension->is_platform_app() ? "true" : "false",
1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        message ? base::StringPrintf("'%s'", message).c_str() : "undefined");
1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(content::ExecuteScriptAndExtractInt(frame, command, &result));
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return static_cast<Result>(result);
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  testing::AssertionResult AreAnyNonWebApisDefinedForMainFrame() {
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return AreAnyNonWebApisDefinedForFrame(
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  testing::AssertionResult AreAnyNonWebApisDefinedForIFrame() {
207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    content::RenderFrameHost* frame = content::FrameMatchingPredicate(
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        browser()->tab_strip_model()->GetActiveWebContents(),
209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&content::FrameIsChildOfMainFrame));
210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return AreAnyNonWebApisDefinedForFrame(frame);
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  testing::AssertionResult AreAnyNonWebApisDefinedForFrame(
214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      content::RenderFrameHost* frame) {
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // All runtime API methods are non-web except for sendRequest and connect.
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const char* non_messaging_apis[] = {
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getBackgroundPage",
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getManifest",
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getURL",
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "reload",
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "requestUpdateCheck",
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "restart",
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "connectNative",
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "sendNativeMessage",
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onStartup",
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onInstalled",
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onSuspend",
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onSuspendCanceled",
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onUpdateAvailable",
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onBrowserUpdateAvailable",
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onConnect",
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onConnectExternal",
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onMessage",
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onMessageExternal",
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "onRestartRequired",
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Note: no "id" here because this test method is used for hosted apps,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // which do have access to runtime.id.
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    };
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Turn the array into a JS array, which effectively gets eval()ed.
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string as_js_array;
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (size_t i = 0; i < arraysize(non_messaging_apis); ++i) {
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      as_js_array += as_js_array.empty() ? "[" : ",";
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]);
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    as_js_array += "]";
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool any_defined;
249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CHECK(content::ExecuteScriptAndExtractBool(
250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        frame,
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "assertions.areAnyRuntimePropertiesDefined(" + as_js_array + ")",
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &any_defined));
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return any_defined ?
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        testing::AssertionSuccess() : testing::AssertionFailure();
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string GetTlsChannelIdFromPortConnect(const Extension* extension,
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             bool include_tls_channel_id,
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             const char* message = NULL) {
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return GetTlsChannelIdFromAssertion("getTlsChannelIdFromPortConnect",
2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                        extension,
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        include_tls_channel_id,
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        message);
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string GetTlsChannelIdFromSendMessage(const Extension* extension,
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             bool include_tls_channel_id,
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             const char* message = NULL) {
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return GetTlsChannelIdFromAssertion("getTlsChannelIdFromSendMessage",
2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                        extension,
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        include_tls_channel_id,
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        message);
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL GetURLForPath(const std::string& host, const std::string& path) {
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string port = base::IntToString(embedded_test_server()->port());
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GURL::Replacements replacements;
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    replacements.SetHostStr(host);
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    replacements.SetPortStr(port);
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return embedded_test_server()->GetURL(path).ReplaceComponents(replacements);
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL chromium_org_url() {
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return GetURLForPath("www.chromium.org", "/chromium.org.html");
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL google_com_url() {
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return GetURLForPath("www.google.com", "/google.com.html");
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> LoadChromiumConnectableExtension() {
2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_refptr<const Extension> extension =
2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        LoadExtensionIntoDir(&web_connectable_dir_,
2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             base::StringPrintf(
2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "{"
2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"name\": \"chromium_connectable\","
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  %s,"
2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"externally_connectable\": {"
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "    \"matches\": [\"*://*.chromium.org:*/*\"]"
3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  }"
3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "}",
3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 common_manifest()));
3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(extension.get());
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return extension;
3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> LoadChromiumConnectableApp() {
3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_refptr<const Extension> extension =
3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        LoadExtensionIntoDir(&web_connectable_dir_,
3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "{"
3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  \"app\": {"
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "    \"background\": {"
3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "      \"scripts\": [\"background.js\"]"
3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "    }"
3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  },"
3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  \"externally_connectable\": {"
3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "    \"matches\": [\"*://*.chromium.org:*/*\"]"
3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  },"
3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  \"manifest_version\": 2,"
3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  \"name\": \"app_connectable\","
3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "  \"version\": \"1.0\""
3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             "}");
3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(extension.get());
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return extension;
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> LoadNotConnectableExtension() {
3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_refptr<const Extension> extension =
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        LoadExtensionIntoDir(&not_connectable_dir_,
3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             base::StringPrintf(
3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "{"
3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"name\": \"not_connectable\","
3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  %s"
3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "}",
3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 common_manifest()));
3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(extension.get());
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return extension;
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension>
3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  LoadChromiumConnectableExtensionWithTlsChannelId() {
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return LoadExtensionIntoDir(&tls_channel_id_connectable_dir_,
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                connectable_with_tls_channel_id_manifest());
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> LoadChromiumHostedApp() {
3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_refptr<const Extension> hosted_app =
3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        LoadExtensionIntoDir(&hosted_app_dir_,
3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             base::StringPrintf(
3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "{"
3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"name\": \"chromium_hosted_app\","
3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"version\": \"1.0\","
3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"manifest_version\": 2,"
3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  \"app\": {"
3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "    \"urls\": [\"%s\"],"
3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "    \"launch\": {"
3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "      \"web_url\": \"%s\""
3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "    }\n"
3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "  }\n"
3605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 "}",
3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 chromium_org_url().spec().c_str(),
3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                 chromium_org_url().spec().c_str()));
3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CHECK(hosted_app.get());
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return hosted_app;
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void InitializeTestServer() {
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::FilePath test_data;
3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII(
3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "extensions/api_test/messaging/externally_connectable/sites"));
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const char* close_background_message() {
377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return "closeBackgroundPage";
378d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
3815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> LoadExtensionIntoDir(
3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      TestExtensionDir* dir,
3835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const std::string& manifest) {
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    dir->WriteManifest(manifest);
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    dir->WriteFile(FILE_PATH_LITERAL("background.js"),
386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                   base::StringPrintf(
387d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "function maybeClose(message) {\n"
388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  if (message.indexOf('%s') >= 0)\n"
389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "    window.setTimeout(function() { window.close() }, 0);\n"
390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "}\n"
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "chrome.runtime.onMessageExternal.addListener(\n"
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "    function(message, sender, reply) {\n"
3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "  reply({ message: message, sender: sender });\n"
394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  maybeClose(message);\n"
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "});\n"
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "chrome.runtime.onConnectExternal.addListener(function(port) {\n"
3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "  port.onMessage.addListener(function(message) {\n"
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "    port.postMessage({ message: message, sender: port.sender });\n"
399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "    maybeClose(message);\n"
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        "  });\n"
401d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "});\n",
402d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                   close_background_message()));
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return LoadExtension(dir->unpacked_path());
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const char* common_manifest() {
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return "\"version\": \"1.0\","
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           "\"background\": {"
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           "    \"scripts\": [\"background.js\"],"
4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           "    \"persistent\": false"
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           "},"
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           "\"manifest_version\": 2";
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string connectable_with_tls_channel_id_manifest() {
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return base::StringPrintf(
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "{"
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "  \"name\": \"chromium_connectable_with_tls_channel_id\","
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "  %s,"
4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "  \"externally_connectable\": {"
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "    \"matches\": [\"*://*.chromium.org:*/*\"],"
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "    \"accepts_tls_channel_id\": true"
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "  }"
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "}",
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        common_manifest());
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string GetTlsChannelIdFromAssertion(const char* method,
4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                           const Extension* extension,
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                           bool include_tls_channel_id,
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                           const char* message) {
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string result;
4335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string args = "'" + extension->id() + "', ";
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    args += include_tls_channel_id ? "true" : "false";
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (message)
4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      args += std::string(", '") + message + "'";
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CHECK(content::ExecuteScriptAndExtractString(
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::StringPrintf("assertions.%s(%s)", method, args.c_str()),
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &result));
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return result;
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestExtensionDir web_connectable_dir_;
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestExtensionDir not_connectable_dir_;
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestExtensionDir tls_channel_id_connectable_dir_;
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestExtensionDir hosted_app_dir_;
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) {
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitializeTestServer();
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> extension =
4545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ExtensionBuilder()
4555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
4565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .SetManifest(DictionaryBuilder()
4575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("name", "Fake extension")
4585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("version", "1")
4595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("manifest_version", 2))
4605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .Build();
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
463effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(extension.get()));
465effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(extension.get()));
470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Tests two extensions on the same sites: one web connectable, one not.
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       WebConnectableAndNotConnectable) {
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitializeTestServer();
477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Install the web connectable extension. chromium.org can connect to it,
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // google.com can't.
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadChromiumConnectableExtension();
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK,
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
491effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Install the non-connectable extension. Nothing can connect to it.
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> not_connectable =
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadNotConnectableExtension();
496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Namespace will be defined here because |chromium_connectable| can connect
4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // to it - so this will be the "cannot establish connection" error.
500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
51068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// See http://crbug.com/297866
511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       DISABLED_BackgroundPageClosesOnMessageReceipt) {
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitializeTestServer();
514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Install the web connectable extension.
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadChromiumConnectableExtension();
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If the background page closes after receipt of the message, it will still
521d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // reply to this message...
522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(OK,
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get(),
524effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                 close_background_message()));
525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // and be re-opened by receipt of a subsequent message.
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK,
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that doesn't receive TLS channel id.
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       WebConnectableWithoutTlsChannelId) {
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Install the web connectable extension. chromium.org can connect to it,
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // google.com can't.
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadChromiumConnectableExtension();
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(chromium_connectable.get());
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The web connectable extension doesn't request the TLS channel ID, so it
5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // doesn't get it, whether or not the page asks for it.
5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that receives TLS channel id with a site
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// that can't connect to it.
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       WebConnectableWithTlsChannelIdWithNonMatchingSite) {
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadChromiumConnectableExtensionWithTlsChannelId();
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(chromium_connectable.get());
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The extension requests the TLS channel ID, but it doesn't get it for a
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // site that can't connect to it, regardless of whether the page asks for it.
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that receives TLS channel id on a site
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// that can connect to it, but with no TLS channel ID having been generated.
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       WebConnectableWithTlsChannelIdWithEmptyTlsChannelId) {
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadChromiumConnectableExtensionWithTlsChannelId();
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(chromium_connectable.get());
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Since the extension requests the TLS channel ID, it gets it for a site that
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // can connect to it, but only if the page also asks to include it.
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the page does ask for it, it isn't empty.
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tls_channel_id =
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Because the TLS channel ID has never been generated for this domain,
5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // no TLS channel ID is reported.
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(), tls_channel_id);
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Flaky on Linux and Windows. http://crbug.com/315264
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that receives TLS channel id, but
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// immediately closes its background page upon receipt of a message.
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DISABLED_WebConnectableWithEmptyTlsChannelIdAndClosedBackgroundPage) {
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadChromiumConnectableExtensionWithTlsChannelId();
6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the page does ask for it, it isn't empty, even if the background page
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // closes upon receipt of the connect.
6165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      chromium_connectable.get(), true, close_background_message());
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Because the TLS channel ID has never been generated for this domain,
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // no TLS channel ID is reported.
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(), tls_channel_id);
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A subsequent connect will still succeed, even if the background page was
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // previously closed.
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tls_channel_id =
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   // And the empty value is still retrieved.
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(), tls_channel_id);
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Tests that enabling and disabling an extension makes the runtime bindings
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// appear and disappear.
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TODO(kalman): Test with multiple extensions that can be accessed by the same
6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// host.
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       EnablingAndDisabling) {
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitializeTestServer();
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadChromiumConnectableExtension();
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> not_connectable =
6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LoadNotConnectableExtension();
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK,
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DisableExtension(chromium_connectable->id());
650ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EnableExtension(chromium_connectable->id());
6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK,
6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Tests connection from incognito tabs when the user denies the connection
6615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// request. Spanning mode only. A separate test for apps and extensions.
662a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//
663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// TODO(kalman): ensure that we exercise split vs spanning incognito logic
664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// somewhere. This is a test that should be shared with the content script logic
665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// so it's not really our specific concern for web connectable.
6668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
6678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(kalman): test messages from incognito extensions too.
6685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
6695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       FromIncognitoDenyApp) {
670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  InitializeTestServer();
671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
6735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(app->is_platform_app());
674a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
675a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
676a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      profile()->GetOffTheRecordProfile(),
677a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      chromium_org_url());
678effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  content::RenderFrameHost* incognito_frame = incognito_browser->
679effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      tab_strip_model()->GetActiveWebContents()->GetMainFrame();
680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  {
6828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    IncognitoConnectability::ScopedAlertTracker alert_tracker(
6838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
6848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // No connection because incognito-enabled hasn't been set for the app, and
6865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // the user denied our interactive request.
6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(
6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        COULD_NOT_ESTABLISH_CONNECTION_ERROR,
6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
6908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
6918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Try again. User has already denied so alert not shown.
6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        COULD_NOT_ESTABLISH_CONNECTION_ERROR,
6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
6965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
6975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
6985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // It's not possible to allow an app in incognito.
7005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
7015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
7021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
7035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
7045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
7065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       FromIncognitoDenyExtension) {
7075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  InitializeTestServer();
7085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
7105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
7125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      profile()->GetOffTheRecordProfile(), chromium_org_url());
7135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::RenderFrameHost* incognito_frame =
7145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      incognito_browser->tab_strip_model()
7155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ->GetActiveWebContents()
7165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ->GetMainFrame();
7175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
7195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IncognitoConnectability::ScopedAlertTracker alert_tracker(
7205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
7215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // The alert doesn't show for extensions.
7231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
7241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              CanConnectAndSendMessagesToFrame(
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  incognito_frame, extension.get(), NULL));
7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
7278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Allowing the extension in incognito mode will bypass the deny.
7305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
7311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
7321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OK,
7331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Tests connection from incognito tabs when the user accepts the connection
7375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// request. Spanning mode only. Separate tests for apps and extensions.
7388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
7398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(kalman): see comment above about split mode.
7405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
7415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       FromIncognitoAllowApp) {
7428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  InitializeTestServer();
7438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
7455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_TRUE(app->is_platform_app());
746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      profile()->GetOffTheRecordProfile(),
7498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      chromium_org_url());
750effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  content::RenderFrameHost* incognito_frame = incognito_browser->
751effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      tab_strip_model()->GetActiveWebContents()->GetMainFrame();
7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  {
7548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    IncognitoConnectability::ScopedAlertTracker alert_tracker(
7558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
7568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Connection allowed even with incognito disabled, because the user
7585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // accepted the interactive request.
7591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(
7601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
7618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
7628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Try again. User has already allowed.
7641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(
7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
7668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
7678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Apps can't be allowed in incognito mode, but it's moot because it's
7705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // already allowed.
7715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
7721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK,
7731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
7745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
7755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
7775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       FromIncognitoAllowExtension) {
7785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  InitializeTestServer();
7795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
7815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
7835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      profile()->GetOffTheRecordProfile(), chromium_org_url());
7845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  content::RenderFrameHost* incognito_frame =
7855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      incognito_browser->tab_strip_model()
7865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ->GetActiveWebContents()
7875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          ->GetMainFrame();
7885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
7905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IncognitoConnectability::ScopedAlertTracker alert_tracker(
7915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
7925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // No alert is shown.
7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
7951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              CanConnectAndSendMessagesToFrame(
7961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  incognito_frame, extension.get(), NULL));
7975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
7985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
7995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
8005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Allowing the extension in incognito mode is what allows connections.
8015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OK,
8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
805a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
806a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests a connection from an iframe within a tab which doesn't have
8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// permission. Iframe should work.
8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
8103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       FromIframeWithPermission) {
8113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  InitializeTestServer();
8123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
8143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
816effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(extension.get()));
818effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
8193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(AppendIframe(chromium_org_url()));
8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, CanConnectAndSendMessagesToIFrame(extension.get()));
823effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
8243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests connection from an iframe without permission within a tab that does.
8273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Iframe shouldn't work.
8283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       FromIframeWithoutPermission) {
8303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  InitializeTestServer();
8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
8351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
836effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
8373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(AppendIframe(google_com_url()));
8393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
8411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToIFrame(extension.get()));
842effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests externally_connectable between a web page and an extension with a
8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TLS channel ID created for the origin.
8474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ExternallyConnectableMessagingWithTlsChannelIdTest :
8484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  public ExternallyConnectableMessagingTest {
8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ExternallyConnectableMessagingWithTlsChannelIdTest()
8514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : tls_channel_id_created_(false, false) {
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string CreateTlsChannelId() {
8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> request_context_getter(
8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        profile()->GetRequestContext());
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string channel_id_private_key;
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string channel_id_cert;
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::ChannelIDService::RequestHandle request_handle;
8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::BrowserThread::PostTask(
8614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        content::BrowserThread::IO,
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FROM_HERE,
8634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(
8644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            &ExternallyConnectableMessagingWithTlsChannelIdTest::
8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                CreateDomainBoundCertOnIOThread,
8664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            base::Unretained(this),
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            base::Unretained(&channel_id_private_key),
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            base::Unretained(&channel_id_cert),
8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            base::Unretained(&request_handle),
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            request_context_getter));
8714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    tls_channel_id_created_.Wait();
8724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Create the expected value.
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::StringPiece spki;
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::asn1::ExtractSPKIFromDERCert(channel_id_cert, &spki);
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::DictionaryValue jwk_value;
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    net::JwkSerializer::ConvertSpkiFromDerToJwk(spki, &jwk_value);
8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string tls_channel_id_value;
8784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::JSONWriter::Write(&jwk_value, &tls_channel_id_value);
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return tls_channel_id_value;
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void CreateDomainBoundCertOnIOThread(
8845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::string* channel_id_private_key,
8855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::string* channel_id_cert,
8865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      net::ChannelIDService::RequestHandle* request_handle,
8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
888effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    net::ChannelIDService* channel_id_service =
8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        request_context_getter->GetURLRequestContext()->
8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            channel_id_service();
8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int status = channel_id_service->GetOrCreateChannelID(
8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        chromium_org_url().host(),
8945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        channel_id_private_key,
8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        channel_id_cert,
8964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&ExternallyConnectableMessagingWithTlsChannelIdTest::
8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   GotDomainBoundCert,
8984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   base::Unretained(this)),
8994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        request_handle);
9004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (status == net::ERR_IO_PENDING)
9014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
9024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GotDomainBoundCert(status);
9034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void GotDomainBoundCert(int status) {
9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_TRUE(status == net::OK);
9074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    tls_channel_id_created_.Signal();
9084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WaitableEvent tls_channel_id_created_;
9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
9124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that receives TLS channel id on a site
9144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// that can connect to it, with a TLS channel ID having been generated.
9154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
9164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       WebConnectableWithNonEmptyTlsChannelId) {
9174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
9184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string expected_tls_channel_id_value = CreateTlsChannelId();
9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
9214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadChromiumConnectableExtensionWithTlsChannelId();
9221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(chromium_connectable.get());
9234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
9254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Since the extension requests the TLS channel ID, it gets it for a site that
9274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // can connect to it, but only if the page also asks to send it.
9284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
9291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
9304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(std::string(),
9311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
9324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the page does ask to send the TLS channel ID, it's sent and non-empty.
9344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tls_channel_id_from_port_connect =
9351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_NE(0u, tls_channel_id_from_port_connect.size());
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The same value is received by both connect and sendMessage.
9394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tls_channel_id_from_send_message =
9401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
9414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(tls_channel_id_from_port_connect, tls_channel_id_from_send_message);
9424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // And since a TLS channel ID exists for the domain, the value received is
9444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // parseable as a JWK. (In particular, it has the same value we created by
9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // converting the public key to JWK with net::ConvertSpkiFromDerToJwk.)
9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tls_channel_id(tls_channel_id_from_port_connect);
9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The TLS channel ID shouldn't change from one connection to the next...
9504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string tls_channel_id2 =
9511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
9524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(tls_channel_id, tls_channel_id2);
9531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tls_channel_id2 =
9541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
9554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(tls_channel_id, tls_channel_id2);
9564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // nor should it change when navigating away, revisiting the page and
9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // requesting it again.
9594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), google_com_url());
9604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
9611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tls_channel_id2 =
9621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
9634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(tls_channel_id, tls_channel_id2);
9641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tls_channel_id2 =
9651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
9664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(tls_channel_id, tls_channel_id2);
9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests a web connectable extension that receives TLS channel id, but
9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// immediately closes its background page upon receipt of a message.
9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Same flakiness seen in http://crbug.com/297866
9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DISABLED_WebConnectableWithNonEmptyTlsChannelIdAndClosedBackgroundPage) {
9744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  InitializeTestServer();
9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string expected_tls_channel_id_value = CreateTlsChannelId();
9764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> chromium_connectable =
9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadChromiumConnectableExtensionWithTlsChannelId();
9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If the page does ask for it, it isn't empty, even if the background page
9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // closes upon receipt of the connect.
9835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
9841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      chromium_connectable.get(), true, close_background_message());
9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
9864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A subsequent connect will still succeed, even if the background page was
9874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // previously closed.
9881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tls_channel_id =
9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
9904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   // And the expected value is still retrieved.
9914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingUserGesture) {
9951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const char kManifest[] = "{"
9961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "  \"name\": \"user_gesture\","
9971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "  \"version\": \"1.0\","
9981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "  \"background\": {"
9991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "    \"scripts\": [\"background.js\"]"
10001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "  },"
10011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "  \"manifest_version\": 2"
10021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          "}";
10031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TestExtensionDir receiver_dir;
10051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  receiver_dir.WriteManifest(kManifest);
10061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  receiver_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
10071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      "chrome.runtime.onMessageExternal.addListener(\n"
10081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      "    function(msg, sender, reply) {\n"
10091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      "      reply({result:chrome.test.isProcessingUserGesture()});\n"
10101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      "    });");
10111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const Extension* receiver = LoadExtension(receiver_dir.unpacked_path());
10121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(receiver);
10131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TestExtensionDir sender_dir;
10151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  sender_dir.WriteManifest(kManifest);
10161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  sender_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");
10171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const Extension* sender = LoadExtension(sender_dir.unpacked_path());
10181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(sender);
10191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("false",
10211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ExecuteScriptInBackgroundPage(sender->id(),
10221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    base::StringPrintf(
10231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "chrome.test.runWithoutUserGesture(function() {\n"
10241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
10251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "    window.domAutomationController.send('' + response.result);\n"
10261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  });\n"
10271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "});", receiver->id().c_str())));
10281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("true",
10301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ExecuteScriptInBackgroundPage(sender->id(),
10311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    base::StringPrintf(
10321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "chrome.test.runWithUserGesture(function() {\n"
10331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
10341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "    window.domAutomationController.send('' + response.result);\n"
10351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  });\n"
10361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "});", receiver->id().c_str())));
10371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
10381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that a hosted app on a connectable site doesn't interfere with the
10405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// connectability of that site.
10415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, HostedAppOnWebsite) {
10425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeTestServer();
10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> app = LoadChromiumHostedApp();
10455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The presence of the hosted app shouldn't give the ability to send messages.
10475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
10481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NAMESPACE_NOT_DEFINED,
10491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(app.get()));
1050effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
10515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Once a connectable extension is installed, it should.
10531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
10541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
1055effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that an invalid extension ID specified in a hosted app does not crash
10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the hosted app's renderer.
10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is a regression test for http://crbug.com/326250#c12.
10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       InvalidExtensionIDFromHostedApp) {
10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeTestServer();
10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The presence of the chromium hosted app triggers this bug. The chromium
10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // connectable extension needs to be installed to set up the runtime bindings.
10685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoadChromiumHostedApp();
10695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoadChromiumConnectableExtension();
10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<const Extension> invalid =
10725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ExtensionBuilder()
10735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          // A bit scary that this works...
10745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .SetID("invalid")
10755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .SetManifest(DictionaryBuilder()
10765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("name", "Fake extension")
10775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("version", "1")
10785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           .Set("manifest_version", 2))
10795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          .Build();
10805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), chromium_org_url());
10825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
10831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            CanConnectAndSendMessagesToMainFrame(invalid.get()));
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // !defined(OS_WIN) - http://crbug.com/350517.
1087a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};  // namespace extensions
1091