blob: aabbf40c43126a6ddce4210659bfabe497548df7 [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 "content/browser/devtools/protocol/browser_handler.h"
#include <algorithm>
#include "base/bind.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/public/browser/devtools_manager_delegate.h"
namespace content {
namespace devtools {
namespace browser {
using Response = DevToolsProtocolClient::Response;
BrowserHandler::BrowserHandler()
: weak_factory_(this) {
}
BrowserHandler::~BrowserHandler() {
}
void BrowserHandler::SetClient(std::unique_ptr<Client> client) {
client_.swap(client);
}
void BrowserHandler::Detached() {
for (const auto& host : attached_hosts_)
host->DetachClient(this);
attached_hosts_.clear();
}
Response BrowserHandler::CreateBrowserContext(std::string* out_context_id) {
// For layering reasons this needs to be handled by
// DevToolsManagerDelegate::HandleCommand.
return Response::ServerError("Not supported");
}
Response BrowserHandler::DisposeBrowserContext(const std::string& context_id,
bool* out_success) {
// For layering reasons this needs to be handled by
// DevToolsManagerDelegate::HandleCommand.
return Response::ServerError("Not supported");
}
Response BrowserHandler::CreateTarget(const std::string& url,
const int* width,
const int* height,
const std::string* context_id,
std::string* out_target_id) {
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
if (!delegate)
return Response::ServerError("Not supported");
scoped_refptr<content::DevToolsAgentHost> agent_host =
delegate->CreateNewTarget(GURL(url));
if (!agent_host)
return Response::ServerError("Not supported");
*out_target_id = agent_host->GetId();
return Response::OK();
}
Response BrowserHandler::CloseTarget(const std::string& target_id,
bool* out_success) {
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host)
return Response::ServerError("No target with given id found");
*out_success = agent_host->Close();
return Response::OK();
}
Response BrowserHandler::GetTargets(DevToolsCommandId command_id) {
DevToolsAgentHost::DiscoverAllHosts(
base::Bind(&BrowserHandler::RespondToGetTargets,
weak_factory_.GetWeakPtr(),
command_id));
return Response::OK();
}
void BrowserHandler::RespondToGetTargets(
DevToolsCommandId command_id,
DevToolsAgentHost::List agents) {
std::vector<scoped_refptr<devtools::browser::TargetInfo>> infos;
for (const auto& agent_host : agents) {
scoped_refptr<devtools::browser::TargetInfo> info =
devtools::browser::TargetInfo::Create()->
set_target_id(agent_host->GetId())->
set_type(agent_host->GetType())->
set_title(agent_host->GetTitle())->
set_url(agent_host->GetURL().spec());
infos.push_back(info);
}
client_->SendGetTargetsResponse(
command_id,
GetTargetsResponse::Create()->set_target_info(std::move(infos)));
}
Response BrowserHandler::Attach(DevToolsCommandId command_id,
const std::string& target_id) {
// Discover in order to get ahold of the items.
DevToolsAgentHost::DiscoverAllHosts(
base::Bind(&BrowserHandler::RespondToAttach,
weak_factory_.GetWeakPtr(), command_id, target_id));
return Response::OK();
}
void BrowserHandler::RespondToAttach(DevToolsCommandId command_id,
const std::string& target_id,
DevToolsAgentHost::List agents) {
// We were discovering to get ahold of the items, discard them.
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
bool success = false;
if (agent_host)
success = agent_host->AttachClient(this);
attached_hosts_.push_back(agent_host);
client_->SendAttachResponse(
command_id,
AttachResponse::Create()->set_success(success));
}
Response BrowserHandler::Detach(const std::string& target_id,
bool* out_success) {
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
auto it = std::find(
attached_hosts_.begin(), attached_hosts_.end(), agent_host);
if (it != attached_hosts_.end())
attached_hosts_.erase(it);
*out_success = agent_host && agent_host->DetachClient(this);
return Response::OK();
}
Response BrowserHandler::SendMessage(const std::string& target_id,
const std::string& message) {
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host)
return Response::ServerError("No target with given id found");
agent_host->DispatchProtocolMessage(this, message);
return Response::OK();
}
Response BrowserHandler::SetRemoteLocations(
const std::vector<std::unique_ptr<base::DictionaryValue>>& locations) {
return Response::OK();
}
void BrowserHandler::DispatchProtocolMessage(
DevToolsAgentHost* agent_host, const std::string& message) {
client_->DispatchMessage(DispatchMessageParams::Create()->
set_target_id(agent_host->GetId())->
set_message(message));
}
void BrowserHandler::AgentHostClosed(DevToolsAgentHost* agent_host,
bool replaced_with_another_client) {
auto it = std::find(
attached_hosts_.begin(), attached_hosts_.end(), agent_host);
if (it != attached_hosts_.end())
attached_hosts_.erase(it);
}
} // namespace browser
} // namespace devtools
} // namespace content