1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_client_host.h"
84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/debugger/devtools_manager.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_devtools_browsertest.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_error_reporter.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_process_manager.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_tabs_module.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/devtools_messages.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui_test_utils.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h"
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Looks for an ExtensionHost whose URL has the given path component (including
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// leading slash).  Also verifies that the expected number of hosts are loaded.
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const std::string& path,
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       int expected_hosts) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host = NULL;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int num_hosts = 0;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionProcessManager::const_iterator iter = manager->begin();
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != manager->end(); ++iter) {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if ((*iter)->GetURL().path() == path) {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_FALSE(host);
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host = *iter;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    num_hosts++;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(expected_hosts, num_hosts);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(host);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return host;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests for the experimental timeline extensions API.
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(johnnyg): crbug.com/52544 Test was broken by webkit r65510.
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, FLAKY_TimelineApi) {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(LoadExtension(
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the ExtensionHost that is hosting our background page.
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* manager =
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser()->profile()->GetExtensionProcessManager();
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab a handle to the DevToolsManager so we can forward messages to it.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab the tab_id of whatever tab happens to be first.
62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* tab_contents = browser()->GetTabContentsAt(0);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(tab_contents);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test setup.
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = false;
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring register_listeners_js = base::StringPrintf(
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      L"setListenersOnTab(%d)", tab_id);
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host->render_view_host(), L"", register_listeners_js, &result));
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Setting the events should have caused an ExtensionDevToolsBridge to be
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // registered for the tab's RenderViewHost.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsClientHost* devtools_client_host =
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      devtools_manager->GetDevToolsClientHostFor(
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          tab_contents->render_view_host());
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(devtools_client_host);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test onPageEvent event.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = false;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DevToolsClientMsg_DispatchOnInspectorFrontend pageEventMessage("");
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  devtools_client_host->SendMessageToClient(pageEventMessage);
86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host->render_view_host(), L"", L"testReceivePageEvent()", &result));
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test onTabClose event.
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = false;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  devtools_manager->UnregisterDevToolsClientHostFor(
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->render_view_host());
94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host->render_view_host(), L"", L"testReceiveTabCloseEvent()", &result));
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that ref counting of listeners from multiple processes works.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, ProcessRefCounting) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(LoadExtension(
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the ExtensionHost that is hosting our background page.
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* manager =
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser()->profile()->GetExtensionProcessManager();
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host_one = FindHostWithPath(manager, "/background.html", 1);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(LoadExtension(
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api_two")));
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host_two = FindHostWithPath(manager,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             "/background_two.html", 2);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab the tab_id of whatever tab happens to be first.
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* tab_contents = browser()->GetTabContentsAt(0);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(tab_contents);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test setup.
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = false;
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring register_listeners_js = base::StringPrintf(
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      L"setListenersOnTab(%d)", tab_id);
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host_one->render_view_host(), L"", register_listeners_js, &result));
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Setting the event listeners should have caused an ExtensionDevToolsBridge
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to be registered for the tab's RenderViewHost.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->render_view_host()));
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Register listeners from the second extension as well.
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring script = base::StringPrintf(L"registerListenersForTab(%d)",
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           tab_id);
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host_two->render_view_host(), L"", script, &result));
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Removing the listeners from the first extension should leave the bridge
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // alive.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = false;
145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host_one->render_view_host(), L"", L"unregisterListeners()", &result));
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->render_view_host()));
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Removing the listeners from the second extension should tear the bridge
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // down.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = false;
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      host_two->render_view_host(), L"", L"unregisterListeners()", &result));
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(result);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(devtools_manager->GetDevToolsClientHostFor(
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->render_view_host()));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
160