| 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 |