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/shell.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/process/process.h" | 15 #include "base/process/process.h" |
16 #include "base/process/process_handle.h" | 16 #include "base/process/process_handle.h" |
17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
20 #include "mojo/common/url_type_converters.h" | 20 #include "mojo/common/url_type_converters.h" |
21 #include "mojo/public/cpp/bindings/binding.h" | 21 #include "mojo/public/cpp/bindings/binding.h" |
22 #include "mojo/public/cpp/bindings/binding_set.h" | 22 #include "mojo/public/cpp/bindings/binding_set.h" |
23 #include "mojo/services/package_manager/loader.h" | 23 #include "mojo/services/package_manager/loader.h" |
24 #include "mojo/shell/connect_util.h" | 24 #include "mojo/shell/connect_util.h" |
25 #include "mojo/shell/public/cpp/connect.h" | 25 #include "mojo/shell/public/cpp/connect.h" |
26 #include "mojo/shell/public/cpp/names.h" | 26 #include "mojo/shell/public/cpp/names.h" |
27 #include "mojo/shell/public/cpp/shell_connection.h" | 27 #include "mojo/shell/public/cpp/shell_connection.h" |
28 #include "mojo/shell/public/interfaces/application_manager.mojom.h" | 28 #include "mojo/shell/public/interfaces/connector.mojom.h" |
29 #include "mojo/shell/public/interfaces/shell.mojom.h" | 29 #include "mojo/shell/public/interfaces/shell.mojom.h" |
30 #include "mojo/shell/public/interfaces/shell_client.mojom.h" | 30 #include "mojo/shell/public/interfaces/shell_client.mojom.h" |
31 #include "mojo/util/filename_util.h" | 31 #include "mojo/util/filename_util.h" |
32 | 32 |
33 namespace mojo { | 33 namespace mojo { |
34 namespace shell { | 34 namespace shell { |
35 namespace { | 35 namespace { |
36 const char kPackageManagerName[] = "mojo:package_manager"; | 36 const char kPackageManagerName[] = "mojo:package_manager"; |
37 | 37 |
38 void EmptyResolverCallback(const String& resolved_name, | 38 void EmptyResolverCallback(const String& resolved_name, |
39 const String& resolved_qualifier, | 39 const String& resolved_qualifier, |
40 mojom::CapabilityFilterPtr base_filter, | 40 mojom::CapabilityFilterPtr base_filter, |
41 const String& file_url) {} | 41 const String& file_url) {} |
42 | 42 |
43 } | 43 } |
44 | 44 |
45 // Encapsulates a connection to an instance of an application, tracked by the | 45 // Encapsulates a connection to an instance of an application, tracked by the |
46 // shell's ApplicationManager. | 46 // shell's Shell. |
47 class ApplicationManager::Instance | 47 class Shell::Instance : public mojom::Connector, |
48 : public mojom::Connector, | 48 public mojom::PIDReceiver, |
49 public mojom::PIDReceiver, | 49 public ShellClient, |
50 public ShellClient, | 50 public InterfaceFactory<mojom::Shell>, |
51 public InterfaceFactory<mojom::ApplicationManager>, | 51 public mojom::Shell { |
52 public mojom::ApplicationManager { | |
53 public: | 52 public: |
54 Instance(mojom::ShellClientPtr shell_client, | 53 Instance(mojom::ShellClientPtr shell_client, |
55 mojo::shell::ApplicationManager* manager, | 54 mojo::shell::Shell* shell, |
56 const Identity& identity) | 55 const Identity& identity) |
57 : manager_(manager), | 56 : shell_(shell), |
58 id_(GenerateUniqueID()), | 57 id_(GenerateUniqueID()), |
59 identity_(identity), | 58 identity_(identity), |
60 allow_any_application_(identity.filter().size() == 1 && | 59 allow_any_application_(identity.filter().size() == 1 && |
61 identity.filter().count("*") == 1), | 60 identity.filter().count("*") == 1), |
62 shell_client_(std::move(shell_client)), | 61 shell_client_(std::move(shell_client)), |
63 pid_receiver_binding_(this), | 62 pid_receiver_binding_(this), |
64 weak_factory_(this) { | 63 weak_factory_(this) { |
65 if (identity_.name() == "mojo:shell" || | 64 if (identity_.name() == "mojo:shell" || |
66 manager_->GetLoaderForName(identity_.name())) { | 65 shell_->GetLoaderForName(identity_.name())) { |
67 pid_ = base::Process::Current().Pid(); | 66 pid_ = base::Process::Current().Pid(); |
68 } | 67 } |
69 DCHECK_NE(kInvalidApplicationID, id_); | 68 DCHECK_NE(kInvalidApplicationID, id_); |
70 } | 69 } |
71 | 70 |
72 ~Instance() override {} | 71 ~Instance() override {} |
73 | 72 |
74 void InitializeClient() { | 73 void InitializeClient() { |
75 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), | 74 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), |
76 identity_.name(), id_, identity_.user_id()); | 75 identity_.name(), id_, identity_.user_id()); |
77 connectors_.set_connection_error_handler( | 76 connectors_.set_connection_error_handler( |
78 base::Bind(&mojo::shell::ApplicationManager::OnInstanceError, | 77 base::Bind(&mojo::shell::Shell::OnInstanceError, |
79 base::Unretained(manager_), base::Unretained(this))); | 78 base::Unretained(shell_), base::Unretained(this))); |
80 } | 79 } |
81 | 80 |
82 void ConnectToClient(scoped_ptr<ConnectParams> params) { | 81 void ConnectToClient(scoped_ptr<ConnectParams> params) { |
83 params->connect_callback().Run(id_, identity_.user_id()); | 82 params->connect_callback().Run(id_, identity_.user_id()); |
84 AllowedInterfaces interfaces; | 83 AllowedInterfaces interfaces; |
85 interfaces.insert("*"); | 84 interfaces.insert("*"); |
86 if (!params->source().is_null()) | 85 if (!params->source().is_null()) |
87 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); | 86 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); |
88 | 87 |
89 Instance* source = manager_->GetExistingInstance(params->source()); | 88 Instance* source = shell_->GetExistingInstance(params->source()); |
90 uint32_t source_id = source ? source->id() : kInvalidApplicationID; | 89 uint32_t source_id = source ? source->id() : kInvalidApplicationID; |
91 shell_client_->AcceptConnection( | 90 shell_client_->AcceptConnection( |
92 params->source().name(), source_id, params->source().user_id(), | 91 params->source().name(), source_id, params->source().user_id(), |
93 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), | 92 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), |
94 Array<String>::From(interfaces), params->target().name()); | 93 Array<String>::From(interfaces), params->target().name()); |
95 } | 94 } |
96 | 95 |
97 scoped_ptr<NativeRunner> StartWithFileURL(const GURL& file_url, | 96 scoped_ptr<NativeRunner> StartWithFileURL(const GURL& file_url, |
98 mojom::ShellClientRequest request, | 97 mojom::ShellClientRequest request, |
99 bool start_sandboxed, | 98 bool start_sandboxed, |
100 NativeRunnerFactory* factory) { | 99 NativeRunnerFactory* factory) { |
101 base::FilePath path = util::UrlToFilePath(file_url); | 100 base::FilePath path = util::UrlToFilePath(file_url); |
102 scoped_ptr<NativeRunner> runner = factory->Create(path); | 101 scoped_ptr<NativeRunner> runner = factory->Create(path); |
103 runner_ = runner.get(); | 102 runner_ = runner.get(); |
104 runner_->Start(path, identity_, start_sandboxed, std::move(request), | 103 runner_->Start(path, identity_, start_sandboxed, std::move(request), |
105 base::Bind(&Instance::PIDAvailable, | 104 base::Bind(&Instance::PIDAvailable, |
106 weak_factory_.GetWeakPtr()), | 105 weak_factory_.GetWeakPtr()), |
107 base::Bind(&mojo::shell::ApplicationManager::CleanupRunner, | 106 base::Bind(&mojo::shell::Shell::CleanupRunner, |
108 manager_->weak_ptr_factory_.GetWeakPtr(), | 107 shell_->weak_ptr_factory_.GetWeakPtr(), |
109 runner_)); | 108 runner_)); |
110 return runner; | 109 return runner; |
111 } | 110 } |
112 | 111 |
113 scoped_ptr<NativeRunner> StartWithFactory( | 112 scoped_ptr<NativeRunner> StartWithFactory( |
114 mojom::ShellClientFactoryPtr shell_client_factory, | 113 mojom::ShellClientFactoryPtr shell_client_factory, |
115 const String& name, | 114 const String& name, |
116 mojom::ShellClientRequest request, | 115 mojom::ShellClientRequest request, |
117 mojom::PIDReceiverRequest pid_receiver_request, | 116 mojom::PIDReceiverRequest pid_receiver_request, |
118 NativeRunnerFactory* factory) { | 117 NativeRunnerFactory* factory) { |
(...skipping 12 matching lines...) Expand all Loading... |
131 info->qualifier = identity_.qualifier(); | 130 info->qualifier = identity_.qualifier(); |
132 info->pid = pid_; | 131 info->pid = pid_; |
133 return info; | 132 return info; |
134 } | 133 } |
135 | 134 |
136 const Identity& identity() const { return identity_; } | 135 const Identity& identity() const { return identity_; } |
137 uint32_t id() const { return id_; } | 136 uint32_t id() const { return id_; } |
138 | 137 |
139 // ShellClient: | 138 // ShellClient: |
140 bool AcceptConnection(Connection* connection) override { | 139 bool AcceptConnection(Connection* connection) override { |
141 connection->AddInterface<mojom::ApplicationManager>(this); | 140 connection->AddInterface<mojom::Shell>(this); |
142 return true; | 141 return true; |
143 } | 142 } |
144 | 143 |
145 private: | 144 private: |
146 // mojom::Connector implementation: | 145 // mojom::Connector implementation: |
147 void Connect(const String& app_name, | 146 void Connect(const String& app_name, |
148 uint32_t user_id, | 147 uint32_t user_id, |
149 shell::mojom::InterfaceProviderRequest remote_interfaces, | 148 shell::mojom::InterfaceProviderRequest remote_interfaces, |
150 shell::mojom::InterfaceProviderPtr local_interfaces, | 149 shell::mojom::InterfaceProviderPtr local_interfaces, |
151 const ConnectCallback& callback) override { | 150 const ConnectCallback& callback) override { |
152 // TODO(beng): perform checking on policy of whether this instance is | 151 // TODO(beng): perform checking on policy of whether this instance is |
153 // allowed to pass different user_ids. | 152 // allowed to pass different user_ids. |
154 if (!IsValidName(app_name)) { | 153 if (!IsValidName(app_name)) { |
155 LOG(ERROR) << "Error: invalid Name: " << app_name; | 154 LOG(ERROR) << "Error: invalid Name: " << app_name; |
156 callback.Run(kInvalidApplicationID, kUserInherit); | 155 callback.Run(kInvalidApplicationID, kUserInherit); |
157 return; | 156 return; |
158 } | 157 } |
159 if (allow_any_application_ || | 158 if (allow_any_application_ || |
160 identity_.filter().find(app_name) != identity_.filter().end()) { | 159 identity_.filter().find(app_name) != identity_.filter().end()) { |
161 scoped_ptr<ConnectParams> params(new ConnectParams); | 160 scoped_ptr<ConnectParams> params(new ConnectParams); |
162 params->set_source(identity_); | 161 params->set_source(identity_); |
163 params->set_target(Identity(app_name, std::string(), user_id)); | 162 params->set_target(Identity(app_name, std::string(), user_id)); |
164 params->set_remote_interfaces(std::move(remote_interfaces)); | 163 params->set_remote_interfaces(std::move(remote_interfaces)); |
165 params->set_local_interfaces(std::move(local_interfaces)); | 164 params->set_local_interfaces(std::move(local_interfaces)); |
166 params->set_connect_callback(callback); | 165 params->set_connect_callback(callback); |
167 manager_->Connect(std::move(params)); | 166 shell_->Connect(std::move(params)); |
168 } | 167 } |
169 else { | 168 else { |
170 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 169 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
171 identity_.name() << " to: " << app_name; | 170 identity_.name() << " to: " << app_name; |
172 callback.Run(kInvalidApplicationID, kUserInherit); | 171 callback.Run(kInvalidApplicationID, kUserInherit); |
173 } | 172 } |
174 } | 173 } |
175 void Clone(mojom::ConnectorRequest request) override { | 174 void Clone(mojom::ConnectorRequest request) override { |
176 connectors_.AddBinding(this, std::move(request)); | 175 connectors_.AddBinding(this, std::move(request)); |
177 } | 176 } |
178 | 177 |
179 // mojom::PIDReceiver: | 178 // mojom::PIDReceiver: |
180 void SetPID(uint32_t pid) override { | 179 void SetPID(uint32_t pid) override { |
181 PIDAvailable(pid); | 180 PIDAvailable(pid); |
182 } | 181 } |
183 | 182 |
184 // InterfaceFactory<mojom::ApplicationManager>: | 183 // InterfaceFactory<mojom::Shell>: |
185 void Create(Connection* connection, | 184 void Create(Connection* connection, |
186 mojom::ApplicationManagerRequest request) override { | 185 mojom::ShellRequest request) override { |
187 application_manager_bindings_.AddBinding(this, std::move(request)); | 186 shell_bindings_.AddBinding(this, std::move(request)); |
188 } | 187 } |
189 | 188 |
190 // mojom::ApplicationManager implementation: | 189 // mojom::Shell implementation: |
191 void CreateInstanceForFactory( | 190 void CreateInstanceForFactory( |
192 mojom::ShellClientFactoryPtr factory, | 191 mojom::ShellClientFactoryPtr factory, |
193 const String& name, | 192 const String& name, |
194 uint32_t user_id, | 193 uint32_t user_id, |
195 mojom::CapabilityFilterPtr filter, | 194 mojom::CapabilityFilterPtr filter, |
196 mojom::PIDReceiverRequest pid_receiver) override { | 195 mojom::PIDReceiverRequest pid_receiver) override { |
197 // TODO(beng): perform checking on policy of whether this instance is | 196 // TODO(beng): perform checking on policy of whether this instance is |
198 // allowed to pass different user_ids. | 197 // allowed to pass different user_ids. |
199 if (user_id == mojom::Connector::kUserInherit) | 198 if (user_id == mojom::Connector::kUserInherit) |
200 user_id = identity_.user_id(); | 199 user_id = identity_.user_id(); |
201 manager_->CreateInstanceForFactory(std::move(factory), name, user_id, | 200 shell_->CreateInstanceForFactory(std::move(factory), name, user_id, |
202 std::move(filter), | 201 std::move(filter), |
203 std::move(pid_receiver)); | 202 std::move(pid_receiver)); |
204 } | 203 } |
205 void AddInstanceListener(mojom::InstanceListenerPtr listener) override { | 204 void AddInstanceListener(mojom::InstanceListenerPtr listener) override { |
206 // TODO(beng): this should only track the instances matching this user, and | 205 // TODO(beng): this should only track the instances matching this user, and |
207 // root. | 206 // root. |
208 manager_->AddInstanceListener(std::move(listener)); | 207 shell_->AddInstanceListener(std::move(listener)); |
209 } | 208 } |
210 | 209 |
211 uint32_t GenerateUniqueID() const { | 210 uint32_t GenerateUniqueID() const { |
212 static uint32_t id = kInvalidApplicationID; | 211 static uint32_t id = kInvalidApplicationID; |
213 ++id; | 212 ++id; |
214 CHECK_NE(kInvalidApplicationID, id); | 213 CHECK_NE(kInvalidApplicationID, id); |
215 return id; | 214 return id; |
216 } | 215 } |
217 | 216 |
218 void PIDAvailable(base::ProcessId pid) { | 217 void PIDAvailable(base::ProcessId pid) { |
219 pid_ = pid; | 218 pid_ = pid; |
220 manager_->NotifyPIDAvailable(id_, pid_); | 219 shell_->NotifyPIDAvailable(id_, pid_); |
221 } | 220 } |
222 | 221 |
223 mojo::shell::ApplicationManager* const manager_; | 222 mojo::shell::Shell* const shell_; |
224 // An id that identifies this instance. Distinct from pid, as a single process | 223 // An id that identifies this instance. Distinct from pid, as a single process |
225 // may vend multiple application instances, and this object may exist before a | 224 // may vend multiple application instances, and this object may exist before a |
226 // process is launched. | 225 // process is launched. |
227 const uint32_t id_; | 226 const uint32_t id_; |
228 const Identity identity_; | 227 const Identity identity_; |
229 const bool allow_any_application_; | 228 const bool allow_any_application_; |
230 mojom::ShellClientPtr shell_client_; | 229 mojom::ShellClientPtr shell_client_; |
231 Binding<mojom::PIDReceiver> pid_receiver_binding_; | 230 Binding<mojom::PIDReceiver> pid_receiver_binding_; |
232 BindingSet<mojom::Connector> connectors_; | 231 BindingSet<mojom::Connector> connectors_; |
233 BindingSet<mojom::ApplicationManager> application_manager_bindings_; | 232 BindingSet<mojom::Shell> shell_bindings_; |
234 NativeRunner* runner_ = nullptr; | 233 NativeRunner* runner_ = nullptr; |
235 base::ProcessId pid_ = base::kNullProcessId; | 234 base::ProcessId pid_ = base::kNullProcessId; |
236 base::WeakPtrFactory<Instance> weak_factory_; | 235 base::WeakPtrFactory<Instance> weak_factory_; |
237 | 236 |
238 DISALLOW_COPY_AND_ASSIGN(Instance); | 237 DISALLOW_COPY_AND_ASSIGN(Instance); |
239 }; | 238 }; |
240 | 239 |
241 // static | 240 // static |
242 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 241 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} |
243 : manager_(manager) { | 242 Shell::TestAPI::~TestAPI() {} |
244 } | |
245 | 243 |
246 ApplicationManager::TestAPI::~TestAPI() { | 244 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { |
247 } | 245 return shell_->identity_to_instance_.find(Identity(name)) != |
248 | 246 shell_->identity_to_instance_.end(); |
249 bool ApplicationManager::TestAPI::HasRunningInstanceForName( | |
250 const std::string& name) const { | |
251 return manager_->identity_to_instance_.find(Identity(name)) != | |
252 manager_->identity_to_instance_.end(); | |
253 } | 247 } |
254 | 248 |
255 //////////////////////////////////////////////////////////////////////////////// | 249 //////////////////////////////////////////////////////////////////////////////// |
256 // ApplicationManager, public: | 250 // Shell, public: |
257 | 251 |
258 ApplicationManager::ApplicationManager( | 252 Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory, |
259 scoped_ptr<NativeRunnerFactory> native_runner_factory, | 253 base::TaskRunner* file_task_runner, |
260 base::TaskRunner* file_task_runner, | 254 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) |
261 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) | |
262 : file_task_runner_(file_task_runner), | 255 : file_task_runner_(file_task_runner), |
263 native_runner_factory_(std::move(native_runner_factory)), | 256 native_runner_factory_(std::move(native_runner_factory)), |
264 weak_ptr_factory_(this) { | 257 weak_ptr_factory_(this) { |
265 mojom::ShellClientRequest request; | 258 mojom::ShellClientRequest request; |
266 CreateInstance(CreateShellIdentity(), &request); | 259 CreateInstance(CreateShellIdentity(), &request); |
267 shell_connection_.reset(new ShellConnection(this, std::move(request))); | 260 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
268 | 261 |
269 InitPackageManager(std::move(app_catalog)); | 262 InitPackageManager(std::move(app_catalog)); |
270 } | 263 } |
271 | 264 |
272 ApplicationManager::~ApplicationManager() { | 265 Shell::~Shell() { |
273 TerminateShellConnections(); | 266 TerminateShellConnections(); |
274 STLDeleteValues(&name_to_loader_); | 267 STLDeleteValues(&name_to_loader_); |
275 for (auto& runner : native_runners_) | 268 for (auto& runner : native_runners_) |
276 runner.reset(); | 269 runner.reset(); |
277 } | 270 } |
278 | 271 |
279 void ApplicationManager::SetInstanceQuitCallback( | 272 void Shell::SetInstanceQuitCallback( |
280 base::Callback<void(const Identity&)> callback) { | 273 base::Callback<void(const Identity&)> callback) { |
281 instance_quit_callback_ = callback; | 274 instance_quit_callback_ = callback; |
282 } | 275 } |
283 | 276 |
284 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { | 277 void Shell::Connect(scoped_ptr<ConnectParams> params) { |
285 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", | 278 TRACE_EVENT_INSTANT1("mojo_shell", "Shell::Connect", |
286 TRACE_EVENT_SCOPE_THREAD, "original_name", | 279 TRACE_EVENT_SCOPE_THREAD, "original_name", |
287 params->target().name()); | 280 params->target().name()); |
288 DCHECK(IsValidName(params->target().name())); | 281 DCHECK(IsValidName(params->target().name())); |
289 | 282 |
290 if (params->target().user_id() == mojom::Connector::kUserInherit) { | 283 if (params->target().user_id() == mojom::Connector::kUserInherit) { |
291 Instance* source = GetExistingInstance(params->source()); | 284 Instance* source = GetExistingInstance(params->source()); |
292 Identity target = params->target(); | 285 Identity target = params->target(); |
293 // TODO(beng): we should CHECK source. | 286 // TODO(beng): we should CHECK source. |
294 target.set_user_id(source ? source->identity().user_id() | 287 target.set_user_id(source ? source->identity().user_id() |
295 : mojom::Connector::kUserRoot); | 288 : mojom::Connector::kUserRoot); |
296 params->set_target(target); | 289 params->set_target(target); |
297 } | 290 } |
298 | 291 |
299 // Connect to an existing matching instance, if possible. | 292 // Connect to an existing matching instance, if possible. |
300 if (ConnectToExistingInstance(¶ms)) | 293 if (ConnectToExistingInstance(¶ms)) |
301 return; | 294 return; |
302 | 295 |
303 std::string name = params->target().name(); | 296 std::string name = params->target().name(); |
304 shell_resolver_->ResolveMojoName( | 297 shell_resolver_->ResolveMojoName( |
305 name, | 298 name, |
306 base::Bind(&ApplicationManager::OnGotResolvedName, | 299 base::Bind(&Shell::OnGotResolvedName, |
307 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); | 300 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); |
308 } | 301 } |
309 | 302 |
310 mojom::ShellClientRequest ApplicationManager::InitInstanceForEmbedder( | 303 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( |
311 const std::string& name) { | 304 const std::string& name) { |
312 DCHECK(!embedder_instance_); | 305 DCHECK(!embedder_instance_); |
313 | 306 |
314 mojo::shell::Identity target(name, std::string(), | 307 mojo::shell::Identity target(name, std::string(), |
315 mojom::Connector::kUserRoot); | 308 mojom::Connector::kUserRoot); |
316 target.set_filter(GetPermissiveCapabilityFilter()); | 309 target.set_filter(GetPermissiveCapabilityFilter()); |
317 DCHECK(!GetExistingInstance(target)); | 310 DCHECK(!GetExistingInstance(target)); |
318 | 311 |
319 mojom::ShellClientRequest request; | 312 mojom::ShellClientRequest request; |
320 embedder_instance_ = CreateInstance(target, &request); | 313 embedder_instance_ = CreateInstance(target, &request); |
321 DCHECK(embedder_instance_); | 314 DCHECK(embedder_instance_); |
322 | 315 |
323 return request; | 316 return request; |
324 } | 317 } |
325 | 318 |
326 void ApplicationManager::SetLoaderForName(scoped_ptr<Loader> loader, | 319 void Shell::SetLoaderForName(scoped_ptr<Loader> loader, |
327 const std::string& name) { | 320 const std::string& name) { |
328 NameToLoaderMap::iterator it = name_to_loader_.find(name); | 321 NameToLoaderMap::iterator it = name_to_loader_.find(name); |
329 if (it != name_to_loader_.end()) | 322 if (it != name_to_loader_.end()) |
330 delete it->second; | 323 delete it->second; |
331 name_to_loader_[name] = loader.release(); | 324 name_to_loader_[name] = loader.release(); |
332 } | 325 } |
333 | 326 |
334 //////////////////////////////////////////////////////////////////////////////// | 327 //////////////////////////////////////////////////////////////////////////////// |
335 // ApplicationManager, ShellClient implementation: | 328 // Shell, ShellClient implementation: |
336 | 329 |
337 bool ApplicationManager::AcceptConnection(Connection* connection) { | 330 bool Shell::AcceptConnection(Connection* connection) { |
338 // The only interface we expose is mojom::ApplicationManager, and access to | 331 // The only interface we expose is mojom::Shell, and access to this interface |
339 // this interface is brokered by a policy specific to each caller, managed by | 332 // is brokered by a policy specific to each caller, managed by the caller's |
340 // the caller's instance. Here we look to see who's calling, and forward to | 333 // instance. Here we look to see who's calling, and forward to the caller's |
341 // the caller's instance to continue. | 334 // instance to continue. |
342 uint32_t caller_instance_id = mojom::Connector::kInvalidApplicationID; | 335 uint32_t caller_instance_id = mojom::Connector::kInvalidApplicationID; |
343 CHECK(connection->GetRemoteApplicationID(&caller_instance_id)); | 336 CHECK(connection->GetRemoteApplicationID(&caller_instance_id)); |
344 Instance* instance = nullptr; | 337 Instance* instance = nullptr; |
345 for (const auto& entry : identity_to_instance_) { | 338 for (const auto& entry : identity_to_instance_) { |
346 if (entry.second->id() == caller_instance_id) { | 339 if (entry.second->id() == caller_instance_id) { |
347 instance = entry.second; | 340 instance = entry.second; |
348 break; | 341 break; |
349 } | 342 } |
350 } | 343 } |
351 DCHECK(instance); | 344 DCHECK(instance); |
352 return instance->AcceptConnection(connection); | 345 return instance->AcceptConnection(connection); |
353 } | 346 } |
354 | 347 |
355 //////////////////////////////////////////////////////////////////////////////// | 348 //////////////////////////////////////////////////////////////////////////////// |
356 // ApplicationManager, private: | 349 // Shell, private: |
357 | 350 |
358 void ApplicationManager::InitPackageManager( | 351 void Shell::InitPackageManager( |
359 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { | 352 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { |
360 scoped_ptr<Loader> loader( | 353 scoped_ptr<Loader> loader( |
361 new package_manager::Loader(file_task_runner_, std::move(app_catalog))); | 354 new package_manager::Loader(file_task_runner_, std::move(app_catalog))); |
362 Loader* loader_raw = loader.get(); | 355 Loader* loader_raw = loader.get(); |
363 std::string name = kPackageManagerName; | 356 std::string name = kPackageManagerName; |
364 SetLoaderForName(std::move(loader), name); | 357 SetLoaderForName(std::move(loader), name); |
365 | 358 |
366 mojom::ShellClientRequest request; | 359 mojom::ShellClientRequest request; |
367 CreateInstance(Identity(name), &request); | 360 CreateInstance(Identity(name), &request); |
368 loader_raw->Load(name, std::move(request)); | 361 loader_raw->Load(name, std::move(request)); |
369 | 362 |
370 ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); | 363 ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); |
371 | 364 |
372 // Seed the catalog with manifest info for the shell & package manager. | 365 // Seed the catalog with manifest info for the shell & package manager. |
373 if (file_task_runner_) { | 366 if (file_task_runner_) { |
374 shell_resolver_->ResolveMojoName(name, base::Bind(&EmptyResolverCallback)); | 367 shell_resolver_->ResolveMojoName(name, base::Bind(&EmptyResolverCallback)); |
375 shell_resolver_->ResolveMojoName("mojo:shell", | 368 shell_resolver_->ResolveMojoName("mojo:shell", |
376 base::Bind(&EmptyResolverCallback)); | 369 base::Bind(&EmptyResolverCallback)); |
377 } | 370 } |
378 } | 371 } |
379 | 372 |
380 void ApplicationManager::TerminateShellConnections() { | 373 void Shell::TerminateShellConnections() { |
381 STLDeleteValues(&identity_to_instance_); | 374 STLDeleteValues(&identity_to_instance_); |
382 } | 375 } |
383 | 376 |
384 void ApplicationManager::OnInstanceError(Instance* instance) { | 377 void Shell::OnInstanceError(Instance* instance) { |
385 const Identity identity = instance->identity(); | 378 const Identity identity = instance->identity(); |
386 // Remove the shell. | 379 // Remove the shell. |
387 auto it = identity_to_instance_.find(identity); | 380 auto it = identity_to_instance_.find(identity); |
388 DCHECK(it != identity_to_instance_.end()); | 381 DCHECK(it != identity_to_instance_.end()); |
389 int id = instance->id(); | 382 int id = instance->id(); |
390 delete it->second; | 383 delete it->second; |
391 identity_to_instance_.erase(it); | 384 identity_to_instance_.erase(it); |
392 instance_listeners_.ForAllPtrs([this, id](mojom::InstanceListener* listener) { | 385 instance_listeners_.ForAllPtrs([this, id](mojom::InstanceListener* listener) { |
393 listener->InstanceDestroyed(id); | 386 listener->InstanceDestroyed(id); |
394 }); | 387 }); |
395 if (!instance_quit_callback_.is_null()) | 388 if (!instance_quit_callback_.is_null()) |
396 instance_quit_callback_.Run(identity); | 389 instance_quit_callback_.Run(identity); |
397 } | 390 } |
398 | 391 |
399 ApplicationManager::Instance* ApplicationManager::GetExistingInstance( | 392 Shell::Instance* Shell::GetExistingInstance(const Identity& identity) const { |
400 const Identity& identity) const { | |
401 const auto& it = identity_to_instance_.find(identity); | 393 const auto& it = identity_to_instance_.find(identity); |
402 return it != identity_to_instance_.end() ? it->second : nullptr; | 394 return it != identity_to_instance_.end() ? it->second : nullptr; |
403 } | 395 } |
404 | 396 |
405 void ApplicationManager::NotifyPIDAvailable(uint32_t id, base::ProcessId pid) { | 397 void Shell::NotifyPIDAvailable(uint32_t id, base::ProcessId pid) { |
406 instance_listeners_.ForAllPtrs([id, pid](mojom::InstanceListener* listener) { | 398 instance_listeners_.ForAllPtrs([id, pid](mojom::InstanceListener* listener) { |
407 listener->InstancePIDAvailable(id, pid); | 399 listener->InstancePIDAvailable(id, pid); |
408 }); | 400 }); |
409 } | 401 } |
410 | 402 |
411 bool ApplicationManager::ConnectToExistingInstance( | 403 bool Shell::ConnectToExistingInstance(scoped_ptr<ConnectParams>* params) { |
412 scoped_ptr<ConnectParams>* params) { | |
413 Instance* instance = GetExistingInstance((*params)->target()); | 404 Instance* instance = GetExistingInstance((*params)->target()); |
414 if (!instance) { | 405 if (!instance) { |
415 Identity root_identity = (*params)->target(); | 406 Identity root_identity = (*params)->target(); |
416 root_identity.set_user_id(mojom::Connector::kUserRoot); | 407 root_identity.set_user_id(mojom::Connector::kUserRoot); |
417 instance = GetExistingInstance(root_identity); | 408 instance = GetExistingInstance(root_identity); |
418 if (!instance) return false; | 409 if (!instance) return false; |
419 } | 410 } |
420 instance->ConnectToClient(std::move(*params)); | 411 instance->ConnectToClient(std::move(*params)); |
421 return true; | 412 return true; |
422 } | 413 } |
423 | 414 |
424 ApplicationManager::Instance* ApplicationManager::CreateInstance( | 415 Shell::Instance* Shell::CreateInstance(const Identity& target_id, |
425 const Identity& target_id, | 416 mojom::ShellClientRequest* request) { |
426 mojom::ShellClientRequest* request) { | |
427 mojom::ShellClientPtr shell_client; | 417 mojom::ShellClientPtr shell_client; |
428 *request = GetProxy(&shell_client); | 418 *request = GetProxy(&shell_client); |
429 Instance* instance = new Instance(std::move(shell_client), this, target_id); | 419 Instance* instance = new Instance(std::move(shell_client), this, target_id); |
430 DCHECK(identity_to_instance_.find(target_id) == | 420 DCHECK(identity_to_instance_.find(target_id) == |
431 identity_to_instance_.end()); | 421 identity_to_instance_.end()); |
432 identity_to_instance_[target_id] = instance; | 422 identity_to_instance_[target_id] = instance; |
433 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); | 423 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); |
434 instance_listeners_.ForAllPtrs( | 424 instance_listeners_.ForAllPtrs( |
435 [this, &info](mojom::InstanceListener* listener) { | 425 [this, &info](mojom::InstanceListener* listener) { |
436 listener->InstanceCreated(info.Clone()); | 426 listener->InstanceCreated(info.Clone()); |
437 }); | 427 }); |
438 instance->InitializeClient(); | 428 instance->InitializeClient(); |
439 return instance; | 429 return instance; |
440 } | 430 } |
441 | 431 |
442 void ApplicationManager::CreateInstanceForFactory( | 432 void Shell::CreateInstanceForFactory( |
443 mojom::ShellClientFactoryPtr factory, | 433 mojom::ShellClientFactoryPtr factory, |
444 const String& name, | 434 const String& name, |
445 uint32_t user_id, | 435 uint32_t user_id, |
446 mojom::CapabilityFilterPtr filter, | 436 mojom::CapabilityFilterPtr filter, |
447 mojom::PIDReceiverRequest pid_receiver) { | 437 mojom::PIDReceiverRequest pid_receiver) { |
448 DCHECK(user_id != mojom::Connector::kUserInherit); | 438 DCHECK(user_id != mojom::Connector::kUserInherit); |
449 // We don't call ConnectToClient() here since the instance was created | 439 // We don't call ConnectToClient() here since the instance was created |
450 // manually by other code, not in response to a Connect() request. The newly | 440 // manually by other code, not in response to a Connect() request. The newly |
451 // created instance is identified by |name| and may be subsequently reached by | 441 // created instance is identified by |name| and may be subsequently reached by |
452 // client code using this identity. | 442 // client code using this identity. |
453 Identity target_id(name, std::string(), mojom::Connector::kUserRoot); | 443 Identity target_id(name, std::string(), mojom::Connector::kUserRoot); |
454 target_id.set_filter(filter->filter.To<CapabilityFilter>()); | 444 target_id.set_filter(filter->filter.To<CapabilityFilter>()); |
455 mojom::ShellClientRequest request; | 445 mojom::ShellClientRequest request; |
456 Instance* instance = CreateInstance(target_id, &request); | 446 Instance* instance = CreateInstance(target_id, &request); |
457 native_runners_.push_back( | 447 native_runners_.push_back( |
458 instance->StartWithFactory(std::move(factory), name, std::move(request), | 448 instance->StartWithFactory(std::move(factory), name, std::move(request), |
459 std::move(pid_receiver), | 449 std::move(pid_receiver), |
460 native_runner_factory_.get())); | 450 native_runner_factory_.get())); |
461 } | 451 } |
462 | 452 |
463 void ApplicationManager::AddInstanceListener( | 453 void Shell::AddInstanceListener(mojom::InstanceListenerPtr listener) { |
464 mojom::InstanceListenerPtr listener) { | |
465 // TODO(beng): filter instances provided by those visible to this client. | 454 // TODO(beng): filter instances provided by those visible to this client. |
466 Array<mojom::InstanceInfoPtr> instances; | 455 Array<mojom::InstanceInfoPtr> instances; |
467 for (auto& instance : identity_to_instance_) | 456 for (auto& instance : identity_to_instance_) |
468 instances.push_back(instance.second->CreateInstanceInfo()); | 457 instances.push_back(instance.second->CreateInstanceInfo()); |
469 listener->SetExistingInstances(std::move(instances)); | 458 listener->SetExistingInstances(std::move(instances)); |
470 | 459 |
471 instance_listeners_.AddInterfacePtr(std::move(listener)); | 460 instance_listeners_.AddInterfacePtr(std::move(listener)); |
472 } | 461 } |
473 | 462 |
474 void ApplicationManager::CreateShellClient( | 463 void Shell::CreateShellClient(const Identity& source, |
475 const Identity& source, | 464 const Identity& shell_client_factory, |
476 const Identity& shell_client_factory, | 465 const std::string& name, |
477 const std::string& name, | 466 mojom::ShellClientRequest request) { |
478 mojom::ShellClientRequest request) { | |
479 mojom::ShellClientFactory* factory = | 467 mojom::ShellClientFactory* factory = |
480 GetShellClientFactory(shell_client_factory, source); | 468 GetShellClientFactory(shell_client_factory, source); |
481 factory->CreateShellClient(std::move(request), name); | 469 factory->CreateShellClient(std::move(request), name); |
482 } | 470 } |
483 | 471 |
484 mojom::ShellClientFactory* ApplicationManager::GetShellClientFactory( | 472 mojom::ShellClientFactory* Shell::GetShellClientFactory( |
485 const Identity& shell_client_factory_identity, | 473 const Identity& shell_client_factory_identity, |
486 const Identity& source_identity) { | 474 const Identity& source_identity) { |
487 auto it = shell_client_factories_.find(shell_client_factory_identity); | 475 auto it = shell_client_factories_.find(shell_client_factory_identity); |
488 if (it != shell_client_factories_.end()) | 476 if (it != shell_client_factories_.end()) |
489 return it->second.get(); | 477 return it->second.get(); |
490 | 478 |
491 mojom::ShellClientFactoryPtr factory; | 479 mojom::ShellClientFactoryPtr factory; |
492 // TODO(beng): we should forward the original source identity! | 480 // TODO(beng): we should forward the original source identity! |
493 ConnectToInterface(this, source_identity, shell_client_factory_identity, | 481 ConnectToInterface(this, source_identity, shell_client_factory_identity, |
494 &factory); | 482 &factory); |
495 mojom::ShellClientFactory* factory_interface = factory.get(); | 483 mojom::ShellClientFactory* factory_interface = factory.get(); |
496 factory.set_connection_error_handler( | 484 factory.set_connection_error_handler( |
497 base::Bind(&ApplicationManager::OnShellClientFactoryLost, | 485 base::Bind(&Shell::OnShellClientFactoryLost, |
498 weak_ptr_factory_.GetWeakPtr(), | 486 weak_ptr_factory_.GetWeakPtr(), |
499 shell_client_factory_identity)); | 487 shell_client_factory_identity)); |
500 shell_client_factories_[shell_client_factory_identity] = std::move(factory); | 488 shell_client_factories_[shell_client_factory_identity] = std::move(factory); |
501 return factory_interface; | 489 return factory_interface; |
502 } | 490 } |
503 | 491 |
504 void ApplicationManager::OnShellClientFactoryLost(const Identity& which) { | 492 void Shell::OnShellClientFactoryLost(const Identity& which) { |
505 // Remove the mapping. | 493 // Remove the mapping. |
506 auto it = shell_client_factories_.find(which); | 494 auto it = shell_client_factories_.find(which); |
507 DCHECK(it != shell_client_factories_.end()); | 495 DCHECK(it != shell_client_factories_.end()); |
508 shell_client_factories_.erase(it); | 496 shell_client_factories_.erase(it); |
509 } | 497 } |
510 | 498 |
511 void ApplicationManager::OnGotResolvedName( | 499 void Shell::OnGotResolvedName(scoped_ptr<ConnectParams> params, |
512 scoped_ptr<ConnectParams> params, | 500 const String& resolved_name, |
513 const String& resolved_name, | 501 const String& resolved_qualifier, |
514 const String& resolved_qualifier, | 502 mojom::CapabilityFilterPtr base_filter, |
515 mojom::CapabilityFilterPtr base_filter, | 503 const String& file_url) { |
516 const String& file_url) { | |
517 std::string qualifier = params->target().qualifier(); | 504 std::string qualifier = params->target().qualifier(); |
518 if (qualifier == GetNamePath(params->target().name())) | 505 if (qualifier == GetNamePath(params->target().name())) |
519 qualifier = resolved_qualifier; | 506 qualifier = resolved_qualifier; |
520 Identity target(params->target().name(), qualifier, | 507 Identity target(params->target().name(), qualifier, |
521 params->target().user_id()); | 508 params->target().user_id()); |
522 params->set_target(target); | 509 params->set_target(target); |
523 | 510 |
524 // It's possible that when this manifest request was issued, another one was | 511 // It's possible that when this manifest request was issued, another one was |
525 // already in-progress and completed by the time this one did, and so the | 512 // already in-progress and completed by the time this one did, and so the |
526 // requested application may already be running. | 513 // requested application may already be running. |
(...skipping 26 matching lines...) Expand all Loading... |
553 target.name(), std::move(request)); | 540 target.name(), std::move(request)); |
554 } else { | 541 } else { |
555 bool start_sandboxed = false; | 542 bool start_sandboxed = false; |
556 native_runners_.push_back( | 543 native_runners_.push_back( |
557 instance->StartWithFileURL(file_url.To<GURL>(), std::move(request), | 544 instance->StartWithFileURL(file_url.To<GURL>(), std::move(request), |
558 start_sandboxed, | 545 start_sandboxed, |
559 native_runner_factory_.get())); | 546 native_runner_factory_.get())); |
560 } | 547 } |
561 } | 548 } |
562 | 549 |
563 bool ApplicationManager::LoadWithLoader(const Identity& target, | 550 bool Shell::LoadWithLoader(const Identity& target, |
564 mojom::ShellClientRequest* request) { | 551 mojom::ShellClientRequest* request) { |
565 Loader* loader = GetLoaderForName(target.name()); | 552 Loader* loader = GetLoaderForName(target.name()); |
566 if (!loader) | 553 if (!loader) |
567 return false; | 554 return false; |
568 loader->Load(target.name(), std::move(*request)); | 555 loader->Load(target.name(), std::move(*request)); |
569 return true; | 556 return true; |
570 } | 557 } |
571 | 558 |
572 Loader* ApplicationManager::GetLoaderForName(const std::string& name) { | 559 Loader* Shell::GetLoaderForName(const std::string& name) { |
573 auto name_it = name_to_loader_.find(name); | 560 auto name_it = name_to_loader_.find(name); |
574 if (name_it != name_to_loader_.end()) | 561 if (name_it != name_to_loader_.end()) |
575 return name_it->second; | 562 return name_it->second; |
576 return default_loader_.get(); | 563 return default_loader_.get(); |
577 } | 564 } |
578 | 565 |
579 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 566 void Shell::CleanupRunner(NativeRunner* runner) { |
580 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 567 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
581 if (it->get() == runner) { | 568 if (it->get() == runner) { |
582 native_runners_.erase(it); | 569 native_runners_.erase(it); |
583 return; | 570 return; |
584 } | 571 } |
585 } | 572 } |
586 } | 573 } |
587 | 574 |
588 } // namespace shell | 575 } // namespace shell |
589 } // namespace mojo | 576 } // namespace mojo |
OLD | NEW |