| // 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; |
| using fuchsia.unknown; |
| |
| /// Maximum number of bytes in a [DataCapability]. |
| const MAX_DATA_LENGTH uint32 = 8192; |
| |
| /// Maximum number of items returned by [DictIterator]. |
| const MAX_DICT_ITEMS_CHUNK uint32 = 128; |
| |
| closed protocol HandleCapability { |
| compose fuchsia.unknown.Cloneable; |
| strict GetHandle() -> (resource struct { |
| handle zx.Handle; |
| }) error @generated_name("HandleCapabilityError") strict enum { |
| UNAVAILABLE = 1; |
| }; |
| }; |
| |
| type DataCapability = flexible union { |
| 1: bytes vector<byte>:MAX_DATA_LENGTH; |
| 2: string string:MAX_DATA_LENGTH; |
| 3: int64 int64; |
| 4: uint64 uint64; |
| }; |
| |
| type OptionalCapability = resource struct { |
| value Capability:optional; |
| }; |
| |
| type Capability = flexible resource union { |
| 1: unit @generated_name("UnitCapability") struct {}; |
| 2: opaque zx.Handle:EVENT; |
| 3: handle client_end:HandleCapability; |
| 4: data DataCapability; |
| 5: cloneable client_end:fuchsia.unknown.Cloneable; |
| 6: dict client_end:Dict; |
| 7: sender client_end:Sender; |
| 8: receiver server_end:Receiver; |
| 9: open client_end:fuchsia.io.Openable; |
| 10: directory client_end:fuchsia.io.Directory; |
| 11: optional OptionalCapability; |
| }; |
| |
| /// The key of a [`DictItem`]. |
| alias DictKey = string:MAX; |
| |
| /// A key-value pair in a [`Dict`]. |
| type DictItem = resource struct { |
| key DictKey; |
| value Capability; |
| }; |
| |
| /// Error returned from methods in [`Dict`]. |
| type DictError = flexible enum { |
| /// The Dict does not contain an item with the given key. |
| NOT_FOUND = 1; |
| |
| /// The Dict already contains an item with the given key. |
| ALREADY_EXISTS = 2; |
| |
| /// The Capability is invalid. |
| /// |
| /// Capabilites must be created by sandbox, via |
| /// `fuchsia.component.sandbox.Factory` or returned from other |
| /// Component Framework APIs. |
| BAD_CAPABILITY = 3; |
| }; |
| |
| @discoverable |
| open protocol Dict { |
| /// Creates a new connection to the same underlying dictionary. |
| /// |
| /// Use `Copy` to a new dictionary with clones of all the exiting entries. |
| compose fuchsia.unknown.Cloneable; |
| |
| /// Inserts a key-value pair into the dict. |
| /// |
| /// * error `DictError.ALREADY_EXISTS` if the dict already contains an |
| /// item with the same key. |
| flexible Insert(DictItem) -> () error DictError; |
| |
| /// Get a clone of a capability from this dictionary. |
| /// |
| /// * error `DictError.NOT_FOUND` if the dict does not contain the key. |
| flexible Get(struct { |
| key DictKey; |
| }) -> (resource struct { |
| capability Capability; |
| }) error DictError; |
| |
| /// Removes a key from the dict, returning the [`Capability`] value. |
| /// |
| /// * error `DictError.NOT_FOUND` if the dict does not contain the key. |
| flexible Remove(struct { |
| key DictKey; |
| }) -> (resource struct { |
| capability Capability; |
| }) error DictError; |
| |
| /// Returns all items in this dict, sorted by key in natural order. |
| /// |
| /// This operation creates shallow clones of values. |
| // TODO(b/314361448): Remove once callers use Dict.Enumerate instead |
| flexible Read() -> (resource struct { |
| items vector<DictItem>:MAX; |
| }); |
| |
| /// 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. |
| flexible Copy(resource struct { |
| request server_end:Dict; |
| }); |
| |
| /// Enumerates the entries in this dictionary. |
| /// |
| /// Creates a clone of each item during enumeration. |
| flexible Enumerate(resource struct { |
| contents server_end:DictIterator; |
| }); |
| |
| /// Removes all the entries in this dictionary. |
| /// |
| /// If `contents` is not provided, all the items are discarded without |
| /// enumerating them. |
| flexible Drain(resource struct { |
| contents server_end:<DictIterator, optional>; |
| }); |
| }; |
| |
| open protocol DictIterator { |
| flexible GetNext() -> (resource struct { |
| items vector<DictItem>:MAX_DICT_ITEMS_CHUNK; |
| }); |
| }; |
| |
| @discoverable |
| open protocol Sender { |
| compose fuchsia.unknown.Cloneable; |
| |
| /// Sends a Capability over this sender. |
| strict Send(ProtocolPayload); |
| }; |
| |
| @discoverable |
| open protocol Receiver { |
| compose fuchsia.unknown.Cloneable; |
| |
| /// Receives a Capability. |
| strict Receive(ProtocolPayload); |
| }; |
| |
| /// Contains a protocol open request. |
| type ProtocolPayload = resource struct { |
| channel zx.Handle:CHANNEL; |
| // TODO(https://fxbug.dev/313998675): Decide whether to replace this with a more specific type |
| flags fuchsia.io.OpenFlags; |
| }; |
| |
| /// Entrypoint for instantiation of sandbox types. |
| @discoverable |
| open protocol Factory { |
| /// Creates a connector (pair of [`Sender`] and [`Receiver`]). |
| strict CreateConnector(resource struct { |
| sender server_end:Sender; |
| receiver client_end:Receiver; |
| }); |
| |
| /// Creates a [`Dict`] initialized with `items`. |
| strict CreateDict(resource struct { |
| // TODO(https://fxbug.dev/306043410): Accept a DictIterator |
| items vector<DictItem>:MAX; |
| server_end server_end:Dict; |
| }) -> () error DictError; |
| }; |