|  | // Copyright 2016 The Fuchsia Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | library fuchsia.component.runner; | 
|  |  | 
|  | using fuchsia.data; | 
|  | using fuchsia.io; | 
|  | using fuchsia.component; | 
|  | using fuchsia.url; | 
|  |  | 
|  | const uint32 MAX_NAMESPACE_COUNT = 32; | 
|  |  | 
|  | /// A protocol used for running components. | 
|  | /// | 
|  | /// This protocol is implemented by components which provide a runtime | 
|  | /// environment for other components. | 
|  | /// | 
|  | /// Note: The component manager is the only intended direct client of this | 
|  | /// interface. | 
|  | [Discoverable] | 
|  | protocol ComponentRunner { | 
|  | /// Start running a component instance described by `start_info`. | 
|  | /// | 
|  | /// Component manager binds and uses `controller` to control the | 
|  | /// lifetime of the newly started component instance. | 
|  | /// | 
|  | /// Errors are delivered as epitaphs over the `ComponentController` | 
|  | /// protocol. In the event of an error, the runner must ensure that | 
|  | /// resources are cleaned up. | 
|  | /// | 
|  | /// Errors: | 
|  | /// | 
|  | Start(ComponentStartInfo start_info, | 
|  | request<ComponentController> controller); | 
|  | }; | 
|  |  | 
|  | /// A single component namespace entry, which describes a namespace mount point | 
|  | /// (`path`) and the directory backing it (`directory`). This type is usually | 
|  | /// composed inside a vector.  See `ComponentStartInfo.ns` for more details. | 
|  | table ComponentNamespaceEntry { | 
|  | /// The mount point for the directory, including a | 
|  | /// leading slash. For example: "/pkg", "/svc", or "/config/data". | 
|  | 1: string:fuchsia.component.MAX_PATH_LENGTH path; | 
|  |  | 
|  | /// The directory mounted at the above `path`. | 
|  | 2: fuchsia.io.Directory directory; | 
|  | }; | 
|  |  | 
|  | /// Parameters for starting a new component instance. | 
|  | table ComponentStartInfo { | 
|  | /// The resolved URL of the component. | 
|  | /// | 
|  | /// This is the canonical URL obtained by the component resolver after | 
|  | /// following redirects and resolving relative paths. | 
|  | 1: fuchsia.url.Url resolved_url; | 
|  |  | 
|  | /// The component's program declaration. | 
|  | /// This information originates from `ComponentDecl.program`. | 
|  | 2: fuchsia.data.Dictionary program; | 
|  |  | 
|  | /// The namespace to provide to the component instance. | 
|  | /// | 
|  | /// A namespace specifies the set of directories that a component instance | 
|  | /// receives at start-up. Through the namespace directories, a component | 
|  | /// may access capabilities available to it. The contents of the namespace | 
|  | /// are mainly determined by the component's `use` declarations but may | 
|  | /// also contain additional capabilities automatically provided by the | 
|  | /// framework. | 
|  | /// | 
|  | /// By convention, a component's namespace typically contains some or all | 
|  | /// of the following directories: | 
|  | /// | 
|  | /// - "/svc": A directory containing services that the component requested | 
|  | ///           to use via its "import" declarations. | 
|  | /// - "/pkg": A directory containing the component's package, including its | 
|  | ///           binaries, libraries, and other assets. | 
|  | /// | 
|  | /// The mount points specified in each entry must be unique and | 
|  | /// non-overlapping. For example, [{"/foo", ..}, {"/foo/bar", ..}] is | 
|  | /// invalid. | 
|  | 3: vector<ComponentNamespaceEntry>:MAX_NAMESPACE_COUNT ns; | 
|  |  | 
|  | /// The directory this component serves. | 
|  | 4: request<fuchsia.io.Directory> outgoing_dir; | 
|  |  | 
|  | /// The directory served by the runner to present runtime information about | 
|  | /// the component. | 
|  | 5: request<fuchsia.io.Directory> runtime_dir; | 
|  | }; | 
|  |  | 
|  | /// A protocol for binding and controlling the lifetime of a component instance | 
|  | /// started using `ComponentRunner.Start()`. The component manager is the | 
|  | /// intended direct client of this protocol. | 
|  | /// | 
|  | /// When the controlled component instance terminates or becomes inaccessible | 
|  | /// for any reason, the server closes the connection with an epitaph. | 
|  | /// | 
|  | /// LIFECYCLE | 
|  | /// | 
|  | /// A component may exist in one of two states: `Started`, or `Stopped`. The | 
|  | /// component is `Started` from the time `ComponentRunner.Start()` is called | 
|  | /// until the ComponentRunner closes the ComponentController handle. The | 
|  | /// component then transitions to `Stopped`. | 
|  | /// | 
|  | /// Component manager uses ComponentController to terminate a component in two | 
|  | /// steps: | 
|  | ///  1) Component manager calls `Stop()` to indicate that the ComponentRunner | 
|  | ///     should stop a component's execution and close this connection with an | 
|  | ///     epitaph. | 
|  | ///  2) If after some time the ComponentController is not closed, component | 
|  | ///     manager calls `Kill()` to indicate that the ComponentRunner must halt a | 
|  | ///     component's execution immediately, and then close this connection with | 
|  | ///     an epitaph. | 
|  | /// | 
|  | /// Component manager first waits for the ComponentController to close, and | 
|  | /// then tears down the namespace it hosts for the stopped component. Component | 
|  | /// manager may call `Kill()` without first having called `Stop()`. | 
|  | /// | 
|  | /// EPITAPH | 
|  | /// | 
|  | /// This protocol sends a FIDL epitaph to indicate that the component instance | 
|  | /// has been terminated. The component runner is expected to clean up all | 
|  | /// resources attributed to the component before closing the connection. | 
|  | /// | 
|  | /// The following epitaphs may be sent by the server on error: | 
|  | /// - `INVALID_ARGUMENTS`: | 
|  | ///     * `start_info.resolved_url` is not supported by this | 
|  | ///       runner; | 
|  | ///     * `start_info` contains missing or invalid arguments. | 
|  | /// - `INSTANCE_CANNOT_START`: The runner could not start the component. | 
|  | ///   For example, a critical part of the program could not be found or | 
|  | ///   loaded, or the referenced binary was invalid for this runner. | 
|  | /// - `RESOURCE_UNAVAILABLE`: The component could not be launched due to | 
|  | ///   lack of resources. | 
|  | /// - `INTERNAL`: An unexpected internal runner error was encountered. | 
|  | /// - `INSTANCE_DIED`: The component instance was started but | 
|  | ///   subsequently terminated, possibly because it crashed or possibly | 
|  | ///   because it exited voluntarily. | 
|  | /// - `ZX_OK`: The component instance was successfully terminated without | 
|  | ///   error. | 
|  | /// - Other status codes (e.g. `ZX_ERR_PEER_CLOSED`) may indicate a failure | 
|  | ///   of the component runner itself. The component manager may respond to such | 
|  | ///   failures by terminating the component runner's job to ensure system | 
|  | ///   stability. | 
|  | protocol ComponentController { | 
|  | /// Request to stop the component instance. | 
|  | /// | 
|  | /// After stopping the component instance, the server should close this | 
|  | /// connection with an epitaph. After the connection | 
|  | /// closes, component manager considers this component instance to be | 
|  | /// Stopped and the component's namespace will be torn down. | 
|  | Stop(); | 
|  |  | 
|  | /// Stop this component instance immediately. | 
|  | /// | 
|  | /// The ComponentRunner must immediately kill the component instance, and | 
|  | /// then close this connection with an epitaph. After the connection | 
|  | /// closes, component manager considers this component instance to be | 
|  | /// Stopped and the component's namespace will be torn down. | 
|  | /// | 
|  | /// In some cases Kill() may be issued before Stop(), but that is not | 
|  | /// guaranteed. | 
|  | Kill(); | 
|  | }; |