diff options
Diffstat (limited to 'mojo/shell')
30 files changed, 246 insertions, 160 deletions
diff --git a/mojo/shell/application_instance.cc b/mojo/shell/application_instance.cc index 7923a76..33b9a48 100644 --- a/mojo/shell/application_instance.cc +++ b/mojo/shell/application_instance.cc @@ -44,7 +44,7 @@ ApplicationInstance::~ApplicationInstance() { void ApplicationInstance::InitializeApplication() { shell_client_->Initialize(binding_.CreateInterfacePtrAndBind(), - identity_.url().spec(), id_); + identity_.url().spec(), id_, identity_.user_id()); binding_.set_connection_error_handler([this]() { OnConnectionError(); }); } @@ -69,6 +69,7 @@ void ApplicationInstance::BindPIDReceiver( // Shell implementation: void ApplicationInstance::Connect( const String& app_url, + uint32_t user_id, shell::mojom::InterfaceProviderRequest remote_interfaces, shell::mojom::InterfaceProviderPtr local_interfaces, mojom::CapabilityFilterPtr filter, @@ -86,8 +87,9 @@ void ApplicationInstance::Connect( capability_filter = filter->filter.To<CapabilityFilter>(); scoped_ptr<ConnectParams> params(new ConnectParams); - params->SetSource(this); - params->set_target(Identity(url, std::string(), capability_filter)); + params->set_source(identity_); + params->set_target( + Identity(url, std::string(), user_id, capability_filter)); params->set_remote_interfaces(std::move(remote_interfaces)); params->set_local_interfaces(std::move(local_interfaces)); params->set_connect_callback(callback); @@ -130,9 +132,9 @@ void ApplicationInstance::CallAcceptConnection( manager_->GetApplicationInstance(params->source()); uint32_t source_id = source ? source->id() : Shell::kInvalidApplicationID; shell_client_->AcceptConnection( - params->source().url().spec(), source_id, params->TakeRemoteInterfaces(), - params->TakeLocalInterfaces(), Array<String>::From(interfaces), - params->target().url().spec()); + params->source().url().spec(), params->source().user_id(), source_id, + params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), + Array<String>::From(interfaces), params->target().url().spec()); } void ApplicationInstance::OnConnectionError() { diff --git a/mojo/shell/application_instance.h b/mojo/shell/application_instance.h index afe30e5..418640e 100644 --- a/mojo/shell/application_instance.h +++ b/mojo/shell/application_instance.h @@ -57,6 +57,7 @@ class ApplicationInstance : public mojom::Shell, private: // Shell implementation: void Connect(const String& app_url, + uint32_t user_id, shell::mojom::InterfaceProviderRequest remote_interfaces, shell::mojom::InterfaceProviderPtr local_interfaces, mojom::CapabilityFilterPtr filter, diff --git a/mojo/shell/application_manager.cc b/mojo/shell/application_manager.cc index 7ad6ca7..c24e36a 100644 --- a/mojo/shell/application_manager.cc +++ b/mojo/shell/application_manager.cc @@ -29,29 +29,6 @@ namespace mojo { namespace shell { -namespace { - -class ShellApplicationLoader : public ApplicationLoader { - public: - explicit ShellApplicationLoader(ApplicationManager* manager) - : manager_(manager) {} - ~ShellApplicationLoader() override {} - - private: - // Overridden from ApplicationLoader: - void Load(const GURL& url, mojom::ShellClientRequest request) override { - DCHECK(request.is_pending()); - shell_connection_.reset(new ShellConnection(manager_, std::move(request))); - } - - ApplicationManager* manager_; - scoped_ptr<ShellConnection> shell_connection_; - - DISALLOW_COPY_AND_ASSIGN(ShellApplicationLoader); -}; - -} // namespace - // static ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) : manager_(manager) { @@ -76,8 +53,9 @@ ApplicationManager::ApplicationManager( : file_task_runner_(file_task_runner), native_runner_factory_(std::move(native_runner_factory)), weak_ptr_factory_(this) { - SetLoaderForURL(make_scoped_ptr(new ShellApplicationLoader(this)), - GURL("mojo://shell/")); + mojom::ShellClientRequest request; + CreateInstance(CreateShellIdentity(), &request); + shell_connection_.reset(new ShellConnection(this, std::move(request))); InitPackageManager(register_mojo_url_schemes); } @@ -100,6 +78,15 @@ void ApplicationManager::Connect(scoped_ptr<ConnectParams> params) { params->target().url().spec()); DCHECK(params->target().url().is_valid()); + if (params->target().user_id() == mojom::Shell::kUserInherit) { + ApplicationInstance* source = GetApplicationInstance(params->source()); + Identity target = params->target(); + // TODO(beng): we should CHECK source. + target.set_user_id(source ? source->identity().user_id() + : mojom::Shell::kUserRoot); + params->set_target(target); + } + // Connect to an existing matching instance, if possible. if (ConnectToExistingInstance(¶ms)) return; @@ -191,7 +178,9 @@ void ApplicationManager::CreateInstanceForHandle( // created instance is identified by |url| and may be subsequently reached by // client code using this identity. CapabilityFilter local_filter = filter->filter.To<CapabilityFilter>(); - Identity target_id(url.To<GURL>(), std::string(), local_filter); + // TODO(beng): obtain userid from the inbound connection. + Identity target_id(url.To<GURL>(), std::string(), mojom::Shell::kUserInherit, + local_filter); mojom::ShellClientRequest request; ApplicationInstance* instance = CreateInstance(target_id, &request); instance->BindPIDReceiver(std::move(pid_receiver)); @@ -232,8 +221,12 @@ void ApplicationManager::InitPackageManager(bool register_mojo_url_schemes) { bool ApplicationManager::ConnectToExistingInstance( scoped_ptr<ConnectParams>* params) { ApplicationInstance* instance = GetApplicationInstance((*params)->target()); - if (!instance) - return false; + if (!instance) { + Identity root_identity = (*params)->target(); + root_identity.set_user_id(mojom::Shell::kUserRoot); + instance = GetApplicationInstance(root_identity); + if (!instance) return false; + } instance->ConnectToClient(std::move(*params)); return true; } @@ -312,7 +305,8 @@ void ApplicationManager::OnGotResolvedURL( // TODO(beng): this clobbers the filter passed via Connect(). if (!base_filter.is_null()) filter = base_filter->filter.To<CapabilityFilter>(); - Identity target(params->target().url(), params->target().qualifier(), filter); + Identity target(params->target().url(), params->target().qualifier(), + params->target().user_id(), filter); mojom::ShellClientRequest request; ApplicationInstance* instance = CreateInstance(target, &request); @@ -329,7 +323,8 @@ void ApplicationManager::OnGotResolvedURL( // from the original request rather than for the package itself, which will // always be the same. CreateShellClient(source, - Identity(resolved_gurl, target.qualifier(), filter), + Identity(resolved_gurl, target.qualifier(), + target.user_id(), filter), target.url(), std::move(request)); } else { bool start_sandboxed = false; diff --git a/mojo/shell/application_manager.h b/mojo/shell/application_manager.h index 3852d6e..b6e657c 100644 --- a/mojo/shell/application_manager.h +++ b/mojo/shell/application_manager.h @@ -34,6 +34,7 @@ class SequencedWorkerPool; } namespace mojo { +class ShellConnection; namespace shell { class ApplicationInstance; @@ -186,6 +187,7 @@ class ApplicationManager : public ShellClient, base::TaskRunner* file_task_runner_; scoped_ptr<NativeRunnerFactory> native_runner_factory_; std::vector<scoped_ptr<NativeRunner>> native_runners_; + scoped_ptr<ShellConnection> shell_connection_; WeakBindingSet<mojom::ApplicationManager> bindings_; base::WeakPtrFactory<ApplicationManager> weak_ptr_factory_; diff --git a/mojo/shell/background/background_shell.cc b/mojo/shell/background/background_shell.cc index 3a56c81..a4b6c5e 100644 --- a/mojo/shell/background/background_shell.cc +++ b/mojo/shell/background/background_shell.cc @@ -176,7 +176,8 @@ mojom::ShellClientRequest BackgroundShell::CreateShellClientRequest( const GURL& url) { scoped_ptr<ConnectParams> params(new ConnectParams); params->set_target( - Identity(url, std::string(), GetPermissiveCapabilityFilter())); + Identity(url, std::string(), mojom::Shell::kUserRoot, + GetPermissiveCapabilityFilter())); mojom::ShellClientRequest request; base::WaitableEvent signal(true, false); thread_->message_loop()->task_runner()->PostTask( diff --git a/mojo/shell/connect_params.cc b/mojo/shell/connect_params.cc index 92d1a87..ec4e722 100644 --- a/mojo/shell/connect_params.cc +++ b/mojo/shell/connect_params.cc @@ -11,21 +11,13 @@ namespace mojo { namespace shell { - ConnectParams::ConnectParams() {} +ConnectParams::ConnectParams() {} - ConnectParams::~ConnectParams() {} - - void ConnectParams::SetSource(ApplicationInstance* source) { - if (!source) { - source_ = Identity(); - return; - } - - source_ = source->identity(); -} +ConnectParams::~ConnectParams() {} void ConnectParams::SetTargetURL(const GURL& target_url) { - target_ = Identity(target_url, target_.qualifier(), target_.filter()); + target_ = Identity(target_url, target_.qualifier(), + mojom::Shell::kUserInherit, target_.filter()); } } // namespace shell diff --git a/mojo/shell/connect_params.h b/mojo/shell/connect_params.h index 172df1f..118108c 100644 --- a/mojo/shell/connect_params.h +++ b/mojo/shell/connect_params.h @@ -28,9 +28,6 @@ class ConnectParams { ConnectParams(); ~ConnectParams(); - // Sets |source_|. If |source| is null, |source_| is reset. - void SetSource(ApplicationInstance* source); - // The following methods set both |target_| and |target_url_request_|. void SetTargetURL(const GURL& target_url); diff --git a/mojo/shell/connect_util.h b/mojo/shell/connect_util.h index 036ecde..baa4d2e 100644 --- a/mojo/shell/connect_util.h +++ b/mojo/shell/connect_util.h @@ -10,6 +10,7 @@ #include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/system/handle.h" #include "mojo/shell/identity.h" +#include "mojo/shell/public/interfaces/shell.mojom.h" class GURL; @@ -44,7 +45,8 @@ inline void ConnectToInterface(ApplicationManager* application_manager, InterfacePtr<Interface>* ptr) { ScopedMessagePipeHandle service_handle = ConnectToInterfaceByName( application_manager, source, - Identity(application_url, std::string(), GetPermissiveCapabilityFilter()), + Identity(application_url, std::string(), mojom::Shell::kUserInherit, + GetPermissiveCapabilityFilter()), Interface::Name_); ptr->Bind(InterfacePtrInfo<Interface>(std::move(service_handle), 0u)); } diff --git a/mojo/shell/identity.cc b/mojo/shell/identity.cc index 2c05b3f..f592da9 100644 --- a/mojo/shell/identity.cc +++ b/mojo/shell/identity.cc @@ -4,6 +4,8 @@ #include "mojo/shell/identity.h" +#include "mojo/shell/public/interfaces/shell.mojom.h" + namespace mojo { namespace shell { namespace { @@ -28,18 +30,17 @@ CapabilityFilter CanonicalizeFilter(const CapabilityFilter& filter) { Identity::Identity() {} Identity::Identity(const GURL& url) - : url_(url), - qualifier_(url_.spec()) {} + : Identity(url, url.spec(), mojom::Shell::kUserRoot) {} -Identity::Identity(const GURL& url, const std::string& qualifier) - : url_(url), - qualifier_(qualifier.empty() ? url_.spec() : qualifier) {} +Identity::Identity(const GURL& url, const std::string& qualifier, + uint32_t user_id) + : Identity(url, qualifier, user_id, CapabilityFilter()) {} -Identity::Identity(const GURL& url, - const std::string& qualifier, - CapabilityFilter filter) +Identity::Identity(const GURL& url, const std::string& qualifier, + uint32_t user_id, CapabilityFilter filter) : url_(url), qualifier_(qualifier.empty() ? url_.spec() : qualifier), + user_id_(user_id), filter_(CanonicalizeFilter(filter)) {} Identity::~Identity() {} @@ -50,17 +51,19 @@ bool Identity::operator<(const Identity& other) const { // TODO(beng): figure out how it should work. if (url_ != other.url_) return url_ < other.url_; - return qualifier_ < other.qualifier_; + if (qualifier_ != other.qualifier_) + return qualifier_ < other.qualifier_; + return user_id_ < other.user_id_; } bool Identity::operator==(const Identity& other) const { return other.url_ == url_ && other.qualifier_ == qualifier_ && - other.filter_ == filter_; + other.filter_ == filter_ && other.user_id_ == user_id_; } Identity CreateShellIdentity() { return Identity(GURL("mojo://shell/"), std::string(), - GetPermissiveCapabilityFilter()); + mojom::Shell::kUserRoot, GetPermissiveCapabilityFilter()); } } // namespace shell diff --git a/mojo/shell/identity.h b/mojo/shell/identity.h index e5a349b..abd0699 100644 --- a/mojo/shell/identity.h +++ b/mojo/shell/identity.h @@ -21,10 +21,15 @@ namespace shell { class Identity { public: Identity(); + // Assumes user = mojom::Shell::kUserRoot. + // Used in tests or for shell-initiated connections. explicit Identity(const GURL& in_url); - Identity(const GURL& in_url, const std::string& in_qualifier); Identity(const GURL& in_url, const std::string& in_qualifier, + uint32_t user_id); + Identity(const GURL& in_url, + const std::string& in_qualifier, + uint32_t user, CapabilityFilter filter); ~Identity(); @@ -33,6 +38,8 @@ class Identity { bool operator==(const Identity& other) const; const GURL& url() const { return url_; } + uint32_t user_id() const { return user_id_; } + void set_user_id(uint32_t user_id) { user_id_ = user_id; } const std::string& qualifier() const { return qualifier_; } const CapabilityFilter& filter() const { return filter_; } @@ -40,6 +47,8 @@ class Identity { GURL url_; std::string qualifier_; + uint32_t user_id_; + // TODO(beng): CapabilityFilter is not currently included in equivalence // checks for Identity since we're not currently clear on the // policy for instance disambiguation. Need to figure this out. diff --git a/mojo/shell/public/cpp/connection.h b/mojo/shell/public/cpp/connection.h index e05243f..39327a6 100644 --- a/mojo/shell/public/cpp/connection.h +++ b/mojo/shell/public/cpp/connection.h @@ -82,6 +82,9 @@ class Connection { // Returns the URL identifying the remote application on this connection. virtual const std::string& GetRemoteApplicationURL() = 0; + // Returns the User ID for the remote application. + virtual uint32_t GetRemoteUserID() const = 0; + // Register a handler to receive an error notification on the pipe to the // remote application's InterfaceProvider. virtual void SetRemoteInterfaceProviderConnectionErrorHandler( diff --git a/mojo/shell/public/cpp/lib/application_test_base.cc b/mojo/shell/public/cpp/lib/application_test_base.cc index f9a726d..49bb65e 100644 --- a/mojo/shell/public/cpp/lib/application_test_base.cc +++ b/mojo/shell/public/cpp/lib/application_test_base.cc @@ -21,6 +21,7 @@ namespace { // Share the application URL with multiple application tests. String g_url; uint32_t g_id = shell::mojom::Shell::kInvalidApplicationID; +uint32_t g_user_id = shell::mojom::Shell::kUserRoot; // ShellClient request handle passed from the shell in MojoMain, stored in // between SetUp()/TearDown() so we can (re-)intialize new ShellConnections. @@ -45,15 +46,18 @@ class ShellGrabber : public shell::mojom::ShellClient { // shell::mojom::ShellClient implementation. void Initialize(shell::mojom::ShellPtr shell, const mojo::String& url, - uint32_t id) override { + uint32_t id, + uint32_t user_id) override { g_url = url; g_id = id; + g_user_id = user_id; g_shell_client_request = binding_.Unbind(); g_shell = std::move(shell); } void AcceptConnection( const String& requestor_url, + uint32_t requestor_user_id, uint32_t requestor_id, shell::mojom::InterfaceProviderRequest local_interfaces, shell::mojom::InterfaceProviderPtr remote_interfaces, @@ -121,7 +125,7 @@ TestHelper::TestHelper(ShellClient* client) url_(g_url) { // Fake ShellClient initialization. shell::mojom::ShellClient* shell_client = shell_connection_.get(); - shell_client->Initialize(std::move(g_shell), g_url, g_id); + shell_client->Initialize(std::move(g_shell), g_url, g_id, g_user_id); } TestHelper::~TestHelper() { diff --git a/mojo/shell/public/cpp/lib/connection_impl.cc b/mojo/shell/public/cpp/lib/connection_impl.cc index 47f9b9f..7fb65b5 100644 --- a/mojo/shell/public/cpp/lib/connection_impl.cc +++ b/mojo/shell/public/cpp/lib/connection_impl.cc @@ -23,6 +23,7 @@ ConnectionImpl::ConnectionImpl( const std::string& connection_url, const std::string& remote_url, uint32_t remote_id, + uint32_t remote_user_id, shell::mojom::InterfaceProviderPtr remote_interfaces, shell::mojom::InterfaceProviderRequest local_interfaces, const std::set<std::string>& allowed_interfaces) @@ -30,6 +31,7 @@ ConnectionImpl::ConnectionImpl( remote_url_(remote_url), remote_id_(remote_id), remote_ids_valid_(false), + remote_user_id_(remote_user_id), local_registry_(std::move(local_interfaces), this), remote_interfaces_(std::move(remote_interfaces)), allowed_interfaces_(allowed_interfaces), @@ -62,6 +64,10 @@ const std::string& ConnectionImpl::GetRemoteApplicationURL() { return remote_url_; } +uint32_t ConnectionImpl::GetRemoteUserID() const { + return remote_user_id_; +} + void ConnectionImpl::SetRemoteInterfaceProviderConnectionErrorHandler( const Closure& handler) { remote_interfaces_.set_connection_error_handler(handler); diff --git a/mojo/shell/public/cpp/lib/connection_impl.h b/mojo/shell/public/cpp/lib/connection_impl.h index 4fc34e7..00e167f 100644 --- a/mojo/shell/public/cpp/lib/connection_impl.h +++ b/mojo/shell/public/cpp/lib/connection_impl.h @@ -30,6 +30,7 @@ class ConnectionImpl : public Connection { ConnectionImpl(const std::string& connection_url, const std::string& remote_url, uint32_t remote_id, + uint32_t remote_user_id, shell::mojom::InterfaceProviderPtr remote_interfaces, shell::mojom::InterfaceProviderRequest local_interfaces, const std::set<std::string>& allowed_interfaces); @@ -41,6 +42,7 @@ class ConnectionImpl : public Connection { // Connection: const std::string& GetConnectionURL() override; const std::string& GetRemoteApplicationURL() override; + uint32_t GetRemoteUserID() const override; void SetRemoteInterfaceProviderConnectionErrorHandler( const Closure& handler) override; bool GetRemoteApplicationID(uint32_t* remote_id) const override; @@ -58,6 +60,7 @@ class ConnectionImpl : public Connection { uint32_t remote_id_; bool remote_ids_valid_; std::vector<Closure> remote_id_callbacks_; + uint32_t remote_user_id_; InterfaceRegistry local_registry_; shell::mojom::InterfaceProviderPtr remote_interfaces_; diff --git a/mojo/shell/public/cpp/lib/shell_client.cc b/mojo/shell/public/cpp/lib/shell_client.cc index b3e83b5..6570068 100644 --- a/mojo/shell/public/cpp/lib/shell_client.cc +++ b/mojo/shell/public/cpp/lib/shell_client.cc @@ -10,7 +10,7 @@ ShellClient::ShellClient() {} ShellClient::~ShellClient() {} void ShellClient::Initialize(Shell* app, const std::string& url, - uint32_t id) { + uint32_t id, uint32_t user_id) { } bool ShellClient::AcceptConnection(Connection* connection) { diff --git a/mojo/shell/public/cpp/lib/shell_connection.cc b/mojo/shell/public/cpp/lib/shell_connection.cc index f9fca2f..8e03fb0 100644 --- a/mojo/shell/public/cpp/lib/shell_connection.cc +++ b/mojo/shell/public/cpp/lib/shell_connection.cc @@ -86,7 +86,9 @@ class AppRefCountImpl : public AppRefCount { ShellConnection::ConnectParams::ConnectParams(const std::string& url) - : url_(url), filter_(shell::mojom::CapabilityFilter::New()) { + : url_(url), + filter_(shell::mojom::CapabilityFilter::New()), + user_id_(shell::mojom::Shell::kUserInherit) { filter_->filter.SetToEmpty(); } ShellConnection::ConnectParams::~ConnectParams() {} @@ -147,9 +149,10 @@ scoped_ptr<Connection> ShellConnection::Connect(ConnectParams* params) { GetProxy(&remote_interfaces); scoped_ptr<internal::ConnectionImpl> registry(new internal::ConnectionImpl( application_url, application_url, - shell::mojom::Shell::kInvalidApplicationID, std::move(remote_interfaces), - std::move(local_request), allowed)); + shell::mojom::Shell::kInvalidApplicationID, params->user_id(), + std::move(remote_interfaces), std::move(local_request), allowed)); shell_->Connect(application_url, + params->user_id(), std::move(remote_request), std::move(local_interfaces), params->TakeFilter(), @@ -179,22 +182,24 @@ scoped_ptr<AppRefCount> ShellConnection::CreateAppRefCount() { void ShellConnection::Initialize(shell::mojom::ShellPtr shell, const mojo::String& url, - uint32_t id) { + uint32_t id, + uint32_t user_id) { shell_ = std::move(shell); shell_.set_connection_error_handler([this]() { OnConnectionError(); }); - client_->Initialize(this, url, id); + client_->Initialize(this, url, id, user_id); } void ShellConnection::AcceptConnection( const String& requestor_url, uint32_t requestor_id, + uint32_t requestor_user_id, shell::mojom::InterfaceProviderRequest local_interfaces, shell::mojom::InterfaceProviderPtr remote_interfaces, Array<String> allowed_interfaces, const String& url) { scoped_ptr<Connection> registry(new internal::ConnectionImpl( - url, requestor_url, requestor_id, std::move(remote_interfaces), - std::move(local_interfaces), + url, requestor_url, requestor_id, requestor_user_id, + std::move(remote_interfaces), std::move(local_interfaces), allowed_interfaces.To<std::set<std::string>>())); if (!client_->AcceptConnection(registry.get())) return; diff --git a/mojo/shell/public/cpp/shell.h b/mojo/shell/public/cpp/shell.h index 3b12cc9..f513f40 100644 --- a/mojo/shell/public/cpp/shell.h +++ b/mojo/shell/public/cpp/shell.h @@ -47,10 +47,13 @@ class Shell { void set_filter(shell::mojom::CapabilityFilterPtr filter) { filter_ = std::move(filter); } + void set_user_id(uint32_t user_id) { user_id_ = user_id; } + uint32_t user_id() const { return user_id_; } private: GURL url_; shell::mojom::CapabilityFilterPtr filter_; + uint32_t user_id_; DISALLOW_COPY_AND_ASSIGN(ConnectParams); }; diff --git a/mojo/shell/public/cpp/shell_client.h b/mojo/shell/public/cpp/shell_client.h index 7bd1298..b7a8e0e 100644 --- a/mojo/shell/public/cpp/shell_client.h +++ b/mojo/shell/public/cpp/shell_client.h @@ -26,10 +26,15 @@ class ShellClient { virtual ~ShellClient(); // Called once a bidirectional connection with the shell has been established. - // |url| is the URL used to start the application. |id| is a unique identifier - // the shell uses to identify this specific instance of the application. + // |url| is the URL used to start the application. + // |id| is a unique identifier the shell uses to identify this specific + // instance of the application. + // |user_id| identifies the user this instance is run as. // Called exactly once before any other method. - virtual void Initialize(Shell* shell, const std::string& url, uint32_t id); + virtual void Initialize(Shell* shell, + const std::string& url, + uint32_t id, + uint32_t user_id = 0); // Called when a connection to this client is brokered by the shell. Override // to expose services to the remote application. Return true if the connection diff --git a/mojo/shell/public/cpp/shell_connection.h b/mojo/shell/public/cpp/shell_connection.h index d0e9b5c..8132425 100644 --- a/mojo/shell/public/cpp/shell_connection.h +++ b/mojo/shell/public/cpp/shell_connection.h @@ -91,10 +91,12 @@ class ShellConnection : public Shell, public shell::mojom::ShellClient { // shell::mojom::ShellClient: void Initialize(shell::mojom::ShellPtr shell, const mojo::String& url, - uint32_t id) override; + uint32_t id, + uint32_t user_id) override; void AcceptConnection( const String& requestor_url, uint32_t requestor_id, + uint32_t requestor_user_id, shell::mojom::InterfaceProviderRequest remote_interfaces, shell::mojom::InterfaceProviderPtr local_interfaces, Array<String> allowed_interfaces, diff --git a/mojo/shell/public/interfaces/shell.mojom b/mojo/shell/public/interfaces/shell.mojom index ed3cbd0..d7160ea2 100644 --- a/mojo/shell/public/interfaces/shell.mojom +++ b/mojo/shell/public/interfaces/shell.mojom @@ -24,35 +24,61 @@ struct CapabilityFilter { // system and request connections to other applications. interface Shell { const uint32 kInvalidApplicationID = 0; + const uint32 kUserRoot = 0; + const uint32 kUserInherit = 1; - // Establishes a connection with another application ("target application") - // (located at |url|) through which the calling application and the - // target application may request services from one another. + // Requests a connection with another application. The application originating + // the request is referred to as the "source" and the one receiving the + // "target". // - // If the calling application would like to request services from the target - // application, it should pass a valid interface request in the |services| - // parameter (i.e. one containing a valid message pipe endpoint). If the - // target application does not wish to offer services, it may either not bind - // an implementation to the interface request, or else bind an implementation - // that will reject some or all service requests. + // The connection is embodied by a pair of message pipes binding the + // InterfaceProvider interface, which allows both the source and target + // applications to export interfaces to one another. The interfaces bound via + // these InterfaceProviders are brokered by the shell according to the + // security policy defined by each application in its manifest . // - // If the calling application would like to offer services to the target - // application, it should pass a bound interface through the - // |exposed_services| parameter. The target application may then request - // services through that interface. + // If the target application is not running, the shell will run it, calling + // its Initialize() method before completing the connection. // - // At least one of |services| or |exposed_services| should be valid/bound in - // the call. + // Parameters: // - // If the |application_url| does not contain a domain, but is of the form - // "mojo:{service}", it is up to the Mojo shell to select an appropriate - // application for the service. Currently, the shell does this based on the - // value of its --origin flag. + // url + // A mojo: or exe: URL identifying the target application. + // + // user_id + // The user id of the target application instance to connect to. If no such + // instance exists, the shell may start one. This user id will be passed + // to the new instance via Initialize(). Applications must generally set + // this to kUserInherit, and the shell will either connect to an existing + // instance matching the caller's user id, create a new instance matching + // the caller's user id, or connect to an existing instance running as + // kUserRoot. By default, applications do not have the ability to pass + // arbitrary values to this method, and doing so will result in a + // connection error on the remote service provider. An application with + // the ability to launch applications with arbitrary user ids (e.g. a login + // app) may set this value to something meaningful to it. + // + // remote_interfaces + // Allows the source application access to interface implementations + // exposed by the target application. The interfaces accessible via this + // InterfaceParameter are filtered by the security policy described by the + // source and target application manifests. + // + // local_interfaces + // Allows the remote application access to interface implementations + // exposed by the source application. The interfaces accessible via this + // InterfaceProvider are filtered by the security policy described by the + // source and target application manifests. + // + // filter + // Deprecated, to be removed. + // + // Response: (application_id) + // The shell responds with a unique identifier for the instance that was + // connected to. // - // |filter| is a whitelist of application URLs and services that the target - // application is permitted to connect to. See documentation for - // CapabilityFilter above. Connect(string url, + uint32 user_id, InterfaceProvider&? remote_interfaces, InterfaceProvider? local_interfaces, CapabilityFilter filter) => (uint32 application_id); diff --git a/mojo/shell/public/interfaces/shell_client.mojom b/mojo/shell/public/interfaces/shell_client.mojom index af0fcb6..575728d 100644 --- a/mojo/shell/public/interfaces/shell_client.mojom +++ b/mojo/shell/public/interfaces/shell_client.mojom @@ -7,63 +7,76 @@ module mojo.shell.mojom; import "mojo/shell/public/interfaces/interface_provider.mojom"; import "mojo/shell/public/interfaces/shell.mojom"; -// TODO(beng): rewrite these comments. -// This is the primary interface implemented by every Mojo application. It -// allows the application to receive its startup arguments from the shell, and -// to be notified of events that occur during its execution. -// -// TODO(aa): It would be good to reorder the parameters once we have interface -// versioning. +// Implemented by something "known to" the Mojo Shell (e.g. an application or +// service), for which an instance is tracked. It allows the implementor to +// receive lifecycle events and service inbound connection attempts. interface ShellClient { - // Initializes the application with the specified arguments. This method is - // guaranteed to be called before any other method is called, and will only be - // called once. + // Called by the shell once an instance for this application has been created. + // This method will be called exactly once before any other method is called. // - // The |url| parameter is the identity of the application as far as the shell - // is concerned. This will be the URL the application was found at, after all - // mappings, resolution, and redirects. And it will not include the - // querystring, since the querystring is not part of an application's - // identity. - // - // The |id| parameter is the identifier of the instance in the - // ApplicationManager. It can be passed to other shell interfaces that request - // an instance identifier. - Initialize(Shell shell, string url, uint32 id); + // Parameters: + // + // shell + // An interface back to the shell by which new connections may be + // established. + // + // url + // The resolved URL used in the connection request that resulted in this + // application being initialized. + // + // id + // A unique identifier used by the shell to identify this instance. + // + // user_id + // Identifies the user this instance is run as in the shell. This may + // differ from the user the application that caused this application to be + // instantiated is run as. This will always be a valid user id, never + // Shell::kUserInherit. + // + Initialize(Shell shell, string url, uint32 id, uint32 user_id); - // Called when another application (identified by |requestor_url|) attempts to - // open a connection to this application. + // Called when another application attempts to open a connection to this + // application. An application implements this method to complete the exchange + // of interface implementations with the remote application. See also + // documentation in shell.mojom for Connect(). The application originating + // the request is referred to as the "source" and the one receiving the + // "target". + // + // Parameters: + // + // requestor_url + // The URL of the source application. // - // If the other application wants to request services from this application, - // it will have passed a valid interface request through the |services| - // parameter (i.e. one containing a valid message pipe endpoint). This - // application may then bind an implementation of |InterfaceProvider| to that - // request in order to make services available to the other application. + // requestor_id + // A unique identifier used by the shell to identify the source + // application's instance. // - // If the other application wants to offer services to this application, it - // will have passed a bound interface through the |exposed_services| - // parameter. This application may then request services through that - // interface. + // requestor_user_id + // An identifier for the user the source application is run as. This may + // differ from the application the target is run as (i.e. the one received + // via Initialize() above). This will always be a valid user id, never + // Shell::kUserInherit. // - // It is possible that both parameters will be valid/bound if the other - // application wants to both request services from and offer services to this - // application. + // local_interfaces + // A request for an InterfaceProvider by which the source application may + // seek to bind interface implementations exported by the target. // - // This application is free to ignore the |services| or |exposed_services| - // parameters if it does not wish to offer or request services. + // remote_interfaces + // An InterfaceProvider by which the target application may bind interface + // implementations exported by the source. // - // |allowed_interfaces| is a set of interface names that the shell has - // determined can be exposed by this application to the connecting - // application. When this parameter is empty, this application should expose - // no services to the connecting application. When this parameter contains - // only the single string value "*" the application may expose all of its - // services to the connecting application. + // allowed_interfaces + // A whitelist of interface names that should be exported to the source, + // according to the security policy described by the source and target's + // manifests. Attempts to bind interfaces not in this whitelist must not be + // fulfilled. // - // |resolved_url| is the URL that was requested to create this connection, - // after all mappings, resolutions, and redirects. This will include any - // querystring that was part of the request. + // resolved_url + // The resolved URL used to complete this connection. // AcceptConnection(string requestor_url, uint32 requestor_id, + uint32 requestor_user_id, InterfaceProvider&? local_interfaces, InterfaceProvider? remote_interfaces, array<string> allowed_interfaces, diff --git a/mojo/shell/runner/child/native_apptest_target.cc b/mojo/shell/runner/child/native_apptest_target.cc index 5f322d7..d2747c5 100644 --- a/mojo/shell/runner/child/native_apptest_target.cc +++ b/mojo/shell/runner/child/native_apptest_target.cc @@ -29,7 +29,7 @@ class TargetApplicationDelegate private: // mojo::ShellClient: void Initialize(mojo::Shell* shell, const std::string& url, - uint32_t id) override {} + uint32_t id, uint32_t user_id) override {} bool AcceptConnection(mojo::Connection* connection) override { connection->AddInterface<mojo::shell::test::TestNativeService>(this); return true; diff --git a/mojo/shell/standalone/context.cc b/mojo/shell/standalone/context.cc index 2c49e73..a966020 100644 --- a/mojo/shell/standalone/context.cc +++ b/mojo/shell/standalone/context.cc @@ -155,9 +155,9 @@ void Context::Init(const base::FilePath& shell_file_root) { new TracingInterfaceProvider(&tracer_, GetProxy(&tracing_local_interfaces)); scoped_ptr<ConnectParams> params(new ConnectParams); - params->set_source(Identity(GURL("mojo:shell"), std::string(), - GetPermissiveCapabilityFilter())); + params->set_source(CreateShellIdentity()); params->set_target(Identity(GURL("mojo:tracing"), std::string(), + mojom::Shell::kUserInherit, GetPermissiveCapabilityFilter())); params->set_remote_interfaces(GetProxy(&tracing_remote_interfaces)); params->set_local_interfaces(std::move(tracing_local_interfaces)); @@ -227,8 +227,10 @@ void Context::Run(const GURL& url) { shell::mojom::InterfaceProviderPtr local_interfaces; scoped_ptr<ConnectParams> params(new ConnectParams); + params->set_source(CreateShellIdentity()); params->set_target( - Identity(url, std::string(), GetPermissiveCapabilityFilter())); + Identity(url, std::string(), mojom::Shell::kUserRoot, + GetPermissiveCapabilityFilter())); params->set_remote_interfaces(GetProxy(&remote_interfaces)); params->set_local_interfaces(std::move(local_interfaces)); application_manager_->Connect(std::move(params)); diff --git a/mojo/shell/tests/application_manager_apptest.cc b/mojo/shell/tests/application_manager_apptest.cc index 9a6b169..367b8fa 100644 --- a/mojo/shell/tests/application_manager_apptest.cc +++ b/mojo/shell/tests/application_manager_apptest.cc @@ -38,7 +38,8 @@ class ApplicationManagerAppTestDelegate private: // mojo::ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override {} + void Initialize(Shell* shell, const std::string& url, uint32_t id, + uint32_t user_id) override {} bool AcceptConnection(Connection* connection) override { connection->AddInterface<CreateInstanceForHandleTest>(this); return true; diff --git a/mojo/shell/tests/application_manager_apptest_driver.cc b/mojo/shell/tests/application_manager_apptest_driver.cc index 39fe9ed..aad9660 100644 --- a/mojo/shell/tests/application_manager_apptest_driver.cc +++ b/mojo/shell/tests/application_manager_apptest_driver.cc @@ -47,7 +47,7 @@ class TargetApplicationDelegate : public mojo::ShellClient, private: // mojo::ShellClient: void Initialize(mojo::Shell* shell, const std::string& url, - uint32_t id) override { + uint32_t id, uint32_t user_id) override { shell_ = shell; base::FilePath target_path; diff --git a/mojo/shell/tests/application_manager_apptest_target.cc b/mojo/shell/tests/application_manager_apptest_target.cc index 5b5964f..5284553 100644 --- a/mojo/shell/tests/application_manager_apptest_target.cc +++ b/mojo/shell/tests/application_manager_apptest_target.cc @@ -24,7 +24,7 @@ class TargetApplicationDelegate : public mojo::ShellClient { private: // mojo::ShellClient: void Initialize(mojo::Shell* shell, const std::string& url, - uint32_t id) override { + uint32_t id, uint32_t user_id) override { CreateInstanceForHandleTestPtr service; shell->ConnectToInterface("mojo:mojo_shell_apptests", &service); service->SetTargetID(id); diff --git a/mojo/shell/tests/application_manager_unittest.cc b/mojo/shell/tests/application_manager_unittest.cc index 48cf094..574a2c8 100644 --- a/mojo/shell/tests/application_manager_unittest.cc +++ b/mojo/shell/tests/application_manager_unittest.cc @@ -600,7 +600,10 @@ TEST_F(ApplicationManagerTest, TestEndApplicationClosure) { bool called = false; scoped_ptr<ConnectParams> params(new ConnectParams); - params->SetTargetURL(GURL("test:test")); + params->set_source(CreateShellIdentity()); + params->set_target( + Identity(GURL("test:test"), "", mojom::Shell::kUserRoot, + GetPermissiveCapabilityFilter())); application_manager_->SetInstanceQuitCallback( base::Bind(&QuitClosure, params->target(), &called)); application_manager_->Connect(std::move(params)); diff --git a/mojo/shell/tests/capability_filter_test.cc b/mojo/shell/tests/capability_filter_test.cc index 40c9370..b9240d6 100644 --- a/mojo/shell/tests/capability_filter_test.cc +++ b/mojo/shell/tests/capability_filter_test.cc @@ -115,7 +115,8 @@ class ServiceApplication : public ShellClient, private: // Overridden from ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override { + void Initialize(Shell* shell, const std::string& url, uint32_t id, + uint32_t user_id) override { shell_ = shell; // ServiceApplications have no capability filter and can thus connect // directly to the validator application. @@ -162,7 +163,7 @@ TestApplication::TestApplication() : shell_(nullptr) {} TestApplication::~TestApplication() {} void TestApplication::Initialize(Shell* shell, const std::string& url, - uint32_t id) { + uint32_t id, uint32_t user_id) { shell_ = shell; url_ = url; } @@ -327,7 +328,9 @@ void CapabilityFilterTest::RunApplication(const std::string& url, shell::mojom::InterfaceProviderPtr local_interfaces; new InterfaceProviderImpl(GetProxy(&local_interfaces), validator_); scoped_ptr<ConnectParams> params(new ConnectParams); - params->set_target(Identity(GURL(url), std::string(), filter)); + params->set_source(CreateShellIdentity()); + params->set_target(Identity(GURL(url), std::string(), + mojom::Shell::kUserInherit, filter)); params->set_remote_interfaces(GetProxy(&remote_interfaces)); params->set_local_interfaces(std::move(local_interfaces)); quit_identities_.insert(params->target()); diff --git a/mojo/shell/tests/capability_filter_test.h b/mojo/shell/tests/capability_filter_test.h index 0efc62c..45a5fa8 100644 --- a/mojo/shell/tests/capability_filter_test.h +++ b/mojo/shell/tests/capability_filter_test.h @@ -29,7 +29,8 @@ class TestApplication : public ShellClient { private: // Overridden from ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override; + void Initialize(Shell* shell, const std::string& url, uint32_t id, + uint32_t user_id) override; bool AcceptConnection(Connection* connection) override; void ConnectionClosed(const std::string& service_url); diff --git a/mojo/shell/tests/package_test_package.cc b/mojo/shell/tests/package_test_package.cc index 4a37ebe..a9defe4 100644 --- a/mojo/shell/tests/package_test_package.cc +++ b/mojo/shell/tests/package_test_package.cc @@ -49,7 +49,8 @@ class ProvidedShellClient private: // mojo::ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override { + void Initialize(Shell* shell, const std::string& url, + uint32_t id, uint32_t user_id) override { shell_ = shell; bindings_.set_connection_error_handler( base::Bind(&ProvidedShellClient::OnConnectionError, @@ -104,7 +105,8 @@ class PackageTestShellClient private: // mojo::ShellClient: - void Initialize(Shell* shell, const std::string& url, uint32_t id) override { + void Initialize(Shell* shell, const std::string& url, + uint32_t id, uint32_t user_id) override { shell_ = shell; bindings_.set_connection_error_handler( base::Bind(&PackageTestShellClient::OnConnectionError, |