OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/embedded_worker_instance.h" | 5 #include "content/browser/service_worker/embedded_worker_instance.h" |
6 | 6 |
7 #include "content/browser/devtools/embedded_worker_devtools_manager.h" | |
7 #include "content/browser/service_worker/embedded_worker_registry.h" | 8 #include "content/browser/service_worker/embedded_worker_registry.h" |
8 #include "content/common/service_worker/embedded_worker_messages.h" | 9 #include "content/common/service_worker/embedded_worker_messages.h" |
10 #include "content/public/browser/browser_thread.h" | |
11 #include "content/public/browser/render_process_host.h" | |
9 #include "ipc/ipc_message.h" | 12 #include "ipc/ipc_message.h" |
10 #include "url/gurl.h" | 13 #include "url/gurl.h" |
11 | 14 |
12 namespace content { | 15 namespace content { |
13 | 16 |
14 namespace { | 17 namespace { |
kinuko
2014/05/08 11:17:31
nit: can we have an empty line (to match the end o
horo
2014/05/08 14:17:46
Done.
| |
15 // Functor to sort by the .second element of a struct. | 18 // Functor to sort by the .second element of a struct. |
16 struct SecondGreater { | 19 struct SecondGreater { |
17 template <typename Value> | 20 template <typename Value> |
18 bool operator()(const Value& lhs, const Value& rhs) { | 21 bool operator()(const Value& lhs, const Value& rhs) { |
19 return lhs.second > rhs.second; | 22 return lhs.second > rhs.second; |
20 } | 23 } |
21 }; | 24 }; |
25 | |
26 void RegisterToDevToolsManagerOnUI( | |
27 int process_id, | |
28 const base::FilePath& storage_partition_path, | |
29 const GURL& scope, | |
30 const base::Callback<void(int worker_devtools_agent_route_id, | |
31 bool pause_on_start)>& callback) { | |
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
33 int worker_devtools_agent_route_id = MSG_ROUTING_NONE; | |
34 bool pause_on_start = false; | |
35 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) { | |
36 // |rph| may be NULL in unit tests. | |
37 worker_devtools_agent_route_id = rph->GetNextRoutingID(); | |
38 pause_on_start = | |
39 EmbeddedWorkerDevToolsManager::GetInstance()->ServiceWorkerCreated( | |
40 process_id, | |
41 worker_devtools_agent_route_id, | |
42 storage_partition_path, | |
43 scope); | |
44 } | |
45 BrowserThread::PostTask( | |
46 BrowserThread::IO, | |
47 FROM_HERE, | |
48 base::Bind(callback, worker_devtools_agent_route_id, pause_on_start)); | |
49 } | |
50 | |
51 void NotifyWorkerContextStartedOnUI(int worker_process_id, | |
52 int worker_route_id) { | |
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
54 EmbeddedWorkerDevToolsManager::GetInstance()->WorkerContextStarted( | |
55 worker_process_id, worker_route_id); | |
56 } | |
57 | |
58 void NotifyWorkerDestroyedOnUI(int worker_process_id, int worker_route_id) { | |
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
60 EmbeddedWorkerDevToolsManager::GetInstance()->WorkerDestroyed( | |
61 worker_process_id, worker_route_id); | |
62 } | |
63 | |
22 } // namespace | 64 } // namespace |
23 | 65 |
66 EmbeddedWorkerInstance::DevToolsManagerBridge::DevToolsManagerBridge( | |
67 int embedded_worker_id, | |
68 const base::FilePath& storage_partition_path) | |
69 : embedded_worker_id_(embedded_worker_id), | |
70 storage_partition_path_(storage_partition_path), | |
71 worker_process_id_(-1), | |
72 worker_devtools_agent_route_id_(MSG_ROUTING_NONE) { | |
73 } | |
74 | |
75 EmbeddedWorkerInstance::DevToolsManagerBridge::~DevToolsManagerBridge() { | |
76 } | |
77 | |
78 void EmbeddedWorkerInstance::DevToolsManagerBridge::RegisterToDevToolsManager( | |
79 int process_id, | |
80 const base::Callback<void(int worker_devtools_agent_route_id, | |
81 bool pause_on_start)>& callback) { | |
82 worker_process_id_ = process_id; | |
83 BrowserThread::PostTask( | |
84 BrowserThread::UI, | |
85 FROM_HERE, | |
86 base::Bind( | |
87 RegisterToDevToolsManagerOnUI, | |
88 worker_process_id_, | |
89 storage_partition_path_, | |
90 scope_, | |
91 base::Bind( | |
92 &DevToolsManagerBridge::RegisteredCallback, this, callback))); | |
93 } | |
94 | |
95 void EmbeddedWorkerInstance::DevToolsManagerBridge::RegisteredCallback( | |
96 const base::Callback<void(int worker_devtools_agent_route_id, | |
97 bool pause_on_start)>& callback, | |
98 int worker_devtools_agent_route_id, | |
99 bool pause_on_start) { | |
100 worker_devtools_agent_route_id_ = worker_devtools_agent_route_id; | |
101 callback.Run(worker_devtools_agent_route_id, pause_on_start); | |
102 } | |
103 | |
104 void EmbeddedWorkerInstance::DevToolsManagerBridge::OnStarted() { | |
105 } | |
106 | |
107 void EmbeddedWorkerInstance::DevToolsManagerBridge::OnStopped() { | |
108 if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE) { | |
109 BrowserThread::PostTask(BrowserThread::UI, | |
110 FROM_HERE, | |
111 base::Bind(NotifyWorkerDestroyedOnUI, | |
112 worker_process_id_, | |
113 worker_devtools_agent_route_id_)); | |
114 } | |
115 } | |
116 void EmbeddedWorkerInstance::DevToolsManagerBridge::OnScriptLoaded() { | |
117 if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE) { | |
118 BrowserThread::PostTask(BrowserThread::UI, | |
119 FROM_HERE, | |
120 base::Bind(NotifyWorkerContextStartedOnUI, | |
121 worker_process_id_, | |
122 worker_devtools_agent_route_id_)); | |
123 } | |
124 } | |
125 | |
126 bool EmbeddedWorkerInstance::DevToolsManagerBridge::OnMessageReceived( | |
127 const IPC::Message& message) { | |
128 return false; | |
129 } | |
130 | |
24 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() { | 131 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() { |
132 RemoveListener(dev_tools_manager_bridge_.get()); | |
kinuko
2014/05/08 11:17:31
nit: doesn't feel it's necessary
horo
2014/05/08 14:17:46
Done.
| |
25 registry_->RemoveWorker(process_id_, embedded_worker_id_); | 133 registry_->RemoveWorker(process_id_, embedded_worker_id_); |
26 } | 134 } |
27 | 135 |
28 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id, | 136 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id, |
29 const GURL& scope, | 137 const GURL& scope, |
30 const GURL& script_url, | 138 const GURL& script_url, |
31 const std::vector<int>& possible_process_ids, | 139 const std::vector<int>& possible_process_ids, |
32 const StatusCallback& callback) { | 140 const StatusCallback& callback) { |
33 DCHECK(status_ == STOPPED); | 141 DCHECK(status_ == STOPPED); |
142 dev_tools_manager_bridge_->set_scope(scope); | |
kinuko
2014/05/08 11:17:31
Looks like the scope can be given to ctor of Embed
horo
2014/05/08 14:17:46
Done.
| |
34 status_ = STARTING; | 143 status_ = STARTING; |
35 std::vector<int> ordered_process_ids = SortProcesses(possible_process_ids); | 144 std::vector<int> ordered_process_ids = SortProcesses(possible_process_ids); |
36 registry_->StartWorker(ordered_process_ids, | 145 registry_->StartWorker(ordered_process_ids, |
37 embedded_worker_id_, | 146 embedded_worker_id_, |
38 service_worker_version_id, | 147 service_worker_version_id, |
39 scope, | 148 scope, |
40 script_url, | 149 script_url, |
41 callback); | 150 callback); |
42 } | 151 } |
43 | 152 |
(...skipping 24 matching lines...) Expand all Loading... | |
68 void EmbeddedWorkerInstance::ReleaseProcessReference(int process_id) { | 177 void EmbeddedWorkerInstance::ReleaseProcessReference(int process_id) { |
69 ProcessRefMap::iterator found = process_refs_.find(process_id); | 178 ProcessRefMap::iterator found = process_refs_.find(process_id); |
70 if (found == process_refs_.end()) { | 179 if (found == process_refs_.end()) { |
71 NOTREACHED() << "Releasing unknown process ref " << process_id; | 180 NOTREACHED() << "Releasing unknown process ref " << process_id; |
72 return; | 181 return; |
73 } | 182 } |
74 if (--found->second == 0) | 183 if (--found->second == 0) |
75 process_refs_.erase(found); | 184 process_refs_.erase(found); |
76 } | 185 } |
77 | 186 |
78 EmbeddedWorkerInstance::EmbeddedWorkerInstance(EmbeddedWorkerRegistry* registry, | 187 EmbeddedWorkerInstance::EmbeddedWorkerInstance( |
79 int embedded_worker_id) | 188 EmbeddedWorkerRegistry* registry, |
189 int embedded_worker_id, | |
190 const base::FilePath& storage_partition_path) | |
80 : registry_(registry), | 191 : registry_(registry), |
81 embedded_worker_id_(embedded_worker_id), | 192 embedded_worker_id_(embedded_worker_id), |
82 status_(STOPPED), | 193 status_(STOPPED), |
83 process_id_(-1), | 194 process_id_(-1), |
84 thread_id_(-1), | 195 thread_id_(-1), |
85 worker_devtools_agent_route_id_(MSG_ROUTING_NONE) { | 196 worker_devtools_agent_route_id_(MSG_ROUTING_NONE), |
197 dev_tools_manager_bridge_( | |
198 new DevToolsManagerBridge(embedded_worker_id, | |
199 storage_partition_path)) { | |
kinuko
2014/05/08 11:17:31
nit: you can get this via registry ptr here rather
horo
2014/05/08 14:17:46
Done.
Added EmbeddedWorkerRegistry::storage_partit
| |
200 AddListener(dev_tools_manager_bridge_.get()); | |
86 } | 201 } |
87 | 202 |
88 void EmbeddedWorkerInstance::RecordProcessId( | 203 void EmbeddedWorkerInstance::WorkerProcessAllocated( |
89 int process_id, | 204 int process_id, |
90 ServiceWorkerStatusCode status, | 205 const base::Callback<void(int worker_devtools_agent_route_id, |
91 int worker_devtools_agent_route_id) { | 206 bool pause_on_start)>& callback) { |
92 DCHECK_EQ(process_id_, -1); | 207 DCHECK_EQ(process_id_, -1); |
93 DCHECK_EQ(worker_devtools_agent_route_id_, MSG_ROUTING_NONE); | 208 process_id_ = process_id; |
94 if (status == SERVICE_WORKER_OK) { | 209 dev_tools_manager_bridge_->RegisterToDevToolsManager(process_id, callback); |
95 process_id_ = process_id; | 210 } |
96 worker_devtools_agent_route_id_ = worker_devtools_agent_route_id; | 211 |
97 } else { | 212 void EmbeddedWorkerInstance::WorkerProcessAllocationFailed() { |
98 status_ = STOPPED; | 213 DCHECK_EQ(process_id_, -1); |
99 } | 214 status_ = STOPPED; |
100 } | 215 } |
101 | 216 |
102 void EmbeddedWorkerInstance::OnScriptLoaded() { | 217 void EmbeddedWorkerInstance::OnScriptLoaded() { |
103 // TODO(horo): Implement this. | 218 FOR_EACH_OBSERVER(Listener, listener_list_, OnScriptLoaded()); |
104 } | 219 } |
105 | 220 |
106 void EmbeddedWorkerInstance::OnScriptLoadFailed() { | 221 void EmbeddedWorkerInstance::OnScriptLoadFailed() { |
107 } | 222 } |
108 | 223 |
109 void EmbeddedWorkerInstance::OnStarted(int thread_id) { | 224 void EmbeddedWorkerInstance::OnStarted(int thread_id) { |
110 // Stop is requested before OnStarted is sent back from the worker. | 225 // Stop is requested before OnStarted is sent back from the worker. |
111 if (status_ == STOPPING) | 226 if (status_ == STOPPING) |
112 return; | 227 return; |
113 DCHECK(status_ == STARTING); | 228 DCHECK(status_ == STARTING); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 // Sort descending by the reference count. | 296 // Sort descending by the reference count. |
182 std::sort(counted.begin(), counted.end(), SecondGreater()); | 297 std::sort(counted.begin(), counted.end(), SecondGreater()); |
183 | 298 |
184 std::vector<int> result(counted.size()); | 299 std::vector<int> result(counted.size()); |
185 for (size_t i = 0; i < counted.size(); ++i) | 300 for (size_t i = 0; i < counted.size(); ++i) |
186 result[i] = counted[i].first; | 301 result[i] = counted[i].first; |
187 return result; | 302 return result; |
188 } | 303 } |
189 | 304 |
190 } // namespace content | 305 } // namespace content |
OLD | NEW |