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

Side by Side Diff: content/browser/devtools/shared_worker_devtools_manager.cc

Issue 223123003: Make DevTools support for the embedded SharedWorker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed version Created 6 years, 8 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 2014 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/shared_worker_devtools_manager.h"
6
7 #include "content/browser/devtools/devtools_manager_impl.h"
8 #include "content/browser/devtools/devtools_protocol.h"
9 #include "content/browser/devtools/devtools_protocol_constants.h"
10 #include "content/browser/devtools/ipc_devtools_agent_host.h"
11 #include "content/browser/shared_worker/shared_worker_instance.h"
12 #include "content/common/devtools_messages.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/worker_service.h"
16 #include "ipc/ipc_listener.h"
17
18 namespace content {
19
20 namespace {
21
22 bool SendMessageToWorker(const SharedWorkerDevToolsManager::WorkerId& worker_id,
23 IPC::Message* message) {
24 RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
25 if (!host) {
26 delete message;
27 return false;
28 }
29 message->set_routing_id(worker_id.second);
30 host->Send(message);
31 return true;
32 }
33
34 } // namespace
35
36 class SharedWorkerDevToolsManager::SharedWorkerDevToolsAgentHost
37 : public IPCDevToolsAgentHost,
38 public IPC::Listener {
39 public:
40 explicit SharedWorkerDevToolsAgentHost(WorkerId worker_id)
41 : worker_id_(worker_id), worker_attached_(true) {
42 AddRef();
43 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
44 host->AddRoute(worker_id_.second, this);
45 }
46
47 // IPCDevToolsAgentHost implementation.
48 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
49 if (worker_attached_)
50 SendMessageToWorker(worker_id_, message);
51 else
52 delete message;
53 }
54 virtual void OnClientAttached() OVERRIDE {}
55 virtual void OnClientDetached() OVERRIDE {}
56
57 // IPC::Listener implementation.
58 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
60 bool handled = true;
61 IPC_BEGIN_MESSAGE_MAP(SharedWorkerDevToolsAgentHost, msg)
62 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
63 OnDispatchOnInspectorFrontend)
64 IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
65 OnSaveAgentRuntimeState)
66 IPC_MESSAGE_UNHANDLED(handled = false)
67 IPC_END_MESSAGE_MAP()
68 return handled;
69 }
70
71 void ReattachToWorker(WorkerId worker_id) {
72 CHECK(!worker_attached_);
73 worker_attached_ = true;
74 worker_id_ = worker_id;
75 AddRef();
76 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
77 host->AddRoute(worker_id_.second, this);
78 Reattach(state_);
79 }
80
81 void DetachFromWorker() {
82 CHECK(worker_attached_);
83 worker_attached_ = false;
84 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
85 host->RemoveRoute(worker_id_.second);
86 Release();
87 }
88
89 WorkerId worker_id() const { return worker_id_; }
90
91 private:
92 virtual ~SharedWorkerDevToolsAgentHost() {
93 CHECK(!worker_attached_);
94 SharedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(this);
95 }
96
97 void OnDispatchOnInspectorFrontend(const std::string& message) {
98 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
99 message);
100 }
101
102 void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
103
104 WorkerId worker_id_;
105 bool worker_attached_;
106 std::string state_;
107 DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsAgentHost);
108 };
109
110 // static
111 SharedWorkerDevToolsManager* SharedWorkerDevToolsManager::GetInstance() {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
113 return Singleton<SharedWorkerDevToolsManager>::get();
114 }
115
116 DevToolsAgentHost* SharedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
117 int worker_process_id,
118 int worker_route_id) {
119 WorkerId id(worker_process_id, worker_route_id);
120
121 WorkerInfoMap::iterator it = workers_.find(id);
122 if (it == workers_.end())
123 return NULL;
124
125 WorkerInfo* info = it->second;
126 if (info->state() != WORKER_UNINSPECTED)
127 return info->agent_host();
128
129 SharedWorkerDevToolsAgentHost* agent_host =
130 new SharedWorkerDevToolsAgentHost(id);
131 info->set_agent_host(agent_host);
132 info->set_state(WORKER_INSPECTED);
133 return agent_host;
134 }
135
136 SharedWorkerDevToolsManager::SharedWorkerDevToolsManager() {}
137
138 SharedWorkerDevToolsManager::~SharedWorkerDevToolsManager() {}
139
140 bool SharedWorkerDevToolsManager::WorkerCreated(
141 int worker_process_id,
142 int worker_route_id,
143 const SharedWorkerInstance& instance) {
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
145 const WorkerId id(worker_process_id, worker_route_id);
146 WorkerInfoMap::iterator it = FindExistingWorkerInfo(instance);
147 if (it == workers_.end()) {
148 scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
149 workers_.set(id, info.Pass());
150 return false;
151 }
152 DCHECK_EQ(WORKER_TERMINATED, it->second->state());
153 scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it);
154 info->set_state(WORKER_PAUSED);
155 workers_.set(id, info.Pass());
156 return true;
157 }
158
159 void SharedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
160 int worker_route_id) {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 const WorkerId id(worker_process_id, worker_route_id);
163 WorkerInfoMap::iterator it = workers_.find(id);
164 DCHECK(it != workers_.end());
165 WorkerInfo* info = it->second;
166 switch (info->state()) {
167 case WORKER_UNINSPECTED:
168 workers_.erase(it);
169 break;
170 case WORKER_INSPECTED: {
171 SharedWorkerDevToolsAgentHost* agent_host = info->agent_host();
172 if (!agent_host->IsAttached()) {
173 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
174 agent_host->DetachFromWorker();
175 return;
176 }
177 info->set_state(WORKER_TERMINATED);
178 // Client host is debugging this worker agent host.
179 std::string notification =
180 DevToolsProtocol::CreateNotification(
181 devtools::Worker::disconnectedFromWorker::kName, NULL)
182 ->Serialize();
183 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
184 agent_host, notification);
185 agent_host->DetachFromWorker();
186 break;
187 }
188 case WORKER_TERMINATED:
189 NOTREACHED();
190 break;
191 case WORKER_PAUSED: {
192 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
193 worker_info->set_state(WORKER_TERMINATED);
194 const WorkerId old_id = worker_info->agent_host()->worker_id();
195 workers_.set(old_id, worker_info.Pass());
196 break;
197 }
198 }
199 }
200
201 void SharedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
202 int worker_route_id) {
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
204 const WorkerId id(worker_process_id, worker_route_id);
205 WorkerInfoMap::iterator it = workers_.find(id);
206 DCHECK(it != workers_.end());
207 WorkerInfo* info = it->second;
208 if (info->state() != WORKER_PAUSED)
209 return;
210 info->agent_host()->ReattachToWorker(id);
211 info->set_state(WORKER_INSPECTED);
212 }
213
214 void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(
215 SharedWorkerDevToolsAgentHost* agent_host) {
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
217 const WorkerId id(agent_host->worker_id());
218 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id);
219 if (worker_info) {
220 DCHECK_EQ(WORKER_TERMINATED, worker_info->state());
221 return;
222 }
223 for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
224 ++it) {
225 if (it->second->agent_host() == agent_host) {
226 DCHECK_EQ(WORKER_PAUSED, it->second->state());
227 SendMessageToWorker(
228 it->first,
229 new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
230 it->second->set_agent_host(NULL);
231 it->second->set_state(WORKER_UNINSPECTED);
232 return;
233 }
234 }
235 }
236
237 SharedWorkerDevToolsManager::WorkerInfoMap::iterator
238 SharedWorkerDevToolsManager::FindExistingWorkerInfo(
239 const SharedWorkerInstance& instance) {
240 WorkerInfoMap::iterator it = workers_.begin();
241 for (; it != workers_.end(); ++it) {
242 if (it->second->instance().Matches(instance))
243 break;
244 }
245 return it;
246 }
247
248 void SharedWorkerDevToolsManager::ResetForTesting() { workers_.clear(); }
249
250 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698