summaryrefslogtreecommitdiff
path: root/chromium/headless/lib/browser/protocol/headless_devtools_session.cc
blob: 4ec24302ef2f6d0be4c3c59e2ff00c2103ea8c8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// 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 "base/command_line.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_agent_host_client.h"
#include "content/public/common/content_switches.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 {
static bool EnableInternalDevToolsBinaryProtocol() {
  static bool disabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
      ::switches::kDisableInternalDevToolsBinaryProtocol);
  return !disabled;
}

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(
    const std::string& method,
    const std::string& message,
    content::DevToolsManagerDelegate::NotHandledCallback callback) {
  if (!browser_ || !dispatcher_->canDispatch(method)) {
    std::move(callback).Run(message);
    return;
  }
  int call_id;
  std::string unused;
  std::unique_ptr<protocol::DictionaryValue> value =
      protocol::DictionaryValue::cast(protocol::StringUtil::parseMessage(
          message, client_->UsesBinaryProtocol() ||
                       EnableInternalDevToolsBinaryProtocol()));
  if (!dispatcher_->parseCommand(value.get(), &call_id, &unused))
    return;
  pending_commands_[call_id] = std::move(callback);
  dispatcher_->dispatch(call_id, method, std::move(value), 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);
  bool binary = client_->UsesBinaryProtocol();
  client_->DispatchProtocolMessage(agent_host_, message->serialize(binary));
}

void HeadlessDevToolsSession::fallThrough(int call_id,
                                          const std::string& method,
                                          const std::string& message) {
  auto callback = std::move(pending_commands_[call_id]);
  pending_commands_.erase(call_id);
  std::move(callback).Run(message);
}

void HeadlessDevToolsSession::sendProtocolNotification(
    std::unique_ptr<Serializable> message) {
  bool binary = client_->UsesBinaryProtocol();
  client_->DispatchProtocolMessage(agent_host_, message->serialize(binary));
}

void HeadlessDevToolsSession::flushProtocolNotifications() {}

}  // namespace protocol
}  // namespace headless