| // Copyright 2018 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/protocol/headless_devtools_session.h" |
| |
| #include "content/public/browser/devtools_agent_host.h" |
| #include "content/public/browser/devtools_agent_host_client.h" |
| #include "headless/lib/browser/protocol/browser_handler.h" |
| #include "headless/lib/browser/protocol/headless_handler.h" |
| #include "headless/lib/browser/protocol/page_handler.h" |
| #include "headless/lib/browser/protocol/target_handler.h" |
| |
| namespace headless { |
| namespace protocol { |
| |
| HeadlessDevToolsSession::HeadlessDevToolsSession( |
| base::WeakPtr<HeadlessBrowserImpl> browser, |
| content::DevToolsAgentHost* agent_host, |
| content::DevToolsAgentHostClient* client) |
| : browser_(browser), |
| agent_host_(agent_host), |
| client_(client), |
| dispatcher_(std::make_unique<UberDispatcher>(this)) { |
| if (agent_host->GetWebContents() && |
| agent_host->GetType() == content::DevToolsAgentHost::kTypePage) { |
| AddHandler(std::make_unique<HeadlessHandler>(browser_, |
| agent_host->GetWebContents())); |
| AddHandler( |
| std::make_unique<PageHandler>(browser_, agent_host->GetWebContents())); |
| } |
| if (client->MayAttachToBrowser()) |
| AddHandler(std::make_unique<BrowserHandler>(browser_, agent_host->GetId())); |
| AddHandler(std::make_unique<TargetHandler>(browser_)); |
| } |
| |
| HeadlessDevToolsSession::~HeadlessDevToolsSession() { |
| dispatcher_.reset(); |
| for (auto& pair : handlers_) |
| pair.second->Disable(); |
| handlers_.clear(); |
| } |
| |
| void HeadlessDevToolsSession::HandleCommand( |
| std::unique_ptr<base::DictionaryValue> command, |
| const std::string& message, |
| content::DevToolsManagerDelegate::NotHandledCallback callback) { |
| if (!browser_) { |
| std::move(callback).Run(std::move(command), message); |
| return; |
| } |
| int call_id; |
| std::string method; |
| std::unique_ptr<protocol::Value> protocolCommand = |
| protocol::toProtocolValue(command.get(), 1000); |
| if (!dispatcher_->parseCommand(protocolCommand.get(), &call_id, &method)) { |
| return; |
| } |
| if (dispatcher_->canDispatch(method)) { |
| pending_commands_[call_id] = |
| std::make_pair(std::move(callback), std::move(command)); |
| dispatcher_->dispatch(call_id, method, std::move(protocolCommand), message); |
| return; |
| } |
| std::move(callback).Run(std::move(command), message); |
| } |
| void HeadlessDevToolsSession::AddHandler( |
| std::unique_ptr<protocol::DomainHandler> handler) { |
| handler->Wire(dispatcher_.get()); |
| handlers_[handler->name()] = std::move(handler); |
| } |
| |
| void HeadlessDevToolsSession::sendProtocolResponse( |
| int call_id, |
| std::unique_ptr<Serializable> message) { |
| pending_commands_.erase(call_id); |
| client_->DispatchProtocolMessage(agent_host_, message->serialize()); |
| } |
| |
| void HeadlessDevToolsSession::fallThrough(int call_id, |
| const std::string& method, |
| const std::string& message) { |
| PendingCommand command = std::move(pending_commands_[call_id]); |
| pending_commands_.erase(call_id); |
| std::move(command.first).Run(std::move(command.second), message); |
| } |
| |
| void HeadlessDevToolsSession::sendProtocolNotification( |
| std::unique_ptr<Serializable> message) { |
| client_->DispatchProtocolMessage(agent_host_, message->serialize()); |
| } |
| |
| void HeadlessDevToolsSession::flushProtocolNotifications() {} |
| |
| } // namespace protocol |
| } // namespace headless |