OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "mojo/shell/application_manager.h" | 5 #include "mojo/shell/application_manager.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 InitPackageManager(register_mojo_url_schemes); | 91 InitPackageManager(register_mojo_url_schemes); |
92 } | 92 } |
93 | 93 |
94 ApplicationManager::~ApplicationManager() { | 94 ApplicationManager::~ApplicationManager() { |
95 TerminateShellConnections(); | 95 TerminateShellConnections(); |
96 STLDeleteValues(&url_to_loader_); | 96 STLDeleteValues(&url_to_loader_); |
97 for (auto& runner : native_runners_) | 97 for (auto& runner : native_runners_) |
98 runner.reset(); | 98 runner.reset(); |
99 } | 99 } |
100 | 100 |
| 101 void ApplicationManager::SetInstanceQuitCallback( |
| 102 base::Callback<void(const Identity&)> callback) { |
| 103 instance_quit_callback_ = callback; |
| 104 } |
| 105 |
101 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { | 106 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { |
102 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", | 107 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", |
103 TRACE_EVENT_SCOPE_THREAD, "original_url", | 108 TRACE_EVENT_SCOPE_THREAD, "original_url", |
104 params->target().url().spec()); | 109 params->target().url().spec()); |
105 DCHECK(params->target().url().is_valid()); | 110 DCHECK(params->target().url().is_valid()); |
106 | 111 |
107 // Connect to an existing matching instance, if possible. | 112 // Connect to an existing matching instance, if possible. |
108 if (ConnectToInstance(¶ms)) | 113 if (ConnectToInstance(¶ms)) |
109 return; | 114 return; |
110 | 115 |
(...skipping 11 matching lines...) Expand all Loading... |
122 delete it->second; | 127 delete it->second; |
123 url_to_loader_[url] = loader.release(); | 128 url_to_loader_[url] = loader.release(); |
124 } | 129 } |
125 | 130 |
126 void ApplicationManager::TerminateShellConnections() { | 131 void ApplicationManager::TerminateShellConnections() { |
127 STLDeleteValues(&identity_to_instance_); | 132 STLDeleteValues(&identity_to_instance_); |
128 } | 133 } |
129 | 134 |
130 void ApplicationManager::OnApplicationInstanceError( | 135 void ApplicationManager::OnApplicationInstanceError( |
131 ApplicationInstance* instance) { | 136 ApplicationInstance* instance) { |
132 // Called from ~ApplicationInstance, so we do not need to call Destroy here. | |
133 const Identity identity = instance->identity(); | 137 const Identity identity = instance->identity(); |
134 base::Closure on_application_end = instance->on_application_end(); | |
135 // Remove the shell. | 138 // Remove the shell. |
136 auto it = identity_to_instance_.find(identity); | 139 auto it = identity_to_instance_.find(identity); |
137 DCHECK(it != identity_to_instance_.end()); | 140 DCHECK(it != identity_to_instance_.end()); |
138 int id = instance->id(); | 141 int id = instance->id(); |
139 delete it->second; | 142 delete it->second; |
140 identity_to_instance_.erase(it); | 143 identity_to_instance_.erase(it); |
141 listeners_.ForAllPtrs( | 144 listeners_.ForAllPtrs( |
142 [this, id](mojom::ApplicationManagerListener* listener) { | 145 [this, id](mojom::ApplicationManagerListener* listener) { |
143 listener->ApplicationInstanceDestroyed(id); | 146 listener->ApplicationInstanceDestroyed(id); |
144 }); | 147 }); |
145 if (!on_application_end.is_null()) | 148 if (!instance_quit_callback_.is_null()) |
146 on_application_end.Run(); | 149 instance_quit_callback_.Run(identity); |
147 } | 150 } |
148 | 151 |
149 ApplicationInstance* ApplicationManager::GetApplicationInstance( | 152 ApplicationInstance* ApplicationManager::GetApplicationInstance( |
150 const Identity& identity) const { | 153 const Identity& identity) const { |
151 const auto& it = identity_to_instance_.find(identity); | 154 const auto& it = identity_to_instance_.find(identity); |
152 return it != identity_to_instance_.end() ? it->second : nullptr; | 155 return it != identity_to_instance_.end() ? it->second : nullptr; |
153 } | 156 } |
154 | 157 |
155 void ApplicationManager::ApplicationPIDAvailable( | 158 void ApplicationManager::ApplicationPIDAvailable( |
156 uint32_t id, | 159 uint32_t id, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 mojom::CapabilityFilterPtr filter, | 196 mojom::CapabilityFilterPtr filter, |
194 mojom::PIDReceiverRequest pid_receiver) { | 197 mojom::PIDReceiverRequest pid_receiver) { |
195 // We don't call ConnectToClient() here since the instance was created | 198 // We don't call ConnectToClient() here since the instance was created |
196 // manually by other code, not in response to a Connect() request. The newly | 199 // manually by other code, not in response to a Connect() request. The newly |
197 // created instance is identified by |url| and may be subsequently reached by | 200 // created instance is identified by |url| and may be subsequently reached by |
198 // client code using this identity. | 201 // client code using this identity. |
199 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); | 202 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); |
200 Identity target_id(url.To<GURL>(), std::string(), local_filter); | 203 Identity target_id(url.To<GURL>(), std::string(), local_filter); |
201 mojom::ShellClientRequest request; | 204 mojom::ShellClientRequest request; |
202 // TODO(beng): do better than url.spec() for application name. | 205 // TODO(beng): do better than url.spec() for application name. |
203 ApplicationInstance* instance = | 206 ApplicationInstance* instance = CreateInstance(target_id, url, &request); |
204 CreateInstance(target_id, base::Closure(), url, &request); | |
205 instance->BindPIDReceiver(std::move(pid_receiver)); | 207 instance->BindPIDReceiver(std::move(pid_receiver)); |
206 scoped_ptr<NativeRunner> runner = | 208 scoped_ptr<NativeRunner> runner = |
207 native_runner_factory_->Create(base::FilePath()); | 209 native_runner_factory_->Create(base::FilePath()); |
208 runner->InitHost(std::move(channel), std::move(request)); | 210 runner->InitHost(std::move(channel), std::move(request)); |
209 instance->SetNativeRunner(runner.get()); | 211 instance->SetNativeRunner(runner.get()); |
210 native_runners_.push_back(std::move(runner)); | 212 native_runners_.push_back(std::move(runner)); |
211 } | 213 } |
212 | 214 |
213 void ApplicationManager::AddListener( | 215 void ApplicationManager::AddListener( |
214 mojom::ApplicationManagerListenerPtr listener) { | 216 mojom::ApplicationManagerListenerPtr listener) { |
215 Array<mojom::ApplicationInfoPtr> applications; | 217 Array<mojom::ApplicationInfoPtr> applications; |
216 for (auto& entry : identity_to_instance_) | 218 for (auto& entry : identity_to_instance_) |
217 applications.push_back(CreateApplicationInfoForInstance(entry.second)); | 219 applications.push_back(CreateApplicationInfoForInstance(entry.second)); |
218 listener->SetRunningApplications(std::move(applications)); | 220 listener->SetRunningApplications(std::move(applications)); |
219 | 221 |
220 listeners_.AddInterfacePtr(std::move(listener)); | 222 listeners_.AddInterfacePtr(std::move(listener)); |
221 } | 223 } |
222 | 224 |
223 //////////////////////////////////////////////////////////////////////////////// | 225 //////////////////////////////////////////////////////////////////////////////// |
224 // ApplicationManager, private: | 226 // ApplicationManager, private: |
225 | 227 |
226 void ApplicationManager::InitPackageManager(bool register_mojo_url_schemes) { | 228 void ApplicationManager::InitPackageManager(bool register_mojo_url_schemes) { |
227 scoped_ptr<ApplicationLoader> loader( | 229 scoped_ptr<ApplicationLoader> loader( |
228 new package_manager::Loader(task_runner_, register_mojo_url_schemes)); | 230 new package_manager::Loader(task_runner_, register_mojo_url_schemes)); |
229 | 231 |
230 mojom::ShellClientRequest request; | 232 mojom::ShellClientRequest request; |
231 GURL url("mojo://package_manager/"); | 233 GURL url("mojo://package_manager/"); |
232 CreateInstance(Identity(url), base::Closure(), url.spec(), &request); | 234 CreateInstance(Identity(url), url.spec(), &request); |
233 loader->Load(url, std::move(request)); | 235 loader->Load(url, std::move(request)); |
234 | 236 |
235 SetLoaderForURL(std::move(loader), url); | 237 SetLoaderForURL(std::move(loader), url); |
236 | 238 |
237 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); | 239 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); |
238 } | 240 } |
239 | 241 |
240 bool ApplicationManager::ConnectToInstance(scoped_ptr<ConnectParams>* params) { | 242 bool ApplicationManager::ConnectToInstance(scoped_ptr<ConnectParams>* params) { |
241 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); | 243 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); |
242 if (!instance) | 244 if (!instance) |
243 return false; | 245 return false; |
244 instance->ConnectToClient(std::move(*params)); | 246 instance->ConnectToClient(std::move(*params)); |
245 return true; | 247 return true; |
246 } | 248 } |
247 | 249 |
248 ApplicationInstance* ApplicationManager::CreateInstance( | 250 ApplicationInstance* ApplicationManager::CreateInstance( |
249 const Identity& target_id, | 251 const Identity& target_id, |
250 const base::Closure& on_application_end, | |
251 const String& application_name, | 252 const String& application_name, |
252 mojom::ShellClientRequest* request) { | 253 mojom::ShellClientRequest* request) { |
253 mojom::ShellClientPtr shell_client; | 254 mojom::ShellClientPtr shell_client; |
254 *request = GetProxy(&shell_client); | 255 *request = GetProxy(&shell_client); |
255 ApplicationInstance* instance = new ApplicationInstance( | 256 ApplicationInstance* instance = new ApplicationInstance( |
256 std::move(shell_client), this, target_id, on_application_end, | 257 std::move(shell_client), this, target_id, application_name); |
257 application_name); | |
258 DCHECK(identity_to_instance_.find(target_id) == | 258 DCHECK(identity_to_instance_.find(target_id) == |
259 identity_to_instance_.end()); | 259 identity_to_instance_.end()); |
260 identity_to_instance_[target_id] = instance; | 260 identity_to_instance_[target_id] = instance; |
261 mojom::ApplicationInfoPtr application_info = | 261 mojom::ApplicationInfoPtr application_info = |
262 CreateApplicationInfoForInstance(instance); | 262 CreateApplicationInfoForInstance(instance); |
263 listeners_.ForAllPtrs( | 263 listeners_.ForAllPtrs( |
264 [this, &application_info](mojom::ApplicationManagerListener* listener) { | 264 [this, &application_info](mojom::ApplicationManagerListener* listener) { |
265 listener->ApplicationInstanceCreated(application_info.Clone()); | 265 listener->ApplicationInstanceCreated(application_info.Clone()); |
266 }); | 266 }); |
267 instance->InitializeApplication(); | 267 instance->InitializeApplication(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 const String& application_name, | 312 const String& application_name, |
313 mojom::CapabilityFilterPtr base_filter) { | 313 mojom::CapabilityFilterPtr base_filter) { |
314 // It's possible that when this manifest request was issued, another one was | 314 // It's possible that when this manifest request was issued, another one was |
315 // already in-progress and completed by the time this one did, and so the | 315 // already in-progress and completed by the time this one did, and so the |
316 // requested application may already be running. | 316 // requested application may already be running. |
317 if (ConnectToInstance(¶ms)) | 317 if (ConnectToInstance(¶ms)) |
318 return; | 318 return; |
319 | 319 |
320 Identity source = params->source(), target = params->target(); | 320 Identity source = params->source(), target = params->target(); |
321 mojom::ShellClientRequest request; | 321 mojom::ShellClientRequest request; |
322 ApplicationInstance* instance = CreateInstance( | 322 ApplicationInstance* instance = |
323 params->target(), params->on_application_end(), application_name, | 323 CreateInstance(params->target(), application_name, &request); |
324 &request); | |
325 instance->ConnectToClient(std::move(params)); | 324 instance->ConnectToClient(std::move(params)); |
326 | 325 |
327 if (LoadWithLoader(target, &request)) | 326 if (LoadWithLoader(target, &request)) |
328 return; | 327 return; |
329 | 328 |
330 CHECK(!file_url.is_null() && !application_name.is_null() && | 329 CHECK(!file_url.is_null() && !application_name.is_null() && |
331 !base_filter.is_null()); | 330 !base_filter.is_null()); |
332 | 331 |
333 GURL resolved_gurl = resolved_url.To<GURL>(); | 332 GURL resolved_gurl = resolved_url.To<GURL>(); |
334 if (target.url().spec() != resolved_url) { | 333 if (target.url().spec() != resolved_url) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 info->name = instance->application_name(); | 386 info->name = instance->application_name(); |
388 if (instance->identity().url().spec() == "mojo://shell/") | 387 if (instance->identity().url().spec() == "mojo://shell/") |
389 info->pid = base::Process::Current().Pid(); | 388 info->pid = base::Process::Current().Pid(); |
390 else | 389 else |
391 info->pid = instance->pid(); | 390 info->pid = instance->pid(); |
392 return info; | 391 return info; |
393 } | 392 } |
394 | 393 |
395 } // namespace shell | 394 } // namespace shell |
396 } // namespace mojo | 395 } // namespace mojo |
OLD | NEW |