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/shell.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 |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "mojo/shell/public/interfaces/shell.mojom.h" | 30 #include "mojo/shell/public/interfaces/shell.mojom.h" |
31 #include "mojo/shell/public/interfaces/shell_client.mojom.h" | 31 #include "mojo/shell/public/interfaces/shell_client.mojom.h" |
32 #include "mojo/util/filename_util.h" | 32 #include "mojo/util/filename_util.h" |
33 | 33 |
34 namespace mojo { | 34 namespace mojo { |
35 namespace shell { | 35 namespace shell { |
36 namespace { | 36 namespace { |
37 const char kPackageManagerName[] = "mojo:package_manager"; | 37 const char kPackageManagerName[] = "mojo:package_manager"; |
38 | 38 |
39 void EmptyResolverCallback(const String& resolved_name, | 39 void EmptyResolverCallback(const String& resolved_name, |
40 const String& resolved_qualifier, | 40 const String& resolved_instance, |
41 mojom::CapabilityFilterPtr base_filter, | 41 mojom::CapabilityFilterPtr base_filter, |
42 const String& file_url) {} | 42 const String& file_url) {} |
43 | 43 |
44 } | 44 } |
45 | 45 |
| 46 Identity CreateShellIdentity() { |
| 47 return Identity("mojo:shell", mojom::kRootUserID); |
| 48 } |
| 49 |
| 50 CapabilityFilter GetPermissiveCapabilityFilter() { |
| 51 CapabilityFilter filter; |
| 52 AllowedInterfaces interfaces; |
| 53 interfaces.insert("*"); |
| 54 filter["*"] = interfaces; |
| 55 return filter; |
| 56 } |
| 57 |
| 58 AllowedInterfaces GetAllowedInterfaces(const CapabilityFilter& filter, |
| 59 const Identity& identity) { |
| 60 // Start by looking for interfaces specific to the supplied identity. |
| 61 auto it = filter.find(identity.name()); |
| 62 if (it != filter.end()) |
| 63 return it->second; |
| 64 |
| 65 // Fall back to looking for a wildcard rule. |
| 66 it = filter.find("*"); |
| 67 if (filter.size() == 1 && it != filter.end()) |
| 68 return it->second; |
| 69 |
| 70 // Finally, nothing is allowed. |
| 71 return AllowedInterfaces(); |
| 72 } |
| 73 |
46 // Encapsulates a connection to an instance of an application, tracked by the | 74 // Encapsulates a connection to an instance of an application, tracked by the |
47 // shell's Shell. | 75 // shell's Shell. |
48 class Shell::Instance : public mojom::Connector, | 76 class Shell::Instance : public mojom::Connector, |
49 public mojom::PIDReceiver, | 77 public mojom::PIDReceiver, |
50 public ShellClient, | 78 public ShellClient, |
51 public InterfaceFactory<mojom::Shell>, | 79 public InterfaceFactory<mojom::Shell>, |
52 public mojom::Shell { | 80 public mojom::Shell { |
53 public: | 81 public: |
54 Instance(mojom::ShellClientPtr shell_client, | 82 Instance(mojom::ShellClientPtr shell_client, |
55 mojo::shell::Shell* shell, | 83 mojo::shell::Shell* shell, |
56 const Identity& identity) | 84 const Identity& identity, |
| 85 const CapabilityFilter& filter) |
57 : shell_(shell), | 86 : shell_(shell), |
58 id_(GenerateUniqueID()), | 87 id_(GenerateUniqueID()), |
59 identity_(identity), | 88 identity_(identity), |
60 allow_any_application_(identity.filter().size() == 1 && | 89 filter_(filter), |
61 identity.filter().count("*") == 1), | 90 allow_any_application_(filter.size() == 1 && filter.count("*") == 1), |
62 shell_client_(std::move(shell_client)), | 91 shell_client_(std::move(shell_client)), |
63 pid_receiver_binding_(this), | 92 pid_receiver_binding_(this), |
64 weak_factory_(this) { | 93 weak_factory_(this) { |
65 if (identity_.name() == "mojo:shell" || | 94 if (identity_.name() == "mojo:shell" || |
66 shell_->GetLoaderForName(identity_.name())) { | 95 shell_->GetLoaderForName(identity_.name())) { |
67 pid_ = base::Process::Current().Pid(); | 96 pid_ = base::Process::Current().Pid(); |
68 } | 97 } |
69 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 98 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
70 } | 99 } |
71 | 100 |
72 ~Instance() override {} | 101 ~Instance() override {} |
73 | 102 |
74 void InitializeClient() { | 103 void InitializeClient() { |
75 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), | 104 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), |
76 identity_.name(), identity_.user_id(), id_); | 105 mojom::Identity::From(identity_), id_); |
77 connectors_.set_connection_error_handler( | 106 connectors_.set_connection_error_handler( |
78 base::Bind(&mojo::shell::Shell::OnInstanceError, | 107 base::Bind(&mojo::shell::Shell::OnInstanceError, |
79 base::Unretained(shell_), base::Unretained(this))); | 108 base::Unretained(shell_), base::Unretained(this))); |
80 } | 109 } |
81 | 110 |
82 void ConnectToClient(scoped_ptr<ConnectParams> params) { | 111 void ConnectToClient(scoped_ptr<ConnectParams> params) { |
83 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 112 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
84 identity_.user_id(), id_); | 113 identity_.user_id(), id_); |
| 114 uint32_t source_id = mojom::kInvalidInstanceID; |
85 AllowedInterfaces interfaces; | 115 AllowedInterfaces interfaces; |
86 interfaces.insert("*"); | 116 interfaces.insert("*"); |
87 if (!params->source().is_null()) | |
88 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); | |
89 | |
90 Instance* source = shell_->GetExistingInstance(params->source()); | 117 Instance* source = shell_->GetExistingInstance(params->source()); |
91 uint32_t source_id = source ? source->id() : mojom::kInvalidInstanceID; | 118 if (source) { |
| 119 interfaces = GetAllowedInterfaces(source->filter_, identity_); |
| 120 source_id = source->id(); |
| 121 } |
92 shell_client_->AcceptConnection( | 122 shell_client_->AcceptConnection( |
93 params->source().name(), params->source().user_id(), source_id, | 123 mojom::Identity::From(params->source()), source_id, |
94 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), | 124 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), |
95 Array<String>::From(interfaces), params->target().name()); | 125 Array<String>::From(interfaces), params->target().name()); |
96 } | 126 } |
97 | 127 |
98 scoped_ptr<NativeRunner> StartWithFileURL(const GURL& file_url, | 128 scoped_ptr<NativeRunner> StartWithFileURL(const GURL& file_url, |
99 mojom::ShellClientRequest request, | 129 mojom::ShellClientRequest request, |
100 bool start_sandboxed, | 130 bool start_sandboxed, |
101 NativeRunnerFactory* factory) { | 131 NativeRunnerFactory* factory) { |
102 base::FilePath path = util::UrlToFilePath(file_url); | 132 base::FilePath path = util::UrlToFilePath(file_url); |
103 scoped_ptr<NativeRunner> runner = factory->Create(path); | 133 scoped_ptr<NativeRunner> runner = factory->Create(path); |
104 runner_ = runner.get(); | 134 runner_ = runner.get(); |
105 runner_->Start(path, identity_, start_sandboxed, std::move(request), | 135 runner_->Start(path, identity_, start_sandboxed, std::move(request), |
106 base::Bind(&Instance::PIDAvailable, | 136 base::Bind(&Instance::PIDAvailable, |
107 weak_factory_.GetWeakPtr()), | 137 weak_factory_.GetWeakPtr()), |
108 base::Bind(&mojo::shell::Shell::CleanupRunner, | 138 base::Bind(&mojo::shell::Shell::CleanupRunner, |
109 shell_->weak_ptr_factory_.GetWeakPtr(), | 139 shell_->weak_ptr_factory_.GetWeakPtr(), |
110 runner_)); | 140 runner_)); |
111 return runner; | 141 return runner; |
112 } | 142 } |
113 | 143 |
114 mojom::InstanceInfoPtr CreateInstanceInfo() const { | 144 mojom::InstanceInfoPtr CreateInstanceInfo() const { |
115 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); | 145 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); |
116 info->id = id_; | 146 info->id = id_; |
117 info->name = identity_.name(); | 147 info->identity = mojom::Identity::From(identity_); |
118 info->qualifier = identity_.qualifier(); | |
119 info->pid = pid_; | 148 info->pid = pid_; |
120 return info; | 149 return info; |
121 } | 150 } |
122 | 151 |
123 const Identity& identity() const { return identity_; } | 152 const Identity& identity() const { return identity_; } |
124 uint32_t id() const { return id_; } | 153 uint32_t id() const { return id_; } |
125 | 154 |
126 // ShellClient: | 155 // ShellClient: |
127 bool AcceptConnection(Connection* connection) override { | 156 bool AcceptConnection(Connection* connection) override { |
128 connection->AddInterface<mojom::Shell>(this); | 157 connection->AddInterface<mojom::Shell>(this); |
129 return true; | 158 return true; |
130 } | 159 } |
131 | 160 |
132 private: | 161 private: |
133 // mojom::Connector implementation: | 162 // mojom::Connector implementation: |
134 void Connect(const String& app_name, | 163 void Connect(mojom::IdentityPtr target, |
135 const String& user_id, | 164 mojom::InterfaceProviderRequest remote_interfaces, |
136 shell::mojom::InterfaceProviderRequest remote_interfaces, | 165 mojom::InterfaceProviderPtr local_interfaces, |
137 shell::mojom::InterfaceProviderPtr local_interfaces, | |
138 const ConnectCallback& callback) override { | 166 const ConnectCallback& callback) override { |
139 if (!IsValidName(app_name)) { | 167 if (!IsValidName(target->name)) { |
140 LOG(ERROR) << "Error: invalid Name: " << app_name; | 168 LOG(ERROR) << "Error: invalid Name: " << target->name; |
141 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 169 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
142 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 170 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
143 return; | 171 return; |
144 } | 172 } |
145 if (!base::IsValidGUID(user_id)) { | 173 if (!base::IsValidGUID(target->user_id)) { |
146 LOG(ERROR) << "Error: invalid user_id: " << user_id; | 174 LOG(ERROR) << "Error: invalid user_id: " << target->user_id; |
147 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 175 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
148 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 176 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
149 return; | 177 return; |
150 } | 178 } |
151 // TODO(beng): perform checking on policy of whether this instance is | 179 // TODO(beng): perform checking on policy of whether this instance is |
152 // allowed to pass different user_ids. | 180 // allowed to pass different user_ids. |
153 if (allow_any_application_ || | 181 // TODO(beng): perform checking on policy of whether this instance is |
154 identity_.filter().find(app_name) != identity_.filter().end()) { | 182 // allowed to pass non-empty instance identifiers. |
| 183 if (allow_any_application_ || filter_.find(target->name) != filter_.end()) { |
155 scoped_ptr<ConnectParams> params(new ConnectParams); | 184 scoped_ptr<ConnectParams> params(new ConnectParams); |
156 params->set_source(identity_); | 185 params->set_source(identity_); |
157 params->set_target(Identity(app_name, std::string(), user_id)); | 186 params->set_target(target.To<Identity>()); |
158 params->set_remote_interfaces(std::move(remote_interfaces)); | 187 params->set_remote_interfaces(std::move(remote_interfaces)); |
159 params->set_local_interfaces(std::move(local_interfaces)); | 188 params->set_local_interfaces(std::move(local_interfaces)); |
160 params->set_connect_callback(callback); | 189 params->set_connect_callback(callback); |
161 shell_->Connect(std::move(params)); | 190 shell_->Connect(std::move(params)); |
162 } else { | 191 } else { |
163 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 192 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
164 identity_.name() << " to: " << app_name; | 193 identity_.name() << " to: " << target->name; |
165 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 194 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
166 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 195 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
167 } | 196 } |
168 } | 197 } |
169 void Clone(mojom::ConnectorRequest request) override { | 198 void Clone(mojom::ConnectorRequest request) override { |
170 connectors_.AddBinding(this, std::move(request)); | 199 connectors_.AddBinding(this, std::move(request)); |
171 } | 200 } |
172 | 201 |
173 // mojom::PIDReceiver: | 202 // mojom::PIDReceiver: |
174 void SetPID(uint32_t pid) override { | 203 void SetPID(uint32_t pid) override { |
175 PIDAvailable(pid); | 204 PIDAvailable(pid); |
176 } | 205 } |
177 | 206 |
178 // InterfaceFactory<mojom::Shell>: | 207 // InterfaceFactory<mojom::Shell>: |
179 void Create(Connection* connection, | 208 void Create(Connection* connection, |
180 mojom::ShellRequest request) override { | 209 mojom::ShellRequest request) override { |
181 shell_bindings_.AddBinding(this, std::move(request)); | 210 shell_bindings_.AddBinding(this, std::move(request)); |
182 } | 211 } |
183 | 212 |
184 // mojom::Shell implementation: | 213 // mojom::Shell implementation: |
185 void CreateInstance(mojom::ShellClientFactoryPtr factory, | 214 void CreateInstance(mojom::ShellClientFactoryPtr factory, |
186 const String& name, | 215 mojom::IdentityPtr target, |
187 const String& user_id, | |
188 mojom::CapabilityFilterPtr filter, | 216 mojom::CapabilityFilterPtr filter, |
189 mojom::PIDReceiverRequest pid_receiver, | 217 mojom::PIDReceiverRequest pid_receiver, |
190 const CreateInstanceCallback& callback) override { | 218 const CreateInstanceCallback& callback) override { |
191 if (!base::IsValidGUID(user_id)) | 219 if (!base::IsValidGUID(target->user_id)) |
192 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT); | 220 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT); |
| 221 |
| 222 Identity target_id = target.To<Identity>(); |
| 223 |
193 // TODO(beng): perform checking on policy of whether this instance is | 224 // TODO(beng): perform checking on policy of whether this instance is |
194 // allowed to pass different user_ids. | 225 // allowed to pass different user_ids. |
195 std::string user_id_string = user_id; | 226 if (target_id.user_id() == mojom::kInheritUserID) |
196 if (user_id_string == mojom::kInheritUserID) | 227 target_id.set_user_id(identity_.user_id()); |
197 user_id_string = identity_.user_id(); | |
198 | 228 |
| 229 mojom::ShellClientRequest request; |
| 230 Instance* instance = shell_->CreateInstance( |
| 231 target_id, filter->filter.To<CapabilityFilter>(), &request); |
| 232 instance->pid_receiver_binding_.Bind(std::move(pid_receiver)); |
| 233 instance->factory_ = std::move(factory); |
| 234 instance->factory_->CreateShellClient(std::move(request), target->name); |
| 235 callback.Run(mojom::ConnectResult::SUCCEEDED); |
199 // We don't call ConnectToClient() here since the instance was created | 236 // We don't call ConnectToClient() here since the instance was created |
200 // manually by other code, not in response to a Connect() request. The newly | 237 // manually by other code, not in response to a Connect() request. The newly |
201 // created instance is identified by |name| and may be subsequently reached | 238 // created instance is identified by |name| and may be subsequently reached |
202 // by client code using this identity. | 239 // by client code using this identity. |
203 Identity target_id(name, std::string(), user_id_string); | |
204 target_id.set_filter(filter->filter.To<CapabilityFilter>()); | |
205 mojom::ShellClientRequest request; | |
206 Instance* instance = shell_->CreateInstance(target_id, &request); | |
207 instance->pid_receiver_binding_.Bind(std::move(pid_receiver)); | |
208 instance->factory_ = std::move(factory); | |
209 instance->factory_->CreateShellClient(std::move(request), name); | |
210 callback.Run(mojom::ConnectResult::SUCCEEDED); | |
211 } | 240 } |
212 void AddInstanceListener(mojom::InstanceListenerPtr listener) override { | 241 void AddInstanceListener(mojom::InstanceListenerPtr listener) override { |
213 // TODO(beng): this should only track the instances matching this user, and | 242 // TODO(beng): this should only track the instances matching this user, and |
214 // root. | 243 // root. |
215 shell_->AddInstanceListener(std::move(listener)); | 244 shell_->AddInstanceListener(std::move(listener)); |
216 } | 245 } |
217 | 246 |
218 uint32_t GenerateUniqueID() const { | 247 uint32_t GenerateUniqueID() const { |
219 static uint32_t id = mojom::kInvalidInstanceID; | 248 static uint32_t id = mojom::kInvalidInstanceID; |
220 ++id; | 249 ++id; |
221 CHECK_NE(mojom::kInvalidInstanceID, id); | 250 CHECK_NE(mojom::kInvalidInstanceID, id); |
222 return id; | 251 return id; |
223 } | 252 } |
224 | 253 |
225 void PIDAvailable(base::ProcessId pid) { | 254 void PIDAvailable(base::ProcessId pid) { |
226 pid_ = pid; | 255 pid_ = pid; |
227 shell_->NotifyPIDAvailable(id_, pid_); | 256 shell_->NotifyPIDAvailable(id_, pid_); |
228 } | 257 } |
229 | 258 |
230 mojo::shell::Shell* const shell_; | 259 mojo::shell::Shell* const shell_; |
231 // An id that identifies this instance. Distinct from pid, as a single process | 260 // An id that identifies this instance. Distinct from pid, as a single process |
232 // may vend multiple application instances, and this object may exist before a | 261 // may vend multiple application instances, and this object may exist before a |
233 // process is launched. | 262 // process is launched. |
234 const uint32_t id_; | 263 const uint32_t id_; |
235 const Identity identity_; | 264 const Identity identity_; |
| 265 const CapabilityFilter filter_; |
236 const bool allow_any_application_; | 266 const bool allow_any_application_; |
237 mojom::ShellClientPtr shell_client_; | 267 mojom::ShellClientPtr shell_client_; |
238 Binding<mojom::PIDReceiver> pid_receiver_binding_; | 268 Binding<mojom::PIDReceiver> pid_receiver_binding_; |
239 BindingSet<mojom::Connector> connectors_; | 269 BindingSet<mojom::Connector> connectors_; |
240 BindingSet<mojom::Shell> shell_bindings_; | 270 BindingSet<mojom::Shell> shell_bindings_; |
241 mojom::ShellClientFactoryPtr factory_; | 271 mojom::ShellClientFactoryPtr factory_; |
242 NativeRunner* runner_ = nullptr; | 272 NativeRunner* runner_ = nullptr; |
243 base::ProcessId pid_ = base::kNullProcessId; | 273 base::ProcessId pid_ = base::kNullProcessId; |
244 base::WeakPtrFactory<Instance> weak_factory_; | 274 base::WeakPtrFactory<Instance> weak_factory_; |
245 | 275 |
246 DISALLOW_COPY_AND_ASSIGN(Instance); | 276 DISALLOW_COPY_AND_ASSIGN(Instance); |
247 }; | 277 }; |
248 | 278 |
249 // static | 279 // static |
250 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} | 280 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} |
251 Shell::TestAPI::~TestAPI() {} | 281 Shell::TestAPI::~TestAPI() {} |
252 | 282 |
253 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { | 283 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { |
254 return shell_->identity_to_instance_.find(Identity(name)) != | 284 for (const auto& entry : shell_->identity_to_instance_) { |
255 shell_->identity_to_instance_.end(); | 285 if (entry.first.name() == name) |
| 286 return true; |
| 287 } |
| 288 return false; |
256 } | 289 } |
257 | 290 |
258 //////////////////////////////////////////////////////////////////////////////// | 291 //////////////////////////////////////////////////////////////////////////////// |
259 // Shell, public: | 292 // Shell, public: |
260 | 293 |
261 Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory, | 294 Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory, |
262 base::TaskRunner* file_task_runner, | 295 base::TaskRunner* file_task_runner, |
263 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) | 296 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) |
264 : file_task_runner_(file_task_runner), | 297 : file_task_runner_(file_task_runner), |
265 native_runner_factory_(std::move(native_runner_factory)), | 298 native_runner_factory_(std::move(native_runner_factory)), |
266 weak_ptr_factory_(this) { | 299 weak_ptr_factory_(this) { |
267 mojom::ShellClientRequest request; | 300 mojom::ShellClientRequest request; |
268 CreateInstance(CreateShellIdentity(), &request); | 301 CreateInstance(CreateShellIdentity(), GetPermissiveCapabilityFilter(), |
| 302 &request); |
269 shell_connection_.reset(new ShellConnection(this, std::move(request))); | 303 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
270 | 304 |
271 InitPackageManager(std::move(app_catalog)); | 305 InitPackageManager(std::move(app_catalog)); |
272 } | 306 } |
273 | 307 |
274 Shell::~Shell() { | 308 Shell::~Shell() { |
275 TerminateShellConnections(); | 309 TerminateShellConnections(); |
276 STLDeleteValues(&name_to_loader_); | 310 STLDeleteValues(&name_to_loader_); |
277 for (auto& runner : native_runners_) | 311 for (auto& runner : native_runners_) |
278 runner.reset(); | 312 runner.reset(); |
(...skipping 12 matching lines...) Expand all Loading... |
291 | 325 |
292 if (params->target().user_id() == mojom::kInheritUserID) { | 326 if (params->target().user_id() == mojom::kInheritUserID) { |
293 Instance* source = GetExistingInstance(params->source()); | 327 Instance* source = GetExistingInstance(params->source()); |
294 Identity target = params->target(); | 328 Identity target = params->target(); |
295 // TODO(beng): we should CHECK source. | 329 // TODO(beng): we should CHECK source. |
296 target.set_user_id(source ? source->identity().user_id() | 330 target.set_user_id(source ? source->identity().user_id() |
297 : mojom::kRootUserID); | 331 : mojom::kRootUserID); |
298 params->set_target(target); | 332 params->set_target(target); |
299 } | 333 } |
300 | 334 |
| 335 CHECK(params->target().user_id() != mojom::kInheritUserID); |
| 336 |
301 // Connect to an existing matching instance, if possible. | 337 // Connect to an existing matching instance, if possible. |
302 if (ConnectToExistingInstance(¶ms)) | 338 if (ConnectToExistingInstance(¶ms)) |
303 return; | 339 return; |
304 | 340 |
305 std::string name = params->target().name(); | 341 std::string name = params->target().name(); |
306 shell_resolver_->ResolveMojoName( | 342 shell_resolver_->ResolveMojoName( |
307 name, | 343 name, |
308 base::Bind(&Shell::OnGotResolvedName, | 344 base::Bind(&Shell::OnGotResolvedName, |
309 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); | 345 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); |
310 } | 346 } |
311 | 347 |
312 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( | 348 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( |
313 const std::string& name) { | 349 const std::string& name) { |
314 DCHECK(!embedder_instance_); | 350 DCHECK(!embedder_instance_); |
315 | 351 |
316 mojo::shell::Identity target(name, std::string(), mojom::kRootUserID); | 352 Identity target(name, mojom::kRootUserID); |
317 target.set_filter(GetPermissiveCapabilityFilter()); | |
318 DCHECK(!GetExistingInstance(target)); | 353 DCHECK(!GetExistingInstance(target)); |
319 | 354 |
320 mojom::ShellClientRequest request; | 355 mojom::ShellClientRequest request; |
321 embedder_instance_ = CreateInstance(target, &request); | 356 embedder_instance_ = CreateInstance( |
| 357 target, GetPermissiveCapabilityFilter(), &request); |
322 DCHECK(embedder_instance_); | 358 DCHECK(embedder_instance_); |
323 | 359 |
324 return request; | 360 return request; |
325 } | 361 } |
326 | 362 |
327 void Shell::SetLoaderForName(scoped_ptr<Loader> loader, | 363 void Shell::SetLoaderForName(scoped_ptr<Loader> loader, |
328 const std::string& name) { | 364 const std::string& name) { |
329 NameToLoaderMap::iterator it = name_to_loader_.find(name); | 365 NameToLoaderMap::iterator it = name_to_loader_.find(name); |
330 if (it != name_to_loader_.end()) | 366 if (it != name_to_loader_.end()) |
331 delete it->second; | 367 delete it->second; |
(...skipping 24 matching lines...) Expand all Loading... |
356 | 392 |
357 void Shell::InitPackageManager( | 393 void Shell::InitPackageManager( |
358 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { | 394 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { |
359 scoped_ptr<Loader> loader( | 395 scoped_ptr<Loader> loader( |
360 new package_manager::Loader(file_task_runner_, std::move(app_catalog))); | 396 new package_manager::Loader(file_task_runner_, std::move(app_catalog))); |
361 Loader* loader_raw = loader.get(); | 397 Loader* loader_raw = loader.get(); |
362 std::string name = kPackageManagerName; | 398 std::string name = kPackageManagerName; |
363 SetLoaderForName(std::move(loader), name); | 399 SetLoaderForName(std::move(loader), name); |
364 | 400 |
365 mojom::ShellClientRequest request; | 401 mojom::ShellClientRequest request; |
366 CreateInstance(Identity(name), &request); | 402 // TODO(beng): Does the package manager actually have to be run with a |
| 403 // permissive filter? |
| 404 Identity identity(name, mojom::kRootUserID); |
| 405 CreateInstance(identity, GetPermissiveCapabilityFilter(), &request); |
367 loader_raw->Load(name, std::move(request)); | 406 loader_raw->Load(name, std::move(request)); |
368 | 407 |
369 ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); | 408 ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); |
370 | 409 |
371 // Seed the catalog with manifest info for the shell & package manager. | 410 // Seed the catalog with manifest info for the shell & package manager. |
372 if (file_task_runner_) { | 411 if (file_task_runner_) { |
373 shell_resolver_->ResolveMojoName(name, base::Bind(&EmptyResolverCallback)); | 412 shell_resolver_->ResolveMojoName(name, base::Bind(&EmptyResolverCallback)); |
374 shell_resolver_->ResolveMojoName("mojo:shell", | 413 shell_resolver_->ResolveMojoName("mojo:shell", |
375 base::Bind(&EmptyResolverCallback)); | 414 base::Bind(&EmptyResolverCallback)); |
376 } | 415 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 Identity root_identity = (*params)->target(); | 451 Identity root_identity = (*params)->target(); |
413 root_identity.set_user_id(mojom::kRootUserID); | 452 root_identity.set_user_id(mojom::kRootUserID); |
414 instance = GetExistingInstance(root_identity); | 453 instance = GetExistingInstance(root_identity); |
415 if (!instance) return false; | 454 if (!instance) return false; |
416 } | 455 } |
417 instance->ConnectToClient(std::move(*params)); | 456 instance->ConnectToClient(std::move(*params)); |
418 return true; | 457 return true; |
419 } | 458 } |
420 | 459 |
421 Shell::Instance* Shell::CreateInstance(const Identity& target_id, | 460 Shell::Instance* Shell::CreateInstance(const Identity& target_id, |
| 461 const CapabilityFilter& filter, |
422 mojom::ShellClientRequest* request) { | 462 mojom::ShellClientRequest* request) { |
| 463 CHECK(target_id.user_id() != mojom::kInheritUserID); |
423 mojom::ShellClientPtr shell_client; | 464 mojom::ShellClientPtr shell_client; |
424 *request = GetProxy(&shell_client); | 465 *request = GetProxy(&shell_client); |
425 Instance* instance = new Instance(std::move(shell_client), this, target_id); | 466 Instance* instance = |
| 467 new Instance(std::move(shell_client), this, target_id, filter); |
426 DCHECK(identity_to_instance_.find(target_id) == | 468 DCHECK(identity_to_instance_.find(target_id) == |
427 identity_to_instance_.end()); | 469 identity_to_instance_.end()); |
428 identity_to_instance_[target_id] = instance; | 470 identity_to_instance_[target_id] = instance; |
429 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); | 471 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); |
430 instance_listeners_.ForAllPtrs( | 472 instance_listeners_.ForAllPtrs( |
431 [this, &info](mojom::InstanceListener* listener) { | 473 [this, &info](mojom::InstanceListener* listener) { |
432 listener->InstanceCreated(info.Clone()); | 474 listener->InstanceCreated(info.Clone()); |
433 }); | 475 }); |
434 instance->InitializeClient(); | 476 instance->InitializeClient(); |
435 return instance; | 477 return instance; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 518 |
477 void Shell::OnShellClientFactoryLost(const Identity& which) { | 519 void Shell::OnShellClientFactoryLost(const Identity& which) { |
478 // Remove the mapping. | 520 // Remove the mapping. |
479 auto it = shell_client_factories_.find(which); | 521 auto it = shell_client_factories_.find(which); |
480 DCHECK(it != shell_client_factories_.end()); | 522 DCHECK(it != shell_client_factories_.end()); |
481 shell_client_factories_.erase(it); | 523 shell_client_factories_.erase(it); |
482 } | 524 } |
483 | 525 |
484 void Shell::OnGotResolvedName(scoped_ptr<ConnectParams> params, | 526 void Shell::OnGotResolvedName(scoped_ptr<ConnectParams> params, |
485 const String& resolved_name, | 527 const String& resolved_name, |
486 const String& resolved_qualifier, | 528 const String& resolved_instance, |
487 mojom::CapabilityFilterPtr base_filter, | 529 mojom::CapabilityFilterPtr base_filter, |
488 const String& file_url) { | 530 const String& file_url) { |
489 std::string qualifier = params->target().qualifier(); | 531 std::string instance_name = params->target().instance(); |
490 if (qualifier == GetNamePath(params->target().name())) | 532 if (instance_name == GetNamePath(params->target().name())) |
491 qualifier = resolved_qualifier; | 533 instance_name = resolved_instance; |
492 Identity target(params->target().name(), qualifier, | 534 Identity target(params->target().name(), params->target().user_id(), |
493 params->target().user_id()); | 535 instance_name); |
494 params->set_target(target); | 536 params->set_target(target); |
495 | 537 |
496 // It's possible that when this manifest request was issued, another one was | 538 // It's possible that when this manifest request was issued, another one was |
497 // already in-progress and completed by the time this one did, and so the | 539 // already in-progress and completed by the time this one did, and so the |
498 // requested application may already be running. | 540 // requested application may already be running. |
499 if (ConnectToExistingInstance(¶ms)) | 541 if (ConnectToExistingInstance(¶ms)) |
500 return; | 542 return; |
501 | 543 |
502 Identity source = params->source(); | 544 Identity source = params->source(); |
503 // |base_filter| can be null when there is no manifest, e.g. for URL types | 545 // |base_filter| can be null when there is no manifest, e.g. for URL types |
504 // not resolvable by the resolver. | 546 // not resolvable by the resolver. |
505 CapabilityFilter filter = GetPermissiveCapabilityFilter(); | 547 CapabilityFilter filter = GetPermissiveCapabilityFilter(); |
506 if (!base_filter.is_null()) | 548 if (!base_filter.is_null()) |
507 filter = base_filter->filter.To<CapabilityFilter>(); | 549 filter = base_filter->filter.To<CapabilityFilter>(); |
508 target.set_filter(filter); | |
509 | 550 |
510 mojom::ShellClientRequest request; | 551 mojom::ShellClientRequest request; |
511 Instance* instance = CreateInstance(target, &request); | 552 Instance* instance = CreateInstance(target, filter, &request); |
512 instance->ConnectToClient(std::move(params)); | 553 instance->ConnectToClient(std::move(params)); |
513 | 554 |
514 if (LoadWithLoader(target, &request)) | 555 if (LoadWithLoader(target, &request)) |
515 return; | 556 return; |
516 | 557 |
517 CHECK(!file_url.is_null() && !base_filter.is_null()); | 558 CHECK(!file_url.is_null() && !base_filter.is_null()); |
518 | 559 |
519 if (target.name() != resolved_name) { | 560 if (target.name() != resolved_name) { |
520 // In cases where a package alias is resolved, we have to use the qualifier | 561 // In cases where a package alias is resolved, we have to use the instance |
521 // from the original request rather than for the package itself, which will | 562 // from the original request rather than for the package itself, which will |
522 // always be the same. | 563 // always be the same. |
523 CreateShellClient( | 564 CreateShellClient( |
524 source, Identity(resolved_name, resolved_qualifier, target.user_id()), | 565 source, Identity(resolved_name, target.user_id(), resolved_instance), |
525 target.name(), std::move(request)); | 566 target.name(), std::move(request)); |
526 } else { | 567 } else { |
527 bool start_sandboxed = false; | 568 bool start_sandboxed = false; |
528 native_runners_.push_back( | 569 native_runners_.push_back( |
529 instance->StartWithFileURL(file_url.To<GURL>(), std::move(request), | 570 instance->StartWithFileURL(file_url.To<GURL>(), std::move(request), |
530 start_sandboxed, | 571 start_sandboxed, |
531 native_runner_factory_.get())); | 572 native_runner_factory_.get())); |
532 } | 573 } |
533 } | 574 } |
534 | 575 |
(...skipping 17 matching lines...) Expand all Loading... |
552 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 593 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
553 if (it->get() == runner) { | 594 if (it->get() == runner) { |
554 native_runners_.erase(it); | 595 native_runners_.erase(it); |
555 return; | 596 return; |
556 } | 597 } |
557 } | 598 } |
558 } | 599 } |
559 | 600 |
560 } // namespace shell | 601 } // namespace shell |
561 } // namespace mojo | 602 } // namespace mojo |
OLD | NEW |