1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/ui_devtools/devtools_client.h"
6 
7 #include "components/ui_devtools/devtools_server.h"
8 #include "third_party/inspector_protocol/crdtp/dispatch.h"
9 #include "third_party/inspector_protocol/crdtp/json.h"
10 
11 namespace ui_devtools {
12 
UiDevToolsClient(const std::string & name,UiDevToolsServer * server)13 UiDevToolsClient::UiDevToolsClient(const std::string& name,
14                                    UiDevToolsServer* server)
15     : name_(name),
16       connection_id_(kNotConnected),
17       dispatcher_(this),
18       server_(server) {
19   DCHECK(server_);
20 }
21 
~UiDevToolsClient()22 UiDevToolsClient::~UiDevToolsClient() {}
23 
AddAgent(std::unique_ptr<UiDevToolsAgent> agent)24 void UiDevToolsClient::AddAgent(std::unique_ptr<UiDevToolsAgent> agent) {
25   agent->Init(&dispatcher_);
26   agents_.push_back(std::move(agent));
27 }
28 
Disconnect()29 void UiDevToolsClient::Disconnect() {
30   connection_id_ = kNotConnected;
31   DisableAllAgents();
32 }
33 
Dispatch(const std::string & json)34 void UiDevToolsClient::Dispatch(const std::string& json) {
35   std::vector<uint8_t> cbor;
36   crdtp::Status status =
37       crdtp::json::ConvertJSONToCBOR(crdtp::SpanFrom(json), &cbor);
38   if (!status.ok()) {
39     dispatcher_.channel()->SendProtocolNotification(
40         crdtp::CreateErrorNotification(
41             crdtp::DispatchResponse::ParseError(status.ToASCIIString())));
42     return;
43   }
44   crdtp::Dispatchable dispatchable(crdtp::SpanFrom(cbor));
45   if (dispatchable.ok()) {
46     dispatcher_.Dispatch(dispatchable).Run();
47     return;
48   }
49   if (dispatchable.HasCallId()) {
50     dispatcher_.channel()->SendProtocolResponse(
51         dispatchable.CallId(),
52         crdtp::CreateErrorResponse(dispatchable.CallId(),
53                                    dispatchable.DispatchError()));
54   } else {
55     dispatcher_.channel()->SendProtocolNotification(
56         crdtp::CreateErrorNotification(dispatchable.DispatchError()));
57   }
58 }
59 
connected() const60 bool UiDevToolsClient::connected() const {
61   return connection_id_ != kNotConnected;
62 }
63 
set_connection_id(int connection_id)64 void UiDevToolsClient::set_connection_id(int connection_id) {
65   connection_id_ = connection_id;
66 }
67 
name() const68 const std::string& UiDevToolsClient::name() const {
69   return name_;
70 }
71 
DisableAllAgents()72 void UiDevToolsClient::DisableAllAgents() {
73   for (std::unique_ptr<UiDevToolsAgent>& agent : agents_)
74     agent->Disable();
75 }
76 
MaybeSendProtocolResponseOrNotification(std::unique_ptr<protocol::Serializable> message)77 void UiDevToolsClient::MaybeSendProtocolResponseOrNotification(
78     std::unique_ptr<protocol::Serializable> message) {
79   if (!connected())
80     return;
81 
82   std::string json;
83   crdtp::Status status = crdtp::json::ConvertCBORToJSON(
84       crdtp::SpanFrom(message->Serialize()), &json);
85   DCHECK(status.ok());  // CBOR was generated by Chrome, so we expect it's ok.
86   server_->SendOverWebSocket(connection_id_, base::StringPiece(json));
87 }
88 
SendProtocolResponse(int callId,std::unique_ptr<protocol::Serializable> message)89 void UiDevToolsClient::SendProtocolResponse(
90     int callId,
91     std::unique_ptr<protocol::Serializable> message) {
92   MaybeSendProtocolResponseOrNotification(std::move(message));
93 }
94 
SendProtocolNotification(std::unique_ptr<protocol::Serializable> message)95 void UiDevToolsClient::SendProtocolNotification(
96     std::unique_ptr<protocol::Serializable> message) {
97   MaybeSendProtocolResponseOrNotification(std::move(message));
98 }
99 
FlushProtocolNotifications()100 void UiDevToolsClient::FlushProtocolNotifications() {
101   NOTIMPLEMENTED();
102 }
103 
FallThrough(int call_id,crdtp::span<uint8_t> method,crdtp::span<uint8_t> message)104 void UiDevToolsClient::FallThrough(int call_id,
105                                    crdtp::span<uint8_t> method,
106                                    crdtp::span<uint8_t> message) {
107   NOTIMPLEMENTED();
108 }
109 
110 }  // namespace ui_devtools
111