| 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 |