| 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 CHECK(source); |
| 87 Identity target = params->target(); |
| 88 target.set_user_id(source->identity().user_id()); |
| 89 params->set_target(target); |
| 90 } |
| 91 |
| 106 // Connect to an existing matching instance, if possible. | 92 // Connect to an existing matching instance, if possible. |
| 107 if (ConnectToExistingInstance(¶ms)) | 93 if (ConnectToExistingInstance(¶ms)) |
| 108 return; | 94 return; |
| 109 | 95 |
| 110 std::string url = params->target().url().spec(); | 96 std::string url = params->target().url().spec(); |
| 111 shell_resolver_->ResolveMojoURL( | 97 shell_resolver_->ResolveMojoURL( |
| 112 url, | 98 url, |
| 113 base::Bind(&ApplicationManager::OnGotResolvedURL, | 99 base::Bind(&ApplicationManager::OnGotResolvedURL, |
| 114 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); | 100 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); |
| 115 } | 101 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 void ApplicationManager::CreateInstanceForHandle( | 173 void ApplicationManager::CreateInstanceForHandle( |
| 188 ScopedHandle channel, | 174 ScopedHandle channel, |
| 189 const String& url, | 175 const String& url, |
| 190 mojom::CapabilityFilterPtr filter, | 176 mojom::CapabilityFilterPtr filter, |
| 191 mojom::PIDReceiverRequest pid_receiver) { | 177 mojom::PIDReceiverRequest pid_receiver) { |
| 192 // We don't call ConnectToClient() here since the instance was created | 178 // 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 | 179 // 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 | 180 // created instance is identified by |url| and may be subsequently reached by |
| 195 // client code using this identity. | 181 // client code using this identity. |
| 196 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); | 182 CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); |
| 197 Identity target_id(url.To<GURL>(), std::string(), local_filter); | 183 // TODO(beng): obtain userid from the inbound connection. |
| 184 Identity target_id(url.To<GURL>(), std::string(), mojom::Shell::kUserInherit, |
| 185 local_filter); |
| 198 mojom::ShellClientRequest request; | 186 mojom::ShellClientRequest request; |
| 199 ApplicationInstance* instance = CreateInstance(target_id, &request); | 187 ApplicationInstance* instance = CreateInstance(target_id, &request); |
| 200 instance->BindPIDReceiver(std::move(pid_receiver)); | 188 instance->BindPIDReceiver(std::move(pid_receiver)); |
| 201 scoped_ptr<NativeRunner> runner = | 189 scoped_ptr<NativeRunner> runner = |
| 202 native_runner_factory_->Create(base::FilePath()); | 190 native_runner_factory_->Create(base::FilePath()); |
| 203 runner->InitHost(std::move(channel), std::move(request)); | 191 runner->InitHost(std::move(channel), std::move(request)); |
| 204 instance->SetNativeRunner(runner.get()); | 192 instance->SetNativeRunner(runner.get()); |
| 205 native_runners_.push_back(std::move(runner)); | 193 native_runners_.push_back(std::move(runner)); |
| 206 } | 194 } |
| 207 | 195 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 228 loader->Load(url, std::move(request)); | 216 loader->Load(url, std::move(request)); |
| 229 | 217 |
| 230 SetLoaderForURL(std::move(loader), url); | 218 SetLoaderForURL(std::move(loader), url); |
| 231 | 219 |
| 232 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); | 220 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); |
| 233 } | 221 } |
| 234 | 222 |
| 235 bool ApplicationManager::ConnectToExistingInstance( | 223 bool ApplicationManager::ConnectToExistingInstance( |
| 236 scoped_ptr<ConnectParams>* params) { | 224 scoped_ptr<ConnectParams>* params) { |
| 237 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); | 225 ApplicationInstance* instance = GetApplicationInstance((*params)->target()); |
| 238 if (!instance) | 226 if (!instance) { |
| 239 return false; | 227 Identity root_identity = (*params)->target(); |
| 228 root_identity.set_user_id(mojom::Shell::kUserRoot); |
| 229 instance = GetApplicationInstance(root_identity); |
| 230 if (!instance) return false; |
| 231 } |
| 240 instance->ConnectToClient(std::move(*params)); | 232 instance->ConnectToClient(std::move(*params)); |
| 241 return true; | 233 return true; |
| 242 } | 234 } |
| 243 | 235 |
| 244 ApplicationInstance* ApplicationManager::CreateInstance( | 236 ApplicationInstance* ApplicationManager::CreateInstance( |
| 245 const Identity& target_id, | 237 const Identity& target_id, |
| 246 mojom::ShellClientRequest* request) { | 238 mojom::ShellClientRequest* request) { |
| 247 mojom::ShellClientPtr shell_client; | 239 mojom::ShellClientPtr shell_client; |
| 248 *request = GetProxy(&shell_client); | 240 *request = GetProxy(&shell_client); |
| 249 ApplicationInstance* instance = | 241 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 | 300 // already in-progress and completed by the time this one did, and so the |
| 309 // requested application may already be running. | 301 // requested application may already be running. |
| 310 if (ConnectToExistingInstance(¶ms)) | 302 if (ConnectToExistingInstance(¶ms)) |
| 311 return; | 303 return; |
| 312 | 304 |
| 313 Identity source = params->source(); | 305 Identity source = params->source(); |
| 314 CapabilityFilter filter = params->target().filter(); | 306 CapabilityFilter filter = params->target().filter(); |
| 315 // TODO(beng): this clobbers the filter passed via Connect(). | 307 // TODO(beng): this clobbers the filter passed via Connect(). |
| 316 if (!base_filter.is_null()) | 308 if (!base_filter.is_null()) |
| 317 filter = base_filter->filter.To<CapabilityFilter>(); | 309 filter = base_filter->filter.To<CapabilityFilter>(); |
| 318 Identity target(params->target().url(), params->target().qualifier(), filter); | 310 Identity target(params->target().url(), params->target().qualifier(), |
| 311 params->target().user_id(), filter); |
| 319 | 312 |
| 320 mojom::ShellClientRequest request; | 313 mojom::ShellClientRequest request; |
| 321 ApplicationInstance* instance = CreateInstance(target, &request); | 314 ApplicationInstance* instance = CreateInstance(target, &request); |
| 322 instance->ConnectToClient(std::move(params)); | 315 instance->ConnectToClient(std::move(params)); |
| 323 | 316 |
| 324 if (LoadWithLoader(target, &request)) | 317 if (LoadWithLoader(target, &request)) |
| 325 return; | 318 return; |
| 326 | 319 |
| 327 CHECK(!file_url.is_null() && !base_filter.is_null()); | 320 CHECK(!file_url.is_null() && !base_filter.is_null()); |
| 328 | 321 |
| 329 GURL resolved_gurl = resolved_url.To<GURL>(); | 322 GURL resolved_gurl = resolved_url.To<GURL>(); |
| 330 if (target.url().spec() != resolved_url) { | 323 if (target.url().spec() != resolved_url) { |
| 331 // In cases where a package alias is resolved, we have to use the qualifier | 324 // 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 | 325 // from the original request rather than for the package itself, which will |
| 333 // always be the same. | 326 // always be the same. |
| 334 CreateShellClient(source, | 327 CreateShellClient(source, |
| 335 Identity(resolved_gurl, target.qualifier(), filter), | 328 Identity(resolved_gurl, target.qualifier(), |
| 329 target.user_id(), filter), |
| 336 target.url(), std::move(request)); | 330 target.url(), std::move(request)); |
| 337 } else { | 331 } else { |
| 338 bool start_sandboxed = false; | 332 bool start_sandboxed = false; |
| 339 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); | 333 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); |
| 340 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); | 334 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); |
| 341 runner->Start(path, start_sandboxed, std::move(request), | 335 runner->Start(path, start_sandboxed, std::move(request), |
| 342 base::Bind(&ApplicationManager::ApplicationPIDAvailable, | 336 base::Bind(&ApplicationManager::ApplicationPIDAvailable, |
| 343 weak_ptr_factory_.GetWeakPtr(), instance->id()), | 337 weak_ptr_factory_.GetWeakPtr(), instance->id()), |
| 344 base::Bind(&ApplicationManager::CleanupRunner, | 338 base::Bind(&ApplicationManager::CleanupRunner, |
| 345 weak_ptr_factory_.GetWeakPtr(), runner.get())); | 339 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(); | 375 info->qualifier = instance->identity().qualifier(); |
| 382 if (instance->identity().url().spec() == "mojo://shell/") | 376 if (instance->identity().url().spec() == "mojo://shell/") |
| 383 info->pid = base::Process::Current().Pid(); | 377 info->pid = base::Process::Current().Pid(); |
| 384 else | 378 else |
| 385 info->pid = instance->pid(); | 379 info->pid = instance->pid(); |
| 386 return info; | 380 return info; |
| 387 } | 381 } |
| 388 | 382 |
| 389 } // namespace shell | 383 } // namespace shell |
| 390 } // namespace mojo | 384 } // namespace mojo |
| OLD | NEW |