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 |