Commit 02f6a50f authored by Ghazale Hosseinabadi's avatar Ghazale Hosseinabadi Committed by Commit Bot

[Extensions] Implement devtools inspection for inactive SW background.

chrome://extensions/ supports inspect views for the background page.
This CL adds the capability to inspect views for an inactive service
worker.

Bug: 1107596
Change-Id: I2b021659c60b07dbc455c1ed046fa4738bea8ffb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425191
Commit-Queue: Ghazale Hosseinabadi <ghazale@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812778}
parent e4742b85
...@@ -1775,8 +1775,8 @@ DeveloperPrivateOpenDevToolsFunction::Run() { ...@@ -1775,8 +1775,8 @@ DeveloperPrivateOpenDevToolsFunction::Run() {
if (!extension) if (!extension)
return RespondNow(Error(kNoSuchExtensionError)); return RespondNow(Error(kNoSuchExtensionError));
if (properties.render_process_id == -1) { if (properties.render_process_id == -1) {
// TODO(crbug.com/1107596): Implement inspecting view of an inactive // Start the service worker and open the inspect window.
// service worker. devtools_util::InspectInactiveServiceWorkerBackground(extension, profile);
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
devtools_util::InspectServiceWorkerBackground(extension, profile); devtools_util::InspectServiceWorkerBackground(extension, profile);
......
...@@ -5,15 +5,19 @@ ...@@ -5,15 +5,19 @@
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/extensions/api/developer_private/developer_private_api.h" #include "chrome/browser/extensions/api/developer_private/developer_private_api.h"
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h" #include "content/public/test/browser_test.h"
#include "content/public/test/service_worker_test_helpers.h"
#include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/service_worker/service_worker_test_utils.h"
#include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/test/result_catcher.h" #include "extensions/test/result_catcher.h"
...@@ -133,6 +137,88 @@ IN_PROC_BROWSER_TEST_F(DeveloperPrivateApiTest, InspectEmbeddedOptionsPage) { ...@@ -133,6 +137,88 @@ IN_PROC_BROWSER_TEST_F(DeveloperPrivateApiTest, InspectEmbeddedOptionsPage) {
EXPECT_TRUE(DevToolsWindow::GetInstanceForInspectedWebContents(wc)); EXPECT_TRUE(DevToolsWindow::GetInstanceForInspectedWebContents(wc));
} }
IN_PROC_BROWSER_TEST_F(DeveloperPrivateApiTest,
InspectInactiveServiceWorkerBackground) {
ResultCatcher result_catcher;
// Load an extension that is service worker based.
const Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("service_worker")
.AppendASCII("worker_based_background")
.AppendASCII("inspect"));
ASSERT_TRUE(extension);
ASSERT_TRUE(result_catcher.GetNextResult());
service_worker_test_utils::TestRegistrationObserver registration_observer(
browser()->profile());
registration_observer.WaitForRegistrationStored();
// Stop the service worker.
{
base::RunLoop run_loop;
content::StoragePartition* storage_partition =
content::BrowserContext::GetDefaultStoragePartition(profile());
content::ServiceWorkerContext* context =
storage_partition->GetServiceWorkerContext();
content::StopServiceWorkerForScope(context, extension->url(),
run_loop.QuitClosure());
run_loop.Run();
}
// Get the info about the extension, including the inspectable views.
auto get_info_function =
base::MakeRefCounted<api::DeveloperPrivateGetExtensionInfoFunction>();
std::unique_ptr<base::Value> result(
extension_function_test_utils::RunFunctionAndReturnSingleResult(
get_info_function.get(),
base::StringPrintf("[\"%s\"]", extension->id().c_str()), browser()));
ASSERT_TRUE(result);
std::unique_ptr<api::developer_private::ExtensionInfo> info =
api::developer_private::ExtensionInfo::FromValue(*result);
ASSERT_TRUE(info);
// There should be a worker based background for the extension.
ASSERT_EQ(1u, info->views.size());
const api::developer_private::ExtensionView& view = info->views[0];
EXPECT_EQ(
api::developer_private::VIEW_TYPE_EXTENSION_SERVICE_WORKER_BACKGROUND,
view.type);
// The service worker should be inactive (indicated by -1 for
// the process id).
EXPECT_EQ(-1, view.render_process_id);
// Inspect the inactive service worker background.
DevToolsWindowCreationObserver devtools_window_created_observer;
auto dev_tools_function =
base::MakeRefCounted<api::DeveloperPrivateOpenDevToolsFunction>();
extension_function_test_utils::RunFunction(dev_tools_function.get(),
base::StringPrintf(
R"([{"renderViewId": -1,
"renderProcessId": -1,
"isServiceWorker": true,
"extensionId": "%s"
}])",
extension->id().c_str()),
browser(), api_test_utils::NONE);
devtools_window_created_observer.WaitForLoad();
// Verify that dev tool window opened.
scoped_refptr<content::DevToolsAgentHost> service_worker_host;
content::DevToolsAgentHost::List targets =
content::DevToolsAgentHost::GetOrCreateAll();
for (const scoped_refptr<content::DevToolsAgentHost>& host : targets) {
if (host->GetType() == content::DevToolsAgentHost::kTypeServiceWorker &&
host->GetURL() ==
extension->GetResourceURL(
BackgroundInfo::GetBackgroundServiceWorkerScript(extension))) {
EXPECT_FALSE(service_worker_host);
service_worker_host = host;
}
}
ASSERT_TRUE(service_worker_host);
EXPECT_TRUE(DevToolsWindow::FindDevToolsWindow(service_worker_host.get()));
}
IN_PROC_BROWSER_TEST_F(DeveloperPrivateApiTest, IN_PROC_BROWSER_TEST_F(DeveloperPrivateApiTest,
InspectActiveServiceWorkerBackground) { InspectActiveServiceWorkerBackground) {
ResultCatcher result_catcher; ResultCatcher result_catcher;
......
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
#include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "extensions/browser/extension_host.h" #include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/lazy_context_id.h" #include "extensions/browser/lazy_context_id.h"
#include "extensions/browser/lazy_context_task_queue.h" #include "extensions/browser/lazy_context_task_queue.h"
#include "extensions/browser/process_manager.h" #include "extensions/browser/process_manager.h"
#include "extensions/browser/service_worker_task_queue.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/background_info.h"
...@@ -26,6 +28,23 @@ void InspectExtensionHost( ...@@ -26,6 +28,23 @@ void InspectExtensionHost(
DevToolsWindow::OpenDevToolsWindow(context_info->web_contents); DevToolsWindow::OpenDevToolsWindow(context_info->web_contents);
} }
void InspectServiceWorkerBackgroundHelper(
std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
if (!context_info)
return;
Profile* profile = Profile::FromBrowserContext(context_info->browser_context);
const Extension* extension =
ExtensionRegistry::Get(context_info->browser_context)
->enabled_extensions()
.GetByID(context_info->extension_id);
// A non-null context info does not guarantee that the extension is enabled,
// due to thread/process asynchrony.
if (extension)
InspectServiceWorkerBackground(extension, profile);
}
} // namespace } // namespace
// Helper to inspect a service worker after it has been started. // Helper to inspect a service worker after it has been started.
...@@ -45,6 +64,17 @@ void InspectServiceWorkerBackground(const Extension* extension, ...@@ -45,6 +64,17 @@ void InspectServiceWorkerBackground(const Extension* extension,
} }
} }
void InspectInactiveServiceWorkerBackground(const Extension* extension,
Profile* profile) {
DCHECK(extension);
DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
LazyContextId context_id(
profile, extension->id(),
Extension::GetBaseURLFromExtensionId(extension->id()));
context_id.GetTaskQueue()->AddPendingTask(
context_id, base::BindOnce(&InspectServiceWorkerBackgroundHelper));
}
void InspectBackgroundPage(const Extension* extension, Profile* profile) { void InspectBackgroundPage(const Extension* extension, Profile* profile) {
DCHECK(extension); DCHECK(extension);
ExtensionHost* host = ProcessManager::Get(profile) ExtensionHost* host = ProcessManager::Get(profile)
......
...@@ -17,6 +17,11 @@ namespace devtools_util { ...@@ -17,6 +17,11 @@ namespace devtools_util {
void InspectServiceWorkerBackground(const Extension* extension, void InspectServiceWorkerBackground(const Extension* extension,
Profile* profile); Profile* profile);
// Open a dev tools window for an inactive service worker background for the
// given extension.
void InspectInactiveServiceWorkerBackground(const Extension* extension,
Profile* profile);
// Open a dev tools window for the background page for the given extension, // Open a dev tools window for the background page for the given extension,
// starting the background page first if necessary. // starting the background page first if necessary.
void InspectBackgroundPage(const Extension* extension, Profile* profile); void InspectBackgroundPage(const Extension* extension, Profile* profile);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment