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