Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: components/web_view/frame_devtools_agent.cc

Issue 1677293002: Bye bye Mandoline (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moar Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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/web_view/frame_devtools_agent.h"
6
7 #include <string.h>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/guid.h"
13 #include "base/json/json_reader.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/values.h"
17 #include "components/web_view/frame_devtools_agent_delegate.h"
18 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
19 #include "mojo/shell/public/cpp/shell.h"
20 #include "url/gurl.h"
21
22 namespace web_view {
23
24 using devtools_service::DevToolsAgentClientPtr;
25 using devtools_service::DevToolsAgentPtr;
26 using devtools_service::DevToolsRegistryPtr;
27
28 using mojo::String;
29
30 namespace {
31
32 void StringToVector(const std::string& in, std::vector<uint8_t>* out) {
33 out->resize(in.size());
34 if (!in.empty())
35 memcpy(&out->front(), in.c_str(), in.size());
36 }
37
38 } // namespace
39
40 // This class is used by FrameDevToolsAgent to relay client messages from the
41 // frame to the DevTools service.
42 class FrameDevToolsAgent::FrameDevToolsAgentClient
43 : public devtools_service::DevToolsAgentClient {
44 public:
45 FrameDevToolsAgentClient(FrameDevToolsAgent* owner,
46 DevToolsAgentClientPtr forward_client)
47 : owner_(owner),
48 binding_(this),
49 forward_client_(std::move(forward_client)) {
50 forward_client_.set_connection_error_handler(base::Bind(
51 &FrameDevToolsAgent::OnForwardClientClosed, base::Unretained(owner_)));
52 if (owner_->forward_agent_)
53 OnAttachedFrame();
54 }
55
56 ~FrameDevToolsAgentClient() override {}
57
58 void OnAttachedFrame() {
59 DCHECK(owner_->forward_agent_);
60
61 if (binding_.is_bound())
62 binding_.Close();
63
64 owner_->forward_agent_->SetClient(binding_.CreateInterfacePtrAndBind());
65 }
66
67 private:
68 // DevToolsAgentClient implementation.
69 void DispatchProtocolMessage(int32_t call_id,
70 const String& message,
71 const String& state) override {
72 DCHECK(forward_client_);
73 owner_->OnReceivedClientMessage(call_id, message, state);
74 // The state is used to persist state across frame navigations. There is no
75 // need to forward it.
76 forward_client_->DispatchProtocolMessage(call_id, message, String());
77 }
78
79 FrameDevToolsAgent* const owner_;
80 mojo::Binding<DevToolsAgentClient> binding_;
81 // The DevToolsAgentClient interface provided by the DevTools service. This
82 // class will forward DevToolsAgentClient method calls it receives to
83 // |forward_client_|.
84 DevToolsAgentClientPtr forward_client_;
85
86 DISALLOW_COPY_AND_ASSIGN(FrameDevToolsAgentClient);
87 };
88
89 FrameDevToolsAgent::FrameDevToolsAgent(mojo::Shell* shell,
90 FrameDevToolsAgentDelegate* delegate)
91 : shell_(shell),
92 delegate_(delegate),
93 id_(base::GenerateGUID()),
94 binding_(this) {
95 DCHECK(shell_);
96 DCHECK(delegate_);
97 }
98
99 FrameDevToolsAgent::~FrameDevToolsAgent() {}
100
101 void FrameDevToolsAgent::AttachFrame(
102 DevToolsAgentPtr forward_agent,
103 Frame::ClientPropertyMap* devtools_properties) {
104 RegisterAgentIfNecessary();
105 forward_agent_ = std::move(forward_agent);
106
107 StringToVector(id_, &(*devtools_properties)["devtools-id"]);
108 if (client_impl_) {
109 StringToVector(state_, &(*devtools_properties)["devtools-state"]);
110 client_impl_->OnAttachedFrame();
111 }
112
113 // This follows Chrome's logic and relies on the fact that call IDs increase
114 // monotonously so iterating over |pending_messages_| preserves the order in
115 // which they were received.
116 for (const auto& item : pending_messages_)
117 forward_agent_->DispatchProtocolMessage(item.second);
118 }
119
120 void FrameDevToolsAgent::RegisterAgentIfNecessary() {
121 if (binding_.is_bound())
122 return;
123
124 DevToolsRegistryPtr devtools_registry;
125 shell_->ConnectToService("mojo:devtools_service", &devtools_registry);
126
127 devtools_registry->RegisterAgent(id_, binding_.CreateInterfacePtrAndBind());
128 }
129
130 void FrameDevToolsAgent::HandlePageNavigateRequest(
131 const base::DictionaryValue* request) {
132 std::string method;
133 if (!request->GetString("method", &method) || method != "Page.navigate")
134 return;
135
136 std::string url_string;
137 if (!request->GetString("params.url", &url_string))
138 return;
139
140 GURL url(url_string);
141 if (!url.is_valid())
142 return;
143
144 // Stop sending messages to the old frame which will be navigated away soon.
145 // However, we don't reset |client_impl_| because we want to receive responses
146 // and events from the old frame in the meantime.
147 forward_agent_.reset();
148
149 delegate_->HandlePageNavigateRequest(url);
150 }
151
152 void FrameDevToolsAgent::SetClient(DevToolsAgentClientPtr client) {
153 client_impl_.reset(new FrameDevToolsAgentClient(this, std::move(client)));
154 }
155
156 void FrameDevToolsAgent::DispatchProtocolMessage(const String& message) {
157 // TODO(yzshen): Consider refactoring and reusing the existing DevTools
158 // protocol parsing code.
159
160 scoped_ptr<base::Value> value = base::JSONReader::Read(message.get());
161 base::DictionaryValue* command = nullptr;
162 if (!value || !value->GetAsDictionary(&command)) {
163 VLOG(1) << "Unable to parse DevTools message: " << message;
164 return;
165 }
166
167 int call_id = -1;
168 if (!command->GetInteger("id", &call_id)) {
169 VLOG(1) << "Call Id not found in a DevTools request message: " << message;
170 return;
171 }
172
173 pending_messages_[call_id] = message;
174
175 HandlePageNavigateRequest(command);
176
177 if (forward_agent_)
178 forward_agent_->DispatchProtocolMessage(message);
179 }
180
181 void FrameDevToolsAgent::OnReceivedClientMessage(int32_t call_id,
182 const String& message,
183 const String& state) {
184 if (!state.is_null() && state.size() > 0)
185 state_ = state;
186
187 pending_messages_.erase(call_id);
188 }
189
190 void FrameDevToolsAgent::OnForwardClientClosed() {
191 client_impl_.reset();
192 state_.clear();
193 pending_messages_.clear();
194 }
195
196 } // namespace web_view
OLDNEW
« no previous file with comments | « components/web_view/frame_devtools_agent.h ('k') | components/web_view/frame_devtools_agent_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698