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

Side by Side Diff: content/browser/devtools/protocol/target_handler.cc

Issue 2354973003: [DevTools] Move subtargets functionality from ServiceWorker to Target domain. (Closed)
Patch Set: review comments Created 4 years, 2 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 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 "content/browser/devtools/protocol/target_handler.h"
6
7 #include "content/browser/devtools/service_worker_devtools_agent_host.h"
8 #include "content/browser/frame_host/frame_tree.h"
9 #include "content/browser/frame_host/frame_tree_node.h"
10 #include "content/browser/frame_host/render_frame_host_impl.h"
11
12 namespace content {
13 namespace devtools {
14 namespace target {
15
16 using Response = DevToolsProtocolClient::Response;
17
18 namespace {
19
20 using ScopeAgentsMap =
21 std::map<GURL, std::unique_ptr<ServiceWorkerDevToolsAgentHost::List>>;
22
23 void GetMatchingHostsByScopeMap(
24 const ServiceWorkerDevToolsAgentHost::List& agent_hosts,
25 const std::set<GURL>& urls,
26 ScopeAgentsMap* scope_agents_map) {
27 std::set<base::StringPiece> host_name_set;
28 for (const GURL& url : urls)
29 host_name_set.insert(url.host_piece());
30 for (const auto& host : agent_hosts) {
31 if (host_name_set.find(host->scope().host_piece()) == host_name_set.end())
32 continue;
33 const auto& it = scope_agents_map->find(host->scope());
34 if (it == scope_agents_map->end()) {
35 std::unique_ptr<ServiceWorkerDevToolsAgentHost::List> new_list(
36 new ServiceWorkerDevToolsAgentHost::List());
37 new_list->push_back(host);
38 (*scope_agents_map)[host->scope()] = std::move(new_list);
39 } else {
40 it->second->push_back(host);
41 }
42 }
43 }
44
45 void AddEligibleHosts(const ServiceWorkerDevToolsAgentHost::List& list,
46 ServiceWorkerDevToolsAgentHost::Map* result) {
47 base::Time last_installed_time;
48 base::Time last_doomed_time;
49 for (const auto& host : list) {
50 if (host->version_installed_time() > last_installed_time)
51 last_installed_time = host->version_installed_time();
52 if (host->version_doomed_time() > last_doomed_time)
53 last_doomed_time = host->version_doomed_time();
54 }
55 for (const auto& host : list) {
56 // We don't attech old redundant Service Workers when there is newer
57 // installed Service Worker.
58 if (host->version_doomed_time().is_null() ||
59 (last_installed_time < last_doomed_time &&
60 last_doomed_time == host->version_doomed_time())) {
61 (*result)[host->GetId()] = host;
62 }
63 }
64 }
65
66 ServiceWorkerDevToolsAgentHost::Map GetMatchingServiceWorkers(
67 BrowserContext* browser_context,
68 const std::set<GURL>& urls) {
69 ServiceWorkerDevToolsAgentHost::Map result;
70 if (!browser_context)
71 return result;
72
73 ServiceWorkerDevToolsAgentHost::List agent_hosts;
74 ServiceWorkerDevToolsManager::GetInstance()
75 ->AddAllAgentHostsForBrowserContext(browser_context, &agent_hosts);
76
77 ScopeAgentsMap scope_agents_map;
78 GetMatchingHostsByScopeMap(agent_hosts, urls, &scope_agents_map);
79
80 for (const auto& it : scope_agents_map)
81 AddEligibleHosts(*it.second.get(), &result);
82
83 return result;
84 }
85
86 } // namespace
87
88 TargetHandler::TargetHandler()
89 : enabled_(false),
90 render_frame_host_(nullptr) {
91 }
92
93 TargetHandler::~TargetHandler() {
94 Disable();
95 }
96
97 void TargetHandler::SetRenderFrameHost(RenderFrameHostImpl* render_frame_host) {
98 render_frame_host_ = render_frame_host;
99 }
100
101 void TargetHandler::SetClient(std::unique_ptr<Client> client) {
102 client_.swap(client);
103 }
104
105 void TargetHandler::Detached() {
106 Disable();
107 }
108
109 void TargetHandler::UpdateServiceWorkers() {
110 if (!enabled_)
111 return;
112
113 frame_urls_.clear();
114 BrowserContext* browser_context = nullptr;
115 if (render_frame_host_) {
116 // TODO(dgozman): do not traverse inside cross-process subframes.
117 for (FrameTreeNode* node :
118 render_frame_host_->frame_tree_node()->frame_tree()->Nodes()) {
119 frame_urls_.insert(node->current_url());
120 }
121 browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
122 }
123
124 std::map<std::string, scoped_refptr<DevToolsAgentHost>> old_hosts =
125 attached_hosts_;
126 ServiceWorkerDevToolsAgentHost::Map new_hosts =
127 GetMatchingServiceWorkers(browser_context, frame_urls_);
128
129 for (const auto& pair : old_hosts) {
130 if (pair.second->GetType() == DevToolsAgentHost::kTypeServiceWorker &&
131 new_hosts.find(pair.first) == new_hosts.end()) {
132 DetachFromTargetInternal(pair.second.get());
133 }
134 }
135
136 for (const auto& pair : new_hosts) {
137 if (old_hosts.find(pair.first) == old_hosts.end())
138 AttachToTargetInternal(pair.second.get(), true);
139 }
140 }
141
142 void TargetHandler::AttachToTargetInternal(
143 DevToolsAgentHost* host, bool waiting_for_debugger) {
144 if (host->IsAttached())
145 return;
146 attached_hosts_[host->GetId()] = host;
147 host->AttachClient(this);
148 client_->TargetCreated(TargetCreatedParams::Create()
149 ->set_target_id(host->GetId())
150 ->set_url(host->GetURL().spec())
151 ->set_type(host->GetType())
152 ->set_waiting_for_debugger(waiting_for_debugger));
153 }
154
155 void TargetHandler::DetachFromTargetInternal(DevToolsAgentHost* host) {
156 auto it = attached_hosts_.find(host->GetId());
157 if (it == attached_hosts_.end())
158 return;
159 host->DetachClient(this);
160 client_->TargetRemoved(TargetRemovedParams::Create()->
161 set_target_id(host->GetId()));
162 attached_hosts_.erase(it);
163 }
164
165 // ----------------- Protocol ----------------------
166
167 Response TargetHandler::Enable() {
168 if (enabled_)
169 return Response::OK();
170 enabled_ = true;
171 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this);
172 UpdateServiceWorkers();
173 return Response::OK();
174 }
175
176 Response TargetHandler::Disable() {
177 if (!enabled_)
178 return Response::OK();
179 enabled_ = false;
180 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this);
181 for (const auto& pair : attached_hosts_)
182 pair.second->DetachClient(this);
183 attached_hosts_.clear();
184 return Response::OK();
185 }
186
187 Response TargetHandler::SetWaitForDebuggerOnStart(bool value) {
188 // TODO(dgozman): implement this.
189 return Response::OK();
190 }
191
192 Response TargetHandler::SendMessageToTarget(
193 const std::string& target_id,
194 const std::string& message) {
195 auto it = attached_hosts_.find(target_id);
196 if (it == attached_hosts_.end())
197 return Response::InternalError("Not attached to the target");
198 it->second->DispatchProtocolMessage(this, message);
199 return Response::OK();
200 }
201
202 Response TargetHandler::GetTargetInfo(
203 const std::string& target_id,
204 scoped_refptr<TargetInfo>* target_info) {
205 scoped_refptr<DevToolsAgentHost> agent_host(
206 DevToolsAgentHost::GetForId(target_id));
207 if (!agent_host)
208 return Response::InvalidParams("No target with such id");
209 *target_info =TargetInfo::Create()
210 ->set_target_id(agent_host->GetId())
211 ->set_type(agent_host->GetType())
212 ->set_title(agent_host->GetTitle())
213 ->set_url(agent_host->GetURL().spec());
214 return Response::OK();
215 }
216
217 Response TargetHandler::ActivateTarget(const std::string& target_id) {
218 scoped_refptr<DevToolsAgentHost> agent_host(
219 DevToolsAgentHost::GetForId(target_id));
220 if (!agent_host)
221 return Response::InvalidParams("No target with such id");
222 agent_host->Activate();
223 return Response::OK();
224 }
225
226 // ---------------- DevToolsAgentHostClient ----------------
227
228 void TargetHandler::DispatchProtocolMessage(
229 DevToolsAgentHost* host,
230 const std::string& message) {
231 auto it = attached_hosts_.find(host->GetId());
232 if (it == attached_hosts_.end())
233 return; // Already disconnected.
234
235 client_->ReceivedMessageFromTarget(
236 ReceivedMessageFromTargetParams::Create()->
237 set_target_id(host->GetId())->
238 set_message(message));
239 }
240
241 void TargetHandler::AgentHostClosed(
242 DevToolsAgentHost* host,
243 bool replaced_with_another_client) {
244 client_->TargetRemoved(TargetRemovedParams::Create()->
245 set_target_id(host->GetId()));
246 attached_hosts_.erase(host->GetId());
247 }
248
249 // -------- ServiceWorkerDevToolsManager::Observer ----------
250
251 void TargetHandler::WorkerCreated(
252 ServiceWorkerDevToolsAgentHost* host) {
253 BrowserContext* browser_context = nullptr;
254 if (render_frame_host_)
255 browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
256 auto hosts = GetMatchingServiceWorkers(browser_context, frame_urls_);
257 if (hosts.find(host->GetId()) != hosts.end() && !host->IsAttached() &&
258 !host->IsPausedForDebugOnStart()) {
259 host->PauseForDebugOnStart();
260 }
261 }
262
263 void TargetHandler::WorkerReadyForInspection(
264 ServiceWorkerDevToolsAgentHost* host) {
265 if (ServiceWorkerDevToolsManager::GetInstance()
266 ->debug_service_worker_on_start()) {
267 // When debug_service_worker_on_start is true, a new DevTools window will
268 // be opened in ServiceWorkerDevToolsManager::WorkerReadyForInspection.
269 return;
270 }
271 UpdateServiceWorkers();
272 }
273
274 void TargetHandler::WorkerVersionInstalled(
275 ServiceWorkerDevToolsAgentHost* host) {
276 UpdateServiceWorkers();
277 }
278
279 void TargetHandler::WorkerVersionDoomed(
280 ServiceWorkerDevToolsAgentHost* host) {
281 UpdateServiceWorkers();
282 }
283
284 void TargetHandler::WorkerDestroyed(
285 ServiceWorkerDevToolsAgentHost* host) {
286 UpdateServiceWorkers();
287 }
288
289 } // namespace target
290 } // namespace devtools
291 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/target_handler.h ('k') | content/browser/devtools/render_frame_devtools_agent_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698