| // Copyright 2022 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.sandbox; |
| |
| using zx; |
| using fuchsia.io; |
| |
| /// Maximum number of bytes in a [DataCapability]. |
| const MAX_DATA_LENGTH uint32 = 8192; |
| |
| /// Maximum number of items returned by [DictionaryItemIterator]. |
| const MAX_DICTIONARY_ITEMS_CHUNK uint32 = 128; |
| |
| /// Maximum number of items returned by [DictionaryKeyIterator]. |
| const MAX_DICTIONARY_KEYS_CHUNK uint32 = 128; |
| |
| @available(added=HEAD) |
| type OneShotHandle = resource struct { |
| token zx.Handle:EVENTPAIR; |
| }; |
| |
| @available(added=HEAD) |
| type DataCapability = flexible union { |
| 1: bytes vector<byte>:MAX_DATA_LENGTH; |
| 2: string string:MAX_DATA_LENGTH; |
| 3: int64 int64; |
| 4: uint64 uint64; |
| }; |
| |
| @available(added=HEAD) |
| type Connector = resource struct { |
| token zx.Handle:EVENTPAIR; |
| }; |
| |
| @available(added=HEAD) |
| type Capability = flexible resource union { |
| 1: unit @generated_name("UnitCapability") struct {}; |
| 2: handle OneShotHandle; |
| 3: data DataCapability; |
| 4: dictionary client_end:Dictionary; |
| 5: connector Connector; |
| 6: directory client_end:fuchsia.io.Directory; |
| 7: router client_end:Router; |
| }; |
| |
| /// The maximum length of a dictionary key. This should coincide with |
| /// fuchsia.component.MAX_NAME_LENGTH. |
| @available(added=HEAD) |
| const MAX_NAME_LENGTH uint64 = fuchsia.io.MAX_NAME_LENGTH; |
| |
| /// The key of a [`DictionaryItem`]. The constraints for valid keys are documented at |
| /// https://fuchsia.dev/reference/cml#names. |
| @available(added=HEAD) |
| alias DictionaryKey = string:MAX_NAME_LENGTH; |
| |
| /// A key-value pair in a [`Dictionary`]. |
| @available(added=HEAD) |
| type DictionaryItem = resource struct { |
| key DictionaryKey; |
| value Capability; |
| }; |
| |
| /// Error returned from methods in [`Dictionary`]. |
| @available(added=HEAD) |
| type DictionaryError = flexible enum { |
| /// The Dictionary does not contain an item with the given key. |
| NOT_FOUND = 1; |
| |
| /// The Dictionary already contains an item with the given key. |
| ALREADY_EXISTS = 2; |
| |
| /// The Capability is invalid. |
| /// |
| /// Capabilities must be created by sandbox, via |
| /// `fuchsia.component.sandbox.Factory` or returned from other |
| /// Component Framework APIs. |
| BAD_CAPABILITY = 3; |
| |
| /// The key is invalid. The constraints for valid keys are documented at |
| /// https://fuchsia.dev/reference/cml#names. |
| INVALID_KEY = 4; |
| }; |
| |
| @discoverable |
| @available(added=20) |
| open protocol Dictionary { |
| /// Inserts a key-value pair into the dictionary. |
| /// |
| /// * error `DictionaryError.ALREADY_EXISTS` if the dictionary already contains an |
| /// item with the same key. |
| @available(added=HEAD) |
| flexible Insert(DictionaryItem) -> () error DictionaryError; |
| |
| /// Get a clone of a capability from this dictionary. |
| /// |
| /// * error `DictionaryError.NOT_FOUND` if the dictionary does not contain the key. |
| @available(added=HEAD) |
| flexible Get(struct { |
| key DictionaryKey; |
| }) -> (resource struct { |
| capability Capability; |
| }) error DictionaryError; |
| |
| /// Removes a key from the dictionary, returning the [`Capability`] value. |
| /// |
| /// * error `DictionaryError.NOT_FOUND` if the dictionary does not contain the key. |
| @available(added=HEAD) |
| flexible Remove(struct { |
| key DictionaryKey; |
| }) -> (resource struct { |
| capability Capability; |
| }) error DictionaryError; |
| |
| /// Creates a new connection to the same underlying dictionary. |
| /// |
| /// Use `Copy` to a new dictionary with clones of all the exiting entries. |
| @available(added=HEAD) |
| flexible Clone() -> (resource struct { |
| dictionary client_end:Dictionary; |
| }); |
| |
| /// Create a new dictionary that contains a clone of all the entries in |
| /// this dictionary. |
| /// |
| /// For example, if this dictionary contains nested dictionaries, the newly |
| /// created dictionary will contain references to those same nested |
| /// dictionaries because the entries are cloned rather than copied. |
| @available(added=HEAD) |
| flexible Copy() -> (resource struct { |
| dictionary client_end:Dictionary; |
| }); |
| |
| /// Enumerates the items in this dictionary. |
| /// |
| /// Creates a clone of each item during enumeration. |
| @available(added=HEAD) |
| flexible Enumerate(resource struct { |
| iterator server_end:DictionaryItemIterator; |
| }); |
| |
| /// Enumerates the keys in this dictionary. |
| @available(added=HEAD) |
| flexible Keys(resource struct { |
| iterator server_end:DictionaryKeyIterator; |
| }); |
| |
| |
| /// Removes all the entries in this dictionary. |
| /// |
| /// If `contents` is not provided, all the items are discarded without |
| /// enumerating them. |
| @available(added=HEAD) |
| flexible Drain(resource struct { |
| iterator server_end:<DictionaryItemIterator, optional>; |
| }); |
| }; |
| |
| @available(added=HEAD) |
| open protocol DictionaryItemIterator { |
| flexible GetNext() -> (resource struct { |
| items vector<DictionaryItem>:MAX_DICTIONARY_ITEMS_CHUNK; |
| }); |
| }; |
| |
| @available(added=HEAD) |
| open protocol DictionaryKeyIterator { |
| flexible GetNext() -> (resource struct { |
| keys vector<DictionaryKey>:MAX_DICTIONARY_KEYS_CHUNK; |
| }); |
| }; |
| |
| /// This represents a component within the framework. |
| /// There are currently no methods here as this is used as a token. |
| @available(added=HEAD) |
| type ComponentToken = resource struct { |
| token zx.Handle:EVENTPAIR; |
| }; |
| |
| /// A request for a route. |
| @available(added=HEAD) |
| type RouteRequest = resource table { |
| /// The requested availability for this capability. |
| 1: availability Availability; |
| /// The component that is requesting the capability. |
| 2: requesting ComponentToken; |
| }; |
| |
| @available(added=HEAD) |
| type RouterError = flexible enum : uint32 { |
| /// The router failed to find the capability. |
| NOT_FOUND = 1; |
| |
| /// The arguments provided to the function are invalid. |
| INVALID_ARGS = 2; |
| }; |
| |
| /// A router allows a client to request a capability. |
| @discoverable |
| @available(added=HEAD) |
| open protocol Router { |
| flexible Route(RouteRequest) -> (resource struct { |
| capability Capability; |
| }) error RouterError; |
| }; |
| |
| /// A receiver is served by clients and allows them to receive channels |
| /// from the framework. |
| @discoverable |
| @available(added=HEAD) |
| open protocol Receiver { |
| /// Sends a channel to this receiver. |
| flexible Receive(ProtocolPayload); |
| }; |
| |
| /// Contains a protocol open request. |
| @available(added=HEAD) |
| type ProtocolPayload = resource struct { |
| channel zx.Handle:CHANNEL; |
| }; |
| |
| @available(added=HEAD) |
| type FactoryError = flexible enum : uint32 { |
| /// An invalid argument was passed. |
| INVALID_ARGS = 1; |
| |
| /// The requested resource was unavailable. |
| UNAVAILABLE = 2; |
| }; |
| |
| /// The [`Factory`] protocol handles: |
| /// |
| /// - Instantiation of sandbox types. |
| /// - Controlling sandbox objects given tokens. |
| /// |
| @discoverable |
| @available(added=HEAD) |
| open protocol Factory { |
| /// Open a connection from the provided [Connector] capability. |
| /// |
| /// If there is an error, it will be reported as a zx.Status epitaph on `server_end`. |
| /// Errors: |
| /// |
| /// - `INVALID_ARGS`: `capability` is not a recognized [Connector]. |
| flexible OpenConnector(resource struct { |
| capability Connector; |
| server_end zx.Handle:CHANNEL; |
| }); |
| |
| /// Extract the handle owned by the underlying `capability`, if it wasn't taken already. |
| /// |
| /// Errors: |
| /// |
| /// - `INVALID_ARGS`: `capability` does not contain a recognized [OneShotHandle] token. |
| /// - `UNAVAILABLE`: The underlying handle was already taken.h |
| flexible TakeHandle(resource struct { |
| capability OneShotHandle; |
| }) -> (resource struct { |
| handle zx.Handle; |
| }) error FactoryError; |
| |
| /// Creates a `Connector` from a client served `Receiver`. |
| flexible CreateConnector(resource struct { |
| receiver client_end:Receiver; |
| }) -> (resource struct { |
| capability Connector; |
| }); |
| |
| /// Creates a `OneShotHandle` from the provided `handle`. |
| flexible CreateOneShotHandle(resource struct { |
| handle zx.Handle; |
| }) -> (resource struct { |
| capability OneShotHandle; |
| }); |
| |
| /// Creates a new empty [`Dictionary`]. |
| flexible CreateDictionary() -> (resource struct { |
| dictionary client_end:Dictionary; |
| }); |
| }; |