blob: 63a3f87be6b83005404e98080ea15410a0ab797a [file] [log] [blame]
// 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 [DictionaryIterator].
const MAX_DICTIONARY_ITEMS_CHUNK uint32 = 128;
@available(added=HEAD)
type HandleCapability = resource struct {
token zx.Handle:EVENTPAIR;
};
/// The `Handle` protocol allows a client to get the contained handle.
@available(added=HEAD)
open protocol Handle {
/// Take the handle or error if the handle was already taken.
flexible GetHandle() -> (resource struct {
handle zx.Handle;
}) error @generated_name("HandleCapabilityError") strict enum {
UNAVAILABLE = 1;
};
};
@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 HandleCapability;
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;
/// Returns all items in this dictionary, sorted by key in natural order.
///
/// This operation creates shallow clones of values.
// TODO(b/314361448): Remove once callers use Dictionary.Enumerate instead
@available(added=HEAD)
flexible Read() -> (resource struct {
items vector<DictionaryItem>:MAX;
});
/// 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 entries in this dictionary.
///
/// Creates a clone of each item during enumeration.
@available(added=HEAD)
flexible Enumerate(resource struct {
contents server_end:DictionaryIterator;
});
/// 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 {
contents server_end:<DictionaryIterator, optional>;
});
};
@available(added=HEAD)
open protocol DictionaryIterator {
flexible GetNext() -> (resource struct {
items vector<DictionaryItem>:MAX_DICTIONARY_ITEMS_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;
};
/// 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.
flexible OpenConnector(resource struct {
capability Connector;
server_end zx.Handle:CHANNEL;
});
/// Operate on the provided handle capability.
///
/// Consumes a token referencing a bedrock object and serves the
/// corresponding FIDL representation on `server_end`. The peer of the
/// `server_end` is another reference to the bedrock object. Dropping the
/// control channel decreases one reference on the object.
flexible OpenHandle(resource struct {
capability HandleCapability;
server_end server_end:Handle;
});
/// Creates a `Connector` from a client served `Receiver`.
flexible CreateConnector(resource struct {
receiver client_end:Receiver;
}) -> (resource struct {
capability Connector;
});
/// Creates a `Handle` from the provided `handle`.
flexible CreateHandle(resource struct {
handle zx.Handle;
}) -> (resource struct {
capability HandleCapability;
});
/// Creates a new empty [`Dictionary`].
flexible CreateDictionary() -> (resource struct {
dictionary client_end:Dictionary;
});
};