blob: fa2f1143c27864796a4501f339487412fafa7089 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "headless/lib/browser/headless_devtools_manager_delegate.h"
#include "build/build_config.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "headless/grit/headless_lib_resources.h"
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_web_contents_impl.h"
#include "headless/lib/browser/protocol/headless_devtools_session.h"
#include "ui/base/resource/resource_bundle.h"
namespace headless {
HeadlessDevToolsManagerDelegate::HeadlessDevToolsManagerDelegate(
base::WeakPtr<HeadlessBrowserImpl> browser)
: browser_(std::move(browser)) {}
HeadlessDevToolsManagerDelegate::~HeadlessDevToolsManagerDelegate() = default;
void HeadlessDevToolsManagerDelegate::HandleCommand(
content::DevToolsAgentHost* agent_host,
content::DevToolsAgentHostClient* client,
const std::string& method,
const std::string& message,
NotHandledCallback callback) {
DCHECK(sessions_.find(client) != sessions_.end());
sessions_[client]->HandleCommand(method, message, std::move(callback));
}
scoped_refptr<content::DevToolsAgentHost>
HeadlessDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
if (!browser_)
return nullptr;
HeadlessBrowserContext* context = browser_->GetDefaultBrowserContext();
HeadlessWebContentsImpl* web_contents_impl = HeadlessWebContentsImpl::From(
context->CreateWebContentsBuilder()
.SetInitialURL(url)
.SetWindowSize(browser_->options()->window_size)
.Build());
return content::DevToolsAgentHost::GetOrCreateFor(
web_contents_impl->web_contents());
}
std::string HeadlessDevToolsManagerDelegate::GetDiscoveryPageHTML() {
return ui::ResourceBundle::GetSharedInstance()
.GetRawDataResource(IDR_HEADLESS_LIB_DEVTOOLS_DISCOVERY_PAGE)
.as_string();
}
bool HeadlessDevToolsManagerDelegate::HasBundledFrontendResources() {
return true;
}
void HeadlessDevToolsManagerDelegate::ClientAttached(
content::DevToolsAgentHost* agent_host,
content::DevToolsAgentHostClient* client) {
DCHECK(sessions_.find(client) == sessions_.end());
sessions_[client] = std::make_unique<protocol::HeadlessDevToolsSession>(
browser_, agent_host, client);
}
void HeadlessDevToolsManagerDelegate::ClientDetached(
content::DevToolsAgentHost* agent_host,
content::DevToolsAgentHostClient* client) {
sessions_.erase(client);
}
std::vector<content::BrowserContext*>
HeadlessDevToolsManagerDelegate::GetBrowserContexts() {
std::vector<content::BrowserContext*> contexts;
for (auto* context : browser_->GetAllBrowserContexts()) {
if (context != browser_->GetDefaultBrowserContext())
contexts.push_back(HeadlessBrowserContextImpl::From(context));
}
return contexts;
}
content::BrowserContext*
HeadlessDevToolsManagerDelegate::GetDefaultBrowserContext() {
return HeadlessBrowserContextImpl::From(browser_->GetDefaultBrowserContext());
}
content::BrowserContext*
HeadlessDevToolsManagerDelegate::CreateBrowserContext() {
auto builder = browser_->CreateBrowserContextBuilder();
builder.SetIncognitoMode(true);
HeadlessBrowserContext* browser_context = builder.Build();
return HeadlessBrowserContextImpl::From(browser_context);
}
void HeadlessDevToolsManagerDelegate::DisposeBrowserContext(
content::BrowserContext* browser_context,
DisposeCallback callback) {
HeadlessBrowserContextImpl* context =
HeadlessBrowserContextImpl::From(browser_context);
std::vector<HeadlessWebContents*> web_contents = context->GetAllWebContents();
while (!web_contents.empty()) {
for (auto* wc : web_contents)
wc->Close();
// Since HeadlessWebContents::Close spawns a nested run loop to await
// closing, new web_contents could be opened. We need to re-query pages and
// close them too.
web_contents = context->GetAllWebContents();
}
context->Close();
std::move(callback).Run(true, "");
}
} // namespace headless