| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/shell/application_manager.h" | 5 #include "mojo/shell/application_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 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/shell_connection.h" | 27 #include "mojo/shell/public/cpp/shell_connection.h" |
| 27 #include "mojo/shell/public/interfaces/application_manager.mojom.h" | 28 #include "mojo/shell/public/interfaces/application_manager.mojom.h" |
| 28 #include "mojo/shell/public/interfaces/shell.mojom.h" | 29 #include "mojo/shell/public/interfaces/shell.mojom.h" |
| 29 #include "mojo/shell/public/interfaces/shell_client.mojom.h" | 30 #include "mojo/shell/public/interfaces/shell_client.mojom.h" |
| 30 #include "mojo/util/filename_util.h" | 31 #include "mojo/util/filename_util.h" |
| 31 | 32 |
| 32 namespace mojo { | 33 namespace mojo { |
| 33 namespace shell { | 34 namespace shell { |
| 34 | 35 |
| 35 // Encapsulates a connection to an instance of an application, tracked by the | 36 // Encapsulates a connection to an instance of an application, tracked by the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 47 identity.filter().count("*") == 1), | 48 identity.filter().count("*") == 1), |
| 48 shell_client_(std::move(shell_client)), | 49 shell_client_(std::move(shell_client)), |
| 49 pid_receiver_binding_(this) { | 50 pid_receiver_binding_(this) { |
| 50 DCHECK_NE(kInvalidApplicationID, id_); | 51 DCHECK_NE(kInvalidApplicationID, id_); |
| 51 } | 52 } |
| 52 | 53 |
| 53 ~Instance() override {} | 54 ~Instance() override {} |
| 54 | 55 |
| 55 void Initialize() { | 56 void Initialize() { |
| 56 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), | 57 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), |
| 57 identity_.url().spec(), id_, identity_.user_id()); | 58 identity_.name(), id_, identity_.user_id()); |
| 58 connectors_.set_connection_error_handler( | 59 connectors_.set_connection_error_handler( |
| 59 base::Bind(&ApplicationManager::OnInstanceError, | 60 base::Bind(&ApplicationManager::OnInstanceError, |
| 60 base::Unretained(manager_), base::Unretained(this))); | 61 base::Unretained(manager_), base::Unretained(this))); |
| 61 } | 62 } |
| 62 | 63 |
| 63 void ConnectToClient(scoped_ptr<ConnectParams> params) { | 64 void ConnectToClient(scoped_ptr<ConnectParams> params) { |
| 64 params->connect_callback().Run(id_); | 65 params->connect_callback().Run(id_); |
| 65 AllowedInterfaces interfaces; | 66 AllowedInterfaces interfaces; |
| 66 interfaces.insert("*"); | 67 interfaces.insert("*"); |
| 67 if (!params->source().is_null()) | 68 if (!params->source().is_null()) |
| 68 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); | 69 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); |
| 69 | 70 |
| 70 Instance* source = manager_->GetExistingInstance(params->source()); | 71 Instance* source = manager_->GetExistingInstance(params->source()); |
| 71 uint32_t source_id = source ? source->id() : kInvalidApplicationID; | 72 uint32_t source_id = source ? source->id() : kInvalidApplicationID; |
| 72 shell_client_->AcceptConnection( | 73 shell_client_->AcceptConnection( |
| 73 params->source().url().spec(), params->source().user_id(), source_id, | 74 params->source().name(), params->source().user_id(), source_id, |
| 74 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), | 75 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), |
| 75 Array<String>::From(interfaces), params->target().url().spec()); | 76 Array<String>::From(interfaces), params->target().name()); |
| 76 } | 77 } |
| 77 | 78 |
| 78 // Required before GetProcessId can be called. | 79 // Required before GetProcessId can be called. |
| 79 void SetNativeRunner(NativeRunner* native_runner) { | 80 void SetNativeRunner(NativeRunner* native_runner) { |
| 80 native_runner_ = native_runner; | 81 native_runner_ = native_runner; |
| 81 } | 82 } |
| 82 | 83 |
| 83 void BindPIDReceiver(mojom::PIDReceiverRequest pid_receiver) { | 84 void BindPIDReceiver(mojom::PIDReceiverRequest pid_receiver) { |
| 84 pid_receiver_binding_.Bind(std::move(pid_receiver)); | 85 pid_receiver_binding_.Bind(std::move(pid_receiver)); |
| 85 } | 86 } |
| 86 | 87 |
| 87 mojom::ShellClient* shell_client() { return shell_client_.get(); } | 88 mojom::ShellClient* shell_client() { return shell_client_.get(); } |
| 88 const Identity& identity() const { return identity_; } | 89 const Identity& identity() const { return identity_; } |
| 89 uint32_t id() const { return id_; } | 90 uint32_t id() const { return id_; } |
| 90 base::ProcessId pid() const { return pid_; } | 91 base::ProcessId pid() const { return pid_; } |
| 91 void set_pid(base::ProcessId pid) { pid_ = pid; } | 92 void set_pid(base::ProcessId pid) { pid_ = pid; } |
| 92 | 93 |
| 93 private: | 94 private: |
| 94 // Connector implementation: | 95 // Connector implementation: |
| 95 void Connect(const String& app_url, | 96 void Connect(const String& app_name, |
| 96 uint32_t user_id, | 97 uint32_t user_id, |
| 97 shell::mojom::InterfaceProviderRequest remote_interfaces, | 98 shell::mojom::InterfaceProviderRequest remote_interfaces, |
| 98 shell::mojom::InterfaceProviderPtr local_interfaces, | 99 shell::mojom::InterfaceProviderPtr local_interfaces, |
| 99 const ConnectCallback& callback) override { | 100 const ConnectCallback& callback) override { |
| 100 GURL url = app_url.To<GURL>(); | 101 if (!IsValidName(app_name)) { |
| 101 if (!url.is_valid()) { | 102 LOG(ERROR) << "Error: invalid Name: " << app_name; |
| 102 LOG(ERROR) << "Error: invalid URL: " << app_url; | |
| 103 callback.Run(kInvalidApplicationID); | 103 callback.Run(kInvalidApplicationID); |
| 104 return; | 104 return; |
| 105 } | 105 } |
| 106 if (allow_any_application_ || | 106 if (allow_any_application_ || |
| 107 identity_.filter().find(url.spec()) != identity_.filter().end()) { | 107 identity_.filter().find(app_name) != identity_.filter().end()) { |
| 108 scoped_ptr<ConnectParams> params(new ConnectParams); | 108 scoped_ptr<ConnectParams> params(new ConnectParams); |
| 109 params->set_source(identity_); | 109 params->set_source(identity_); |
| 110 params->set_target(Identity(url, std::string(), user_id)); | 110 params->set_target(Identity(app_name, std::string(), user_id)); |
| 111 params->set_remote_interfaces(std::move(remote_interfaces)); | 111 params->set_remote_interfaces(std::move(remote_interfaces)); |
| 112 params->set_local_interfaces(std::move(local_interfaces)); | 112 params->set_local_interfaces(std::move(local_interfaces)); |
| 113 params->set_connect_callback(callback); | 113 params->set_connect_callback(callback); |
| 114 manager_->Connect(std::move(params)); | 114 manager_->Connect(std::move(params)); |
| 115 } | 115 } |
| 116 else { | 116 else { |
| 117 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 117 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
| 118 identity_.url() << " to: " << url.spec(); | 118 identity_.name() << " to: " << app_name; |
| 119 callback.Run(kInvalidApplicationID); | 119 callback.Run(kInvalidApplicationID); |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 void Clone(mojom::ConnectorRequest request) override { | 122 void Clone(mojom::ConnectorRequest request) override { |
| 123 connectors_.AddBinding(this, std::move(request)); | 123 connectors_.AddBinding(this, std::move(request)); |
| 124 } | 124 } |
| 125 | 125 |
| 126 // PIDReceiver implementation: | 126 // PIDReceiver implementation: |
| 127 void SetPID(uint32_t pid) override { | 127 void SetPID(uint32_t pid) override { |
| 128 // This will call us back to update pid_. | 128 // This will call us back to update pid_. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 153 }; | 153 }; |
| 154 | 154 |
| 155 // static | 155 // static |
| 156 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 156 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) |
| 157 : manager_(manager) { | 157 : manager_(manager) { |
| 158 } | 158 } |
| 159 | 159 |
| 160 ApplicationManager::TestAPI::~TestAPI() { | 160 ApplicationManager::TestAPI::~TestAPI() { |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool ApplicationManager::TestAPI::HasRunningInstanceForURL( | 163 bool ApplicationManager::TestAPI::HasRunningInstanceForName( |
| 164 const GURL& url) const { | 164 const std::string& name) const { |
| 165 return manager_->identity_to_instance_.find(Identity(url)) != | 165 return manager_->identity_to_instance_.find(Identity(name)) != |
| 166 manager_->identity_to_instance_.end(); | 166 manager_->identity_to_instance_.end(); |
| 167 } | 167 } |
| 168 | 168 |
| 169 //////////////////////////////////////////////////////////////////////////////// | 169 //////////////////////////////////////////////////////////////////////////////// |
| 170 // ApplicationManager, public: | 170 // ApplicationManager, public: |
| 171 | 171 |
| 172 ApplicationManager::ApplicationManager( | 172 ApplicationManager::ApplicationManager( |
| 173 scoped_ptr<NativeRunnerFactory> native_runner_factory, | 173 scoped_ptr<NativeRunnerFactory> native_runner_factory, |
| 174 base::TaskRunner* file_task_runner, | 174 base::TaskRunner* file_task_runner, |
| 175 bool register_mojo_url_schemes, | |
| 176 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) | 175 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) |
| 177 : file_task_runner_(file_task_runner), | 176 : file_task_runner_(file_task_runner), |
| 178 native_runner_factory_(std::move(native_runner_factory)), | 177 native_runner_factory_(std::move(native_runner_factory)), |
| 179 weak_ptr_factory_(this) { | 178 weak_ptr_factory_(this) { |
| 180 mojom::ShellClientRequest request; | 179 mojom::ShellClientRequest request; |
| 181 CreateInstance(CreateShellIdentity(), &request); | 180 CreateInstance(CreateShellIdentity(), &request); |
| 182 shell_connection_.reset(new ShellConnection(this, std::move(request))); | 181 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
| 183 | 182 |
| 184 InitPackageManager(register_mojo_url_schemes, std::move(app_catalog)); | 183 InitPackageManager(std::move(app_catalog)); |
| 185 } | 184 } |
| 186 | 185 |
| 187 ApplicationManager::~ApplicationManager() { | 186 ApplicationManager::~ApplicationManager() { |
| 188 TerminateShellConnections(); | 187 TerminateShellConnections(); |
| 189 STLDeleteValues(&url_to_loader_); | 188 STLDeleteValues(&name_to_loader_); |
| 190 for (auto& runner : native_runners_) | 189 for (auto& runner : native_runners_) |
| 191 runner.reset(); | 190 runner.reset(); |
| 192 } | 191 } |
| 193 | 192 |
| 194 void ApplicationManager::SetInstanceQuitCallback( | 193 void ApplicationManager::SetInstanceQuitCallback( |
| 195 base::Callback<void(const Identity&)> callback) { | 194 base::Callback<void(const Identity&)> callback) { |
| 196 instance_quit_callback_ = callback; | 195 instance_quit_callback_ = callback; |
| 197 } | 196 } |
| 198 | 197 |
| 199 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { | 198 void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { |
| 200 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", | 199 TRACE_EVENT_INSTANT1("mojo_shell", "ApplicationManager::Connect", |
| 201 TRACE_EVENT_SCOPE_THREAD, "original_url", | 200 TRACE_EVENT_SCOPE_THREAD, "original_name", |
| 202 params->target().url().spec()); | 201 params->target().name()); |
| 203 DCHECK(params->target().url().is_valid()); | 202 DCHECK(IsValidName(params->target().name())); |
| 204 | 203 |
| 205 if (params->target().user_id() == mojom::Connector::kUserInherit) { | 204 if (params->target().user_id() == mojom::Connector::kUserInherit) { |
| 206 Instance* source = GetExistingInstance(params->source()); | 205 Instance* source = GetExistingInstance(params->source()); |
| 207 Identity target = params->target(); | 206 Identity target = params->target(); |
| 208 // TODO(beng): we should CHECK source. | 207 // TODO(beng): we should CHECK source. |
| 209 target.set_user_id(source ? source->identity().user_id() | 208 target.set_user_id(source ? source->identity().user_id() |
| 210 : mojom::Connector::kUserRoot); | 209 : mojom::Connector::kUserRoot); |
| 211 params->set_target(target); | 210 params->set_target(target); |
| 212 } | 211 } |
| 213 | 212 |
| 214 // Connect to an existing matching instance, if possible. | 213 // Connect to an existing matching instance, if possible. |
| 215 if (ConnectToExistingInstance(¶ms)) | 214 if (ConnectToExistingInstance(¶ms)) |
| 216 return; | 215 return; |
| 217 | 216 |
| 218 std::string url = params->target().url().spec(); | 217 std::string name = params->target().name(); |
| 219 shell_resolver_->ResolveMojoURL( | 218 shell_resolver_->ResolveMojoName( |
| 220 url, | 219 name, |
| 221 base::Bind(&ApplicationManager::OnGotResolvedURL, | 220 base::Bind(&ApplicationManager::OnGotResolvedName, |
| 222 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); | 221 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms))); |
| 223 } | 222 } |
| 224 | 223 |
| 225 mojom::ShellClientRequest ApplicationManager::InitInstanceForEmbedder( | 224 mojom::ShellClientRequest ApplicationManager::InitInstanceForEmbedder( |
| 226 const GURL& url) { | 225 const std::string& name) { |
| 227 DCHECK(!embedder_instance_); | 226 DCHECK(!embedder_instance_); |
| 228 | 227 |
| 229 mojo::shell::Identity target(url, std::string(), mojom::Connector::kUserRoot); | 228 mojo::shell::Identity target(name, std::string(), |
| 230 target.SetFilter(GetPermissiveCapabilityFilter()); | 229 mojom::Connector::kUserRoot); |
| 230 target.set_filter(GetPermissiveCapabilityFilter()); |
| 231 DCHECK(!GetExistingInstance(target)); | 231 DCHECK(!GetExistingInstance(target)); |
| 232 | 232 |
| 233 mojom::ShellClientRequest request; | 233 mojom::ShellClientRequest request; |
| 234 embedder_instance_ = CreateInstance(target, &request); | 234 embedder_instance_ = CreateInstance(target, &request); |
| 235 DCHECK(embedder_instance_); | 235 DCHECK(embedder_instance_); |
| 236 | 236 |
| 237 return request; | 237 return request; |
| 238 } | 238 } |
| 239 | 239 |
| 240 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 240 void ApplicationManager::SetLoaderForName(scoped_ptr<ApplicationLoader> loader, |
| 241 const GURL& url) { | 241 const std::string& name) { |
| 242 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 242 NameToLoaderMap::iterator it = name_to_loader_.find(name); |
| 243 if (it != url_to_loader_.end()) | 243 if (it != name_to_loader_.end()) |
| 244 delete it->second; | 244 delete it->second; |
| 245 url_to_loader_[url] = loader.release(); | 245 name_to_loader_[name] = loader.release(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 //////////////////////////////////////////////////////////////////////////////// | 248 //////////////////////////////////////////////////////////////////////////////// |
| 249 // ApplicationManager, ShellClient implementation: | 249 // ApplicationManager, ShellClient implementation: |
| 250 | 250 |
| 251 bool ApplicationManager::AcceptConnection(Connection* connection) { | 251 bool ApplicationManager::AcceptConnection(Connection* connection) { |
| 252 connection->AddInterface<mojom::ApplicationManager>(this); | 252 connection->AddInterface<mojom::ApplicationManager>(this); |
| 253 return true; | 253 return true; |
| 254 } | 254 } |
| 255 | 255 |
| 256 //////////////////////////////////////////////////////////////////////////////// | 256 //////////////////////////////////////////////////////////////////////////////// |
| 257 // ApplicationManager, InterfaceFactory<mojom::ApplicationManager> | 257 // ApplicationManager, InterfaceFactory<mojom::ApplicationManager> |
| 258 // implementation: | 258 // implementation: |
| 259 | 259 |
| 260 void ApplicationManager::Create(Connection* connection, | 260 void ApplicationManager::Create(Connection* connection, |
| 261 mojom::ApplicationManagerRequest request) { | 261 mojom::ApplicationManagerRequest request) { |
| 262 bindings_.AddBinding(this, std::move(request)); | 262 bindings_.AddBinding(this, std::move(request)); |
| 263 } | 263 } |
| 264 | 264 |
| 265 //////////////////////////////////////////////////////////////////////////////// | 265 //////////////////////////////////////////////////////////////////////////////// |
| 266 // ApplicationManager, mojom::ApplicationManager implemetation: | 266 // ApplicationManager, mojom::ApplicationManager implemetation: |
| 267 | 267 |
| 268 void ApplicationManager::CreateInstanceForHandle( | 268 void ApplicationManager::CreateInstanceForHandle( |
| 269 ScopedHandle channel, | 269 ScopedHandle channel, |
| 270 const String& url, | 270 const String& name, |
| 271 mojom::CapabilityFilterPtr filter, | 271 mojom::CapabilityFilterPtr filter, |
| 272 mojom::PIDReceiverRequest pid_receiver) { | 272 mojom::PIDReceiverRequest pid_receiver) { |
| 273 // We don't call ConnectToClient() here since the instance was created | 273 // We don't call ConnectToClient() here since the instance was created |
| 274 // manually by other code, not in response to a Connect() request. The newly | 274 // manually by other code, not in response to a Connect() request. The newly |
| 275 // created instance is identified by |url| and may be subsequently reached by | 275 // created instance is identified by |name| and may be subsequently reached by |
| 276 // client code using this identity. | 276 // client code using this identity. |
| 277 // TODO(beng): obtain userid from the inbound connection. | 277 // TODO(beng): obtain userid from the inbound connection. |
| 278 Identity target_id(url.To<GURL>(), std::string(), | 278 Identity target_id(name, std::string(), mojom::Connector::kUserInherit); |
| 279 mojom::Connector::kUserInherit); | 279 target_id.set_filter(filter->filter.To<CapabilityFilter>()); |
| 280 target_id.SetFilter(filter->filter.To<CapabilityFilter>()); | |
| 281 mojom::ShellClientRequest request; | 280 mojom::ShellClientRequest request; |
| 282 Instance* instance = CreateInstance(target_id, &request); | 281 Instance* instance = CreateInstance(target_id, &request); |
| 283 instance->BindPIDReceiver(std::move(pid_receiver)); | 282 instance->BindPIDReceiver(std::move(pid_receiver)); |
| 284 scoped_ptr<NativeRunner> runner = | 283 scoped_ptr<NativeRunner> runner = |
| 285 native_runner_factory_->Create(base::FilePath()); | 284 native_runner_factory_->Create(base::FilePath()); |
| 286 runner->InitHost(std::move(channel), std::move(request)); | 285 runner->InitHost(std::move(channel), std::move(request)); |
| 287 instance->SetNativeRunner(runner.get()); | 286 instance->SetNativeRunner(runner.get()); |
| 288 native_runners_.push_back(std::move(runner)); | 287 native_runners_.push_back(std::move(runner)); |
| 289 } | 288 } |
| 290 | 289 |
| 291 void ApplicationManager::AddListener( | 290 void ApplicationManager::AddListener( |
| 292 mojom::ApplicationManagerListenerPtr listener) { | 291 mojom::ApplicationManagerListenerPtr listener) { |
| 293 Array<mojom::ApplicationInfoPtr> applications; | 292 Array<mojom::ApplicationInfoPtr> applications; |
| 294 for (auto& entry : identity_to_instance_) | 293 for (auto& entry : identity_to_instance_) |
| 295 applications.push_back(CreateApplicationInfoForInstance(entry.second)); | 294 applications.push_back(CreateApplicationInfoForInstance(entry.second)); |
| 296 listener->SetRunningApplications(std::move(applications)); | 295 listener->SetRunningApplications(std::move(applications)); |
| 297 | 296 |
| 298 listeners_.AddInterfacePtr(std::move(listener)); | 297 listeners_.AddInterfacePtr(std::move(listener)); |
| 299 } | 298 } |
| 300 | 299 |
| 301 //////////////////////////////////////////////////////////////////////////////// | 300 //////////////////////////////////////////////////////////////////////////////// |
| 302 // ApplicationManager, private: | 301 // ApplicationManager, private: |
| 303 | 302 |
| 304 void ApplicationManager::InitPackageManager( | 303 void ApplicationManager::InitPackageManager( |
| 305 bool register_mojo_url_schemes, | |
| 306 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { | 304 scoped_ptr<package_manager::ApplicationCatalogStore> app_catalog) { |
| 307 scoped_ptr<ApplicationLoader> loader(new package_manager::Loader( | 305 scoped_ptr<ApplicationLoader> loader(new package_manager::Loader( |
| 308 file_task_runner_, register_mojo_url_schemes, std::move(app_catalog))); | 306 file_task_runner_, std::move(app_catalog))); |
| 309 | 307 |
| 310 mojom::ShellClientRequest request; | 308 mojom::ShellClientRequest request; |
| 311 GURL url("mojo://package_manager/"); | 309 std::string name = "mojo:package_manager"; |
| 312 CreateInstance(Identity(url), &request); | 310 CreateInstance(Identity(name), &request); |
| 313 loader->Load(url, std::move(request)); | 311 loader->Load(name, std::move(request)); |
| 314 | 312 |
| 315 SetLoaderForURL(std::move(loader), url); | 313 SetLoaderForName(std::move(loader), name); |
| 316 | 314 |
| 317 ConnectToInterface(this, CreateShellIdentity(), url, &shell_resolver_); | 315 ConnectToInterface(this, CreateShellIdentity(), name, &shell_resolver_); |
| 318 } | 316 } |
| 319 | 317 |
| 320 void ApplicationManager::TerminateShellConnections() { | 318 void ApplicationManager::TerminateShellConnections() { |
| 321 STLDeleteValues(&identity_to_instance_); | 319 STLDeleteValues(&identity_to_instance_); |
| 322 } | 320 } |
| 323 | 321 |
| 324 void ApplicationManager::OnInstanceError(Instance* instance) { | 322 void ApplicationManager::OnInstanceError(Instance* instance) { |
| 325 const Identity identity = instance->identity(); | 323 const Identity identity = instance->identity(); |
| 326 // Remove the shell. | 324 // Remove the shell. |
| 327 auto it = identity_to_instance_.find(identity); | 325 auto it = identity_to_instance_.find(identity); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 [this, &application_info](mojom::ApplicationManagerListener* listener) { | 384 [this, &application_info](mojom::ApplicationManagerListener* listener) { |
| 387 listener->ApplicationInstanceCreated(application_info.Clone()); | 385 listener->ApplicationInstanceCreated(application_info.Clone()); |
| 388 }); | 386 }); |
| 389 instance->Initialize(); | 387 instance->Initialize(); |
| 390 return instance; | 388 return instance; |
| 391 } | 389 } |
| 392 | 390 |
| 393 void ApplicationManager::CreateShellClient( | 391 void ApplicationManager::CreateShellClient( |
| 394 const Identity& source, | 392 const Identity& source, |
| 395 const Identity& shell_client_factory, | 393 const Identity& shell_client_factory, |
| 396 const GURL& url, | 394 const std::string& name, |
| 397 mojom::ShellClientRequest request) { | 395 mojom::ShellClientRequest request) { |
| 398 mojom::ShellClientFactory* factory = | 396 mojom::ShellClientFactory* factory = |
| 399 GetShellClientFactory(shell_client_factory, source); | 397 GetShellClientFactory(shell_client_factory, source); |
| 400 factory->CreateShellClient(std::move(request), url.spec()); | 398 factory->CreateShellClient(std::move(request), name); |
| 401 } | 399 } |
| 402 | 400 |
| 403 mojom::ShellClientFactory* ApplicationManager::GetShellClientFactory( | 401 mojom::ShellClientFactory* ApplicationManager::GetShellClientFactory( |
| 404 const Identity& shell_client_factory_identity, | 402 const Identity& shell_client_factory_identity, |
| 405 const Identity& source_identity) { | 403 const Identity& source_identity) { |
| 406 auto it = shell_client_factories_.find(shell_client_factory_identity); | 404 auto it = shell_client_factories_.find(shell_client_factory_identity); |
| 407 if (it != shell_client_factories_.end()) | 405 if (it != shell_client_factories_.end()) |
| 408 return it->second.get(); | 406 return it->second.get(); |
| 409 | 407 |
| 410 mojom::ShellClientFactoryPtr factory; | 408 mojom::ShellClientFactoryPtr factory; |
| 411 // TODO(beng): we should forward the original source identity! | 409 // TODO(beng): we should forward the original source identity! |
| 412 ConnectToInterface(this, source_identity, shell_client_factory_identity, | 410 ConnectToInterface(this, source_identity, shell_client_factory_identity, |
| 413 &factory); | 411 &factory); |
| 414 mojom::ShellClientFactory* factory_interface = factory.get(); | 412 mojom::ShellClientFactory* factory_interface = factory.get(); |
| 415 factory.set_connection_error_handler( | 413 factory.set_connection_error_handler( |
| 416 base::Bind(&ApplicationManager::OnShellClientFactoryLost, | 414 base::Bind(&ApplicationManager::OnShellClientFactoryLost, |
| 417 weak_ptr_factory_.GetWeakPtr(), | 415 weak_ptr_factory_.GetWeakPtr(), |
| 418 shell_client_factory_identity)); | 416 shell_client_factory_identity)); |
| 419 shell_client_factories_[shell_client_factory_identity] = std::move(factory); | 417 shell_client_factories_[shell_client_factory_identity] = std::move(factory); |
| 420 return factory_interface; | 418 return factory_interface; |
| 421 } | 419 } |
| 422 | 420 |
| 423 void ApplicationManager::OnShellClientFactoryLost(const Identity& which) { | 421 void ApplicationManager::OnShellClientFactoryLost(const Identity& which) { |
| 424 // Remove the mapping. | 422 // Remove the mapping. |
| 425 auto it = shell_client_factories_.find(which); | 423 auto it = shell_client_factories_.find(which); |
| 426 DCHECK(it != shell_client_factories_.end()); | 424 DCHECK(it != shell_client_factories_.end()); |
| 427 shell_client_factories_.erase(it); | 425 shell_client_factories_.erase(it); |
| 428 } | 426 } |
| 429 | 427 |
| 430 void ApplicationManager::OnGotResolvedURL( | 428 void ApplicationManager::OnGotResolvedName( |
| 431 scoped_ptr<ConnectParams> params, | 429 scoped_ptr<ConnectParams> params, |
| 432 const String& resolved_url, | 430 const String& resolved_name, |
| 433 const String& resolved_qualifier, | 431 const String& resolved_qualifier, |
| 434 mojom::CapabilityFilterPtr base_filter, | 432 mojom::CapabilityFilterPtr base_filter, |
| 435 const String& file_url) { | 433 const String& file_url) { |
| 436 // It's possible that when this manifest request was issued, another one was | 434 // It's possible that when this manifest request was issued, another one was |
| 437 // already in-progress and completed by the time this one did, and so the | 435 // already in-progress and completed by the time this one did, and so the |
| 438 // requested application may already be running. | 436 // requested application may already be running. |
| 439 if (ConnectToExistingInstance(¶ms)) | 437 if (ConnectToExistingInstance(¶ms)) |
| 440 return; | 438 return; |
| 441 | 439 |
| 442 Identity source = params->source(); | 440 Identity source = params->source(); |
| 443 // |base_filter| can be null when there is no manifest, e.g. for URL types | 441 // |base_filter| can be null when there is no manifest, e.g. for URL types |
| 444 // not resolvable by the resolver. | 442 // not resolvable by the resolver. |
| 445 CapabilityFilter filter = GetPermissiveCapabilityFilter(); | 443 CapabilityFilter filter = GetPermissiveCapabilityFilter(); |
| 446 if (!base_filter.is_null()) | 444 if (!base_filter.is_null()) |
| 447 filter = base_filter->filter.To<CapabilityFilter>(); | 445 filter = base_filter->filter.To<CapabilityFilter>(); |
| 448 Identity target = params->target(); | 446 Identity target = params->target(); |
| 449 target.SetFilter(filter); | 447 target.set_filter(filter); |
| 450 | 448 |
| 451 mojom::ShellClientRequest request; | 449 mojom::ShellClientRequest request; |
| 452 Instance* instance = CreateInstance(target, &request); | 450 Instance* instance = CreateInstance(target, &request); |
| 453 instance->ConnectToClient(std::move(params)); | 451 instance->ConnectToClient(std::move(params)); |
| 454 | 452 |
| 455 if (LoadWithLoader(target, &request)) | 453 if (LoadWithLoader(target, &request)) |
| 456 return; | 454 return; |
| 457 | 455 |
| 458 CHECK(!file_url.is_null() && !base_filter.is_null()); | 456 CHECK(!file_url.is_null() && !base_filter.is_null()); |
| 459 | 457 |
| 460 GURL resolved_gurl = resolved_url.To<GURL>(); | 458 if (target.name() != resolved_name) { |
| 461 if (target.url().spec() != resolved_url) { | |
| 462 // In cases where a package alias is resolved, we have to use the qualifier | 459 // In cases where a package alias is resolved, we have to use the qualifier |
| 463 // from the original request rather than for the package itself, which will | 460 // from the original request rather than for the package itself, which will |
| 464 // always be the same. | 461 // always be the same. |
| 465 CreateShellClient( | 462 CreateShellClient( |
| 466 source, Identity(resolved_gurl, target.qualifier(), target.user_id()), | 463 source, Identity(resolved_name, target.qualifier(), target.user_id()), |
| 467 target.url(), std::move(request)); | 464 target.name(), std::move(request)); |
| 468 } else { | 465 } else { |
| 469 bool start_sandboxed = false; | 466 bool start_sandboxed = false; |
| 470 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); | 467 base::FilePath path = util::UrlToFilePath(file_url.To<GURL>()); |
| 471 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); | 468 scoped_ptr<NativeRunner> runner = native_runner_factory_->Create(path); |
| 472 runner->Start(path, target, start_sandboxed, std::move(request), | 469 runner->Start(path, target, start_sandboxed, std::move(request), |
| 473 base::Bind(&ApplicationManager::ApplicationPIDAvailable, | 470 base::Bind(&ApplicationManager::ApplicationPIDAvailable, |
| 474 weak_ptr_factory_.GetWeakPtr(), instance->id()), | 471 weak_ptr_factory_.GetWeakPtr(), instance->id()), |
| 475 base::Bind(&ApplicationManager::CleanupRunner, | 472 base::Bind(&ApplicationManager::CleanupRunner, |
| 476 weak_ptr_factory_.GetWeakPtr(), runner.get())); | 473 weak_ptr_factory_.GetWeakPtr(), runner.get())); |
| 477 instance->SetNativeRunner(runner.get()); | 474 instance->SetNativeRunner(runner.get()); |
| 478 native_runners_.push_back(std::move(runner)); | 475 native_runners_.push_back(std::move(runner)); |
| 479 } | 476 } |
| 480 } | 477 } |
| 481 | 478 |
| 482 bool ApplicationManager::LoadWithLoader(const Identity& target, | 479 bool ApplicationManager::LoadWithLoader(const Identity& target, |
| 483 mojom::ShellClientRequest* request) { | 480 mojom::ShellClientRequest* request) { |
| 484 ApplicationLoader* loader = GetLoaderForURL(target.url()); | 481 ApplicationLoader* loader = GetLoaderForName(target.name()); |
| 485 if (!loader) | 482 if (!loader) |
| 486 return false; | 483 return false; |
| 487 loader->Load(target.url(), std::move(*request)); | 484 loader->Load(target.name(), std::move(*request)); |
| 488 return true; | 485 return true; |
| 489 } | 486 } |
| 490 | 487 |
| 491 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { | 488 ApplicationLoader* ApplicationManager::GetLoaderForName( |
| 492 auto url_it = url_to_loader_.find(url); | 489 const std::string& name) { |
| 493 if (url_it != url_to_loader_.end()) | 490 auto name_it = name_to_loader_.find(name); |
| 494 return url_it->second; | 491 if (name_it != name_to_loader_.end()) |
| 492 return name_it->second; |
| 495 return default_loader_.get(); | 493 return default_loader_.get(); |
| 496 } | 494 } |
| 497 | 495 |
| 498 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 496 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 499 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 497 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
| 500 if (it->get() == runner) { | 498 if (it->get() == runner) { |
| 501 native_runners_.erase(it); | 499 native_runners_.erase(it); |
| 502 return; | 500 return; |
| 503 } | 501 } |
| 504 } | 502 } |
| 505 } | 503 } |
| 506 | 504 |
| 507 mojom::ApplicationInfoPtr ApplicationManager::CreateApplicationInfoForInstance( | 505 mojom::ApplicationInfoPtr ApplicationManager::CreateApplicationInfoForInstance( |
| 508 Instance* instance) const { | 506 Instance* instance) const { |
| 509 mojom::ApplicationInfoPtr info(mojom::ApplicationInfo::New()); | 507 mojom::ApplicationInfoPtr info(mojom::ApplicationInfo::New()); |
| 510 info->id = instance->id(); | 508 info->id = instance->id(); |
| 511 info->url = instance->identity().url().spec(); | 509 info->name = instance->identity().name(); |
| 512 info->qualifier = instance->identity().qualifier(); | 510 info->qualifier = instance->identity().qualifier(); |
| 513 if (instance->identity().url().spec() == "mojo://shell/") | 511 if (instance->identity().name() == "mojo:shell") |
| 514 info->pid = base::Process::Current().Pid(); | 512 info->pid = base::Process::Current().Pid(); |
| 515 else | 513 else |
| 516 info->pid = instance->pid(); | 514 info->pid = instance->pid(); |
| 517 return info; | 515 return info; |
| 518 } | 516 } |
| 519 | 517 |
| 520 } // namespace shell | 518 } // namespace shell |
| 521 } // namespace mojo | 519 } // namespace mojo |
| OLD | NEW |