| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SERVICES_SERVICE_MANAGER_PUBLIC_CPP_MANIFEST_H_ |
| #define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_MANIFEST_H_ |
| |
| #include <map> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/component_export.h" |
| #include "base/files/file_path.h" |
| |
| namespace service_manager { |
| |
| // Represents metadata about a service that the Service Manager needs in order |
| // to start and control instances of that given service. This data is provided |
| // to the Service Manager at initialization time for every known service in the |
| // system. |
| // |
| // A service will typically define a dedicated manifest target in their public |
| // C++ client library with a single GetManifest() function that returns a |
| // const ref to a function-local static Manifest. Then any Service Manager |
| // embedder can reference the manifest in order to include support for that |
| // service within its runtime environment. |
| // |
| // Instead of constructing a Manifest manually, prefer to use a ManifestBuilder |
| // defined in manifest_builder.h for more readable and maintainable manifest |
| // definitions. |
| struct COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Manifest { |
| public: |
| using ServiceName = std::string; |
| using CapabilityName = std::string; |
| using InterfaceName = std::string; |
| using InterfaceNameSet = std::set<InterfaceName>; |
| using CapabilityNameSet = std::set<CapabilityName>; |
| using ExposedCapabilityMap = std::map<CapabilityName, InterfaceNameSet>; |
| using RequiredCapabilityMap = std::map<ServiceName, CapabilityNameSet>; |
| |
| // Represents the display name of this service (in e.g. a task manager). |
| struct COMPONENT_EXPORT(SERVICE_MANAGER_CPP) DisplayName { |
| enum class Type { kDefault, kRawString, kResourceId }; |
| |
| DisplayName() : type(Type::kDefault) {} |
| explicit DisplayName(const char* raw_string) |
| : type(Type::kRawString), raw_string(raw_string) {} |
| explicit DisplayName(int resource_id) |
| : type(Type::kResourceId), resource_id(resource_id) {} |
| |
| Type type; |
| union { |
| const char* raw_string; |
| int resource_id; |
| }; |
| }; |
| |
| enum class InstanceSharingPolicy { |
| // Instances of the service are never shared across groups or instance IDs. |
| // Every tuple of group and instance ID corresponds to a unique instance. |
| kNoSharing, |
| |
| // Only one instance of the service can exist at a time, and any combination |
| // of group and instance ID refers to the same single instance. i.e. group |
| // and instance ID are effectively ignored when locating the instance of |
| // this service on behalf of clients. |
| kSingleton, |
| |
| // At most one instance of this service will exist with a given instance ID. |
| // i.e., instance group is effectively ignored when locating an instance of |
| // the service on behalf of a client. |
| kSharedAcrossGroups, |
| }; |
| |
| // Indicates how instances of this service are launched. Ignored if this |
| // manifest is packaged within another manifest, as launch is always delegated |
| // to some instance of the packaging service in that case. See |
| // |packaged_services| below for more information about packaged service |
| // manifests. |
| enum class ExecutionMode { |
| // The service implementation is built into the Service Manager embedder's |
| // binary (for example Chromium, or any Content embedder), and the embedder |
| // handles requests for new instances of the service in-process via |
| // ServiceManager::Delegate::RunBuiltinServiceInstanceInCurrentProcess(). |
| // |
| // If a service uses this ExecutionMode in Chromium for example, that means |
| // the service always runs in the browser process. |
| kInProcessBuiltin, |
| |
| // The service implementation is built into the Service Manager embedder's |
| // binary (for example Chromium, or any Content embedder), and the embedder |
| // handles requests for new instances of the service via |
| // ServiceProcess::Delegate::RunService(). The service will always run in |
| // a child process sandboxed according to sandbox::mojom::Sandbox (see |
| // Options below). |
| kOutOfProcessBuiltin, |
| |
| // The service is launched out-of-process from a standalone service |
| // executable on disk within the running application's directory. The name |
| // of the executable is expected to be "${service_name}.service" (or |
| // "${service_name}.service.exe" on Windows). |
| // |
| // Proper sandboxing is currently not supported for standalone service |
| // executables, so sandbox::mojom::Sandbox (see Options below) is |
| // ignored. This renders |
| // standalone service executables generally unsuitable for production |
| // environments. |
| kStandaloneExecutable, |
| }; |
| |
| // Miscellanous options which control how the service is launched and how it |
| // can interact with other service instances in the system. |
| struct COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Options { |
| Options(); |
| Options(const Options&); |
| Options(Options&&); |
| ~Options(); |
| |
| Options& operator=(Options&&); |
| Options& operator=(const Options&); |
| |
| // Indicates how instances of this service may be shared across clients. |
| InstanceSharingPolicy instance_sharing_policy = |
| InstanceSharingPolicy::kNoSharing; |
| |
| // If |true|, this service is allowed to connect to other service instances |
| // in instance groups other than its own. This is considered a privileged |
| // capability, as instance grouping provides natural boundaries for service |
| // instance isolation. |
| bool can_connect_to_instances_in_any_group = false; |
| |
| // If |true|, this service is allowed to connect to other services instances |
| // with a specific instance ID. This is considered a privileged capability |
| // since it allows this service to instigate the creation of an arbitrary |
| // number of service instances. |
| bool can_connect_to_instances_with_any_id = false; |
| |
| // If |true|, this service is allowed to directly register new service |
| // instances with the Service Manager. This is considered a privileged |
| // capability since it grants this service a significant degree of control |
| // over the entire system's behavior. For example, the service could |
| // completely replace other system services and therefore intercept requests |
| // intended for those services. |
| bool can_register_other_service_instances = false; |
| |
| // Indicates how instances of this service are launched. Ignored iff this |
| // manifest is packaged within another service's manifest. |
| ExecutionMode execution_mode = ExecutionMode::kInProcessBuiltin; |
| |
| // The type of sandboxing required by instances of this service. Only used |
| // if |execution_mode| is |kOutOfProcessBuiltin| or |
| // |kStandaloneExecutable|. |
| // |
| // TODO(https://crbug.com/915806): Make this field a |
| // sandbox::mojom::Sandbox enum. |
| std::string sandbox_type{"utility"}; |
| }; |
| |
| // Represents a file required by instances of the service despite being |
| // inaccessible to the service directly, due to e.g. sandboxing constraints. |
| // |
| // Currently ignored on platforms other than Android and Linux. |
| struct PreloadedFileInfo { |
| // A key which can be used by the service implementation to locate the |
| // file's open descriptor via |base::FileDescriptorStore|. |
| std::string key; |
| |
| // The path to the file. On Linux this is relative to the main Service |
| // Manager embedder's executable (i.e. relative to base::DIR_EXE.) On |
| // Android it's an APK asset path. |
| base::FilePath path; |
| }; |
| |
| // A helper for Manifest writers to create a set of interfaces to be used in |
| // in exposed capabilities. |
| template <typename... InterfaceTypes> |
| struct InterfaceList {}; |
| |
| Manifest(); |
| Manifest(const Manifest&); |
| Manifest(Manifest&&); |
| |
| ~Manifest(); |
| |
| Manifest& operator=(const Manifest&); |
| Manifest& operator=(Manifest&&); |
| |
| // Amends this Manifest with a subset of |other|. Namely, exposed and required |
| // capabilities, exposed and required interface filter capabilities, packaged |
| // services, and preloaded files are all added from |other| if present. |
| Manifest& Amend(Manifest other); |
| |
| ServiceName service_name; |
| DisplayName display_name; |
| Options options; |
| |
| // All capabilities exposed by this service. The key is the name of the |
| // capability, which is an arbitrary string value chosen by and scoped to the |
| // service. The value is a set of mojom interface names, conveying the set of |
| // interfaces to which this capability grants access via the Service Manager. |
| // See |required_capabilities| for information on how another service can have |
| // that access granted to them. |
| ExposedCapabilityMap exposed_capabilities; |
| |
| // All capabilities required by this service. The key is the name of another |
| // service, and the corresponding value is the set of (names of) capabilities |
| // required from that service. |
| // |
| // If a service A declares in its manifest that it requires a capability X |
| // from service B, then A will be allowed to request any interface exposed |
| // through X (i.e. through the capability in the |exposed_capabilities| field |
| // of B's manifest), using |BindInterface()| on A's Connector. |
| RequiredCapabilityMap required_capabilities; |
| |
| // DEPRECATED: This will be removed soon. Don't add new uses of interface |
| // filters. Instead prefer to define explicit broker interfaces and expose |
| // them through |exposed_capabilities|. |
| // |
| // Services may define capabilities to be scoped within a named interface |
| // filter. These capabilities do not apply to normal interface binding |
| // requests (i.e. requests made by clients through |Connector.BindInterface|). |
| // Instead, the exposing service may use |Connector.FilterInterfaces| to |
| // set up an InterfaceProvider pipe proxied through the Service Manager. The |
| // Service Manager will filter interface requests on that pipe according to |
| // the given filter name and remote service name. The remote service must in |
| // turn require one or more capabilities from the named filter in order to |
| // access any interfaces via the proxied InterfaceProvider, which the exposing |
| // service must pass to the remote service somehow. |
| // |
| // If this all sounds very confusing, that's because it is very confusing. |
| // Hence the "DEPRECATED" bit. |
| using FilterName = std::string; |
| std::map<FilterName, ExposedCapabilityMap> |
| exposed_interface_filter_capabilities; |
| |
| // DEPRECATED: This will be removed soon. Don't add new uses of interface |
| // filters. |
| // |
| // This is like |required_capabilities|, except that it only grants the |
| // requiring/ service access to a set of interfaces on a specific |
| // InterfaceProvider, filtered by the exposing service according to an |
| // |exposed_interface_filter_capabilities| in that service's manifest. See |
| // notes on that field above. |
| std::map<FilterName, RequiredCapabilityMap> |
| required_interface_filter_capabilities; |
| |
| // A list of manifests for services "packaged" by this service. For a service |
| // Y to be packaged within a service X means that the Service Manager will |
| // always delegate creation of Y instances to an instance of X via calls to |
| // |Service::CreatePackagedServiceInstance()|. |
| // |
| // See |
| // https://chromium.googlesource.com/chromium/src/+/main/services/service_manager/README.md#Packaging |
| // for more information. |
| std::vector<Manifest> packaged_services; |
| std::vector<PreloadedFileInfo> preloaded_files; |
| |
| // The list of interfaces that this service are allowed to connect to |
| // unconditionally on any service. |
| InterfaceNameSet interfaces_bindable_on_any_service; |
| }; |
| |
| } // namespace service_manager |
| |
| #endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_MANIFEST_H_ |