| 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 11 matching lines...) Expand all Loading... |
| 22 #include "mojo/shell/application_instance.h" | 22 #include "mojo/shell/application_instance.h" |
| 23 #include "mojo/shell/connect_util.h" | 23 #include "mojo/shell/connect_util.h" |
| 24 #include "mojo/shell/public/cpp/connect.h" | 24 #include "mojo/shell/public/cpp/connect.h" |
| 25 #include "mojo/shell/public/cpp/shell_connection.h" | 25 #include "mojo/shell/public/cpp/shell_connection.h" |
| 26 #include "mojo/shell/switches.h" | 26 #include "mojo/shell/switches.h" |
| 27 #include "mojo/util/filename_util.h" | 27 #include "mojo/util/filename_util.h" |
| 28 | 28 |
| 29 namespace mojo { | 29 namespace mojo { |
| 30 namespace shell { | 30 namespace shell { |
| 31 | 31 |
| 32 namespace { | |
| 33 | |
| 34 class ShellApplicationLoader : public ApplicationLoader { | |
| 35 public: | |
| 36 explicit ShellApplicationLoader(ApplicationManager* manager) | |
| 37 : manager_(manager) {} | |
| 38 ~ShellApplicationLoader() override {} | |
| 39 | |
| 40 private: | |
| 41 // Overridden from ApplicationLoader: | |
| 42 void Load(const GURL& url, mojom::ShellClientRequest request) override { | |
| 43 DCHECK(request.is_pending()); | |
| 44 shell_connection_.reset(new ShellConnection(manager_, std::move(request))); | |
| 45 } | |
| 46 | |
| 47 ApplicationManager* manager_; | |
| 48 scoped_ptr<ShellConnection> shell_connection_; | |
| 49 | |
| 50 DISALLOW_COPY_AND_ASSIGN(ShellApplicationLoader); | |
| 51 }; | |
| 52 | |
| 53 } // namespace | |
| 54 | |
| 55 // static | 32 // static |
| 56 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 33 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) |
| 57 : manager_(manager) { | 34 : manager_(manager) { |
| 58 } | 35 } |
| 59 | 36 |
| 60 ApplicationManager::TestAPI::~TestAPI() { | 37 ApplicationManager::TestAPI::~TestAPI() { |
| 61 } | 38 } |
| 62 | 39 |
| 63 bool ApplicationManager::TestAPI::HasRunningInstanceForURL( | 40 bool ApplicationManager::TestAPI::HasRunningInstanceForURL( |
| 64 const GURL& url) const { | 41 const GURL& url) const { |
| 65 return manager_->identity_to_instance_.find(Identity(url)) != | 42 return manager_->identity_to_instance_.find(Identity(url)) != |
| 66 manager_->identity_to_instance_.end(); | 43 manager_->identity_to_instance_.end(); |
| 67 } | 44 } |
| 68 | 45 |
| 69 //////////////////////////////////////////////////////////////////////////////// | 46 //////////////////////////////////////////////////////////////////////////////// |
| 70 // ApplicationManager, public: | 47 // ApplicationManager, public: |
| 71 | 48 |
| 72 ApplicationManager::ApplicationManager(bool register_mojo_url_schemes) | 49 ApplicationManager::ApplicationManager(bool register_mojo_url_schemes) |
| 73 : ApplicationManager(nullptr, nullptr, register_mojo_url_schemes) {} | 50 : ApplicationManager(nullptr, nullptr, register_mojo_url_schemes) {} |
| 74 | 51 |
| 75 ApplicationManager::ApplicationManager( | 52 ApplicationManager::ApplicationManager( |
| 76 scoped_ptr<NativeRunnerFactory> native_runner_factory, | 53 scoped_ptr<NativeRunnerFactory> native_runner_factory, |
| 77 base::TaskRunner* task_runner, | 54 base::TaskRunner* task_runner, |
| 78 bool register_mojo_url_schemes) | 55 bool register_mojo_url_schemes) |
| 79 : task_runner_(task_runner), | 56 : task_runner_(task_runner), |
| 80 native_runner_factory_(std::move(native_runner_factory)), | 57 native_runner_factory_(std::move(native_runner_factory)), |
| 81 weak_ptr_factory_(this) { | 58 weak_ptr_factory_(this) { |
| 82 SetLoaderForURL(make_scoped_ptr(new ShellApplicationLoader(this)), | 59 mojom::ShellClientRequest request; |
| 83 GURL("mojo://shell/")); | 60 CreateInstance(CreateShellIdentity(), &request); |
| 61 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
| 84 | 62 |
| 85 InitPackageManager(register_mojo_url_schemes); | 63 InitPackageManager(register_mojo_url_schemes); |
| 86 } | 64 } |
| 87 | 65 |
| 88 ApplicationManager::~ApplicationManager() { | 66 ApplicationManager::~ApplicationManager() { |
| 89 TerminateShellConnections(); | 67 TerminateShellConnections(); |
| 90 STLDeleteValues(&url_to_loader_); | 68 STLDeleteValues(&url_to_loader_); |
| 91 for (auto& runner : native_runners_) | 69 for (auto& runner : native_runners_) |
| 92 runner.reset(); | 70 runner.reset(); |
| 93 } | 71 } |
| 94 | 72 |
| 95 void ApplicationManager::SetInstanceQuitCallback( | 73 void ApplicationManager::SetInstanceQuitCallback( |
| 96 base::Callback<void(const Identity&)> callback) { | 74 base::Callback<void(const Identity&)> callback) { |
| 97 instance_quit_callback_ = callback; | 75 instance_quit_callback_ = callback; |
| 98 } | 76 } |
| 99 | 77 |
| 100 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { | 78 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { |
| 101 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", | 79 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", |
| 102 TRACE_EVENT_SCOPE_THREAD, "original_url", | 80 TRACE_EVENT_SCOPE_THREAD, "original_url", |
| 103 params->target().url().spec()); | 81 params->target().url().spec()); |
| 104 DCHECK(params->target().url().is_valid()); | 82 DCHECK(params->target().url().is_valid()); |
| 105 | 83 |
| 84 if (params->target().user_id() == mojom::Shell::kUserInherit) { |
| 85 ApplicationInstance* source = GetApplicationInstance(params->source()); |
| 86 Identity target = params->target(); |
| 87 // TODO(beng): we should CHECK source. |
| 88 target.set_user_id(source ? source->identity().user_id() |
| 89 : mojom::Shell::kUserRoot); |
| 90 params->set_target(target); |
| 91 } |
| 92 |
| 106 // Connect to an existing matching instance, if possible. | 93 // Connect to an existing matching instance, if possible. |
| 107 if (ConnectToExistingInstance(¶ms)) | 94 if (ConnectToExistingInstance(¶ms)) |
| 108 return; | 95 return; |
| 109 | 96 |
| 110 std::string url = params->target().url().spec(); | 97 std::string url = params->target().url().spec(); |
| 111 shell_resolver_->ResolveMojoURL( | 98 shell_resolver_->ResolveMojoURL( |
| 112 url, | 99 url, |
| 113 base::Bind(&ApplicationManager::OnGotResolvedURL, | 100 base::Bind(&ApplicationManager::OnGotResolvedURL, |
| 114 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); | 101 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); |
| 115 } | 102 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 void ApplicationManager::CreateInstanceForHandle( | 174 void ApplicationManager::CreateInstanceForHandle( |
| 188 ScopedHandle channel, | 175 ScopedHandle channel, |
| 189 const String& url, | 176 const String& url, |
| 190 mojom::CapabilityFilterPtr filter, | 177 mojom::CapabilityFilterPtr filter, |
| 191 mojom::PIDReceiverRequest pid_receiver) { | 178 mojom::PIDReceiverRequest pid_receiver) { |
| 192 // We don't call ConnectToClient() here since the instance was created | 179 // We don't call ConnectToClient() here since the instance was created |
| 193 // manually by other code, not in response to a Connect() request. The newly | 180 // manually by other code, not in response to a Connect() request. The newly |
| 194 // created instance is identified by |url| and may be subsequently reached by | 181 // created instance is identified by |url| and may be subsequently reached by |
| 195 // client code using this identity. | 182 // client code using this identity. |
| 196 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); | 183 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); |
| 197 Identity target_id(url.To<GURL>(), std::string(), local_filter); | 184 // TODO(beng): obtain userid from the inbound connection. |
| 185 Identity target_id(url.To<GURL>(), std::string(), mojom::Shell::kUserInherit, |
| 186 local_filter); |
| 198 mojom::ShellClientRequest request; | 187 mojom::ShellClientRequest request; |
| 199 ApplicationInstance* instance = CreateInstance(target_id, &request); | 188 ApplicationInstance* instance = CreateInstance(target_id, &request); |
| 200 instance->BindPIDReceiver(std::move(pid_receiver)); | 189 instance->BindPIDReceiver(std::move(pid_receiver)); |
| 201 scoped_ptr<NativeRunner> runner = | 190 scoped_ptr<NativeRunner> runner = |
| 202 native_runner_factory_->Create(base::FilePath()); | 191 native_runner_factory_->Create(base::FilePath()); |
| 203 runner->InitHost(std::move(channel), std::move(request)); | 192 runner->InitHost(std::move(channel), std::move(request)); |
| 204 instance->SetNativeRunner(runner.get()); | 193 instance->SetNativeRunner(runner.get()); |
| 205 native_runners_.push_back(std::move(runner)); | 194 native_runners_.push_back(std::move(runner)); |
| 206 } | 195 } |
| 207 | 196 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 228 loader->Load(url, std::move(request)); | 217 loader->Load(url, std::move(request)); |
| 229 | 218 |
| 230 SetLoaderForURL(std::move(loader), url); | 219 SetLoaderForURL(std::move(loader), url); |
| 231 | 220 |
| 232 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); | 221 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); |
| 233 } | 222 } |
| 234 | 223 |
| 235 bool ApplicationManager::ConnectToExistingInstance( | 224 bool ApplicationManager::ConnectToExistingInstance( |
| 236 scoped_ptr<ConnectParams>* params) { | 225 scoped_ptr<ConnectParams>* params) { |
| 237 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); | 226 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); |
| 238 if (!instance) | 227 if (!instance) { |
| 239 return false; | 228 Identity root_identity = (*params)->target(); |
| 229 root_identity.set_user_id(mojom::Shell::kUserRoot); |
| 230 instance = GetApplicationInstance(root_identity); |
| 231 if (!instance) return false; |
| 232 } |
| 240 instance->ConnectToClient(std::move(*params)); | 233 instance->ConnectToClient(std::move(*params)); |
| 241 return true; | 234 return true; |
| 242 } | 235 } |
| 243 | 236 |
| 244 ApplicationInstance* ApplicationManager::CreateInstance( | 237 ApplicationInstance* ApplicationManager::CreateInstance( |
| 245 const Identity& target_id, | 238 const Identity& target_id, |
| 246 mojom::ShellClientRequest* request) { | 239 mojom::ShellClientRequest* request) { |
| 247 mojom::ShellClientPtr shell_client; | 240 mojom::ShellClientPtr shell_client; |
| 248 *request = GetProxy(&shell_client); | 241 *request = GetProxy(&shell_client); |
| 249 ApplicationInstance* instance = | 242 ApplicationInstance* instance = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 // already in-progress and completed by the time this one did, and so the | 301 // already in-progress and completed by the time this one did, and so the |
| 309 // requested application may already be running. | 302 // requested application may already be running. |
| 310 if (ConnectToExistingInstance(¶ms)) | 303 if (ConnectToExistingInstance(¶ms)) |
| 311 return; | 304 return; |
| 312 | 305 |
| 313 Identity source = params->source(); | 306 Identity source = params->source(); |
| 314 CapabilityFilter filter = params->target().filter(); | 307 CapabilityFilter filter = params->target().filter(); |
| 315 // TODO(beng): this clobbers the filter passed via Connect(). | 308 // TODO(beng): this clobbers the filter passed via Connect(). |
| 316 if (!base_filter.is_null()) | 309 if (!base_filter.is_null()) |
| 317 filter = base_filter->filter.To<CapabilityFilter>(); | 310 filter = base_filter->filter.To<CapabilityFilter>(); |
| 318 Identity target(params->target().url(), params->target().qualifier(), filter); | 311 Identity target(params->target().url(), params->target().qualifier(), |
| 312 params->target().user_id(), filter); |
| 319 | 313 |
| 320 mojom::ShellClientRequest request; | 314 mojom::ShellClientRequest request; |
| 321 ApplicationInstance* instance = CreateInstance(target, &request); | 315 ApplicationInstance* instance = CreateInstance(target, &request); |
| 322 instance->ConnectToClient(std::move(params)); | 316 instance->ConnectToClient(std::move(params)); |
| 323 | 317 |
| 324 if (LoadWithLoader(target, &request)) | 318 if (LoadWithLoader(target, &request)) |
| 325 return; | 319 return; |
| 326 | 320 |
| 327 CHECK(!file_url.is_null() && !base_filter.is_null()); | 321 CHECK(!file_url.is_null() && !base_filter.is_null()); |
| 328 | 322 |
| 329 GURL resolved_gurl = resolved_url.To<GURL>(); | 323 GURL resolved_gurl = resolved_url.To<GURL>(); |
| 330 if (target.url().spec() != resolved_url) { | 324 if (target.url().spec() != resolved_url) { |
| 331 // In cases where a package alias is resolved, we have to use the qualifier | 325 // In cases where a package alias is resolved, we have to use the qualifier |
| 332 // from the original request rather than for the package itself, which will | 326 // from the original request rather than for the package itself, which will |
| 333 // always be the same. | 327 // always be the same. |
| 334 CreateShellClient(source, | 328 CreateShellClient(source, |
| 335 Identity(resolved_gurl, target.qualifier(), filter), | 329 Identity(resolved_gurl, target.qualifier(), |
| 330 target.user_id(), filter), |
| 336 target.url(), std::move(request)); | 331 target.url(), std::move(request)); |
| 337 } else { | 332 } else { |
| 338 bool start_sandboxed = false; | 333 bool start_sandboxed = false; |
| 339 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); | 334 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); |
| 340 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); | 335 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); |
| 341 runner->Start(path, target, start_sandboxed, std::move(request), | 336 runner->Start(path, target, start_sandboxed, std::move(request), |
| 342 base::Bind(&ApplicationManager::ApplicationPIDAvailable, | 337 base::Bind(&ApplicationManager::ApplicationPIDAvailable, |
| 343 weak_ptr_factory_.GetWeakPtr(), instance->id()), | 338 weak_ptr_factory_.GetWeakPtr(), instance->id()), |
| 344 base::Bind(&ApplicationManager::CleanupRunner, | 339 base::Bind(&ApplicationManager::CleanupRunner, |
| 345 weak_ptr_factory_.GetWeakPtr(), runner.get())); | 340 weak_ptr_factory_.GetWeakPtr(), runner.get())); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 info->qualifier = instance->identity().qualifier(); | 376 info->qualifier = instance->identity().qualifier(); |
| 382 if (instance->identity().url().spec() == "mojo://shell/") | 377 if (instance->identity().url().spec() == "mojo://shell/") |
| 383 info->pid = base::Process::Current().Pid(); | 378 info->pid = base::Process::Current().Pid(); |
| 384 else | 379 else |
| 385 info->pid = instance->pid(); | 380 info->pid = instance->pid(); |
| 386 return info; | 381 return info; |
| 387 } | 382 } |
| 388 | 383 |
| 389 } // namespace shell | 384 } // namespace shell |
| 390 } // namespace mojo | 385 } // namespace mojo |
| OLD | NEW |