// Copyright 2018 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.sysmem;

using zx;

/// A BufferCollectionToken is not a BufferCollection, but rather a way to
/// identify a potential shared BufferCollection prior to the BufferCollection
/// being allocated.
///
/// We use a channel for the BufferCollectionToken instead of a single eventpair
/// (pair) because this way we can detect error conditions like a participant
/// dying mid-create.
[Discoverable, Layout = "Simple"]
protocol BufferCollectionToken {
    /// The initiator or a participant can send Duplicate() as part of creating
    /// another participant-side handle to the same logical
    /// BufferCollectionToken.
    ///
    /// This method is used to hand the logical token to all participants so all
    /// participants can provide constraints to sysmem for the overall
    /// BufferCollection to achieve the goal of allocating buffers compatible
    /// with all participants.
    ///
    /// The Duplicate() message is intentionally available only on
    /// BufferCollectionToken not BufferCollection.
    ///
    /// The token is separate from BufferCollection so that participants contact
    /// sysmem directly, so that participants are only trusting their environment
    /// for who sysmem is (fake token mitigation), not an initiator.  Only after
    /// successful BindSharedCollection does a participant know that the token
    /// was a real sysmem token.  In contrast, if we had Duplicate() directly on
    /// BufferCollection, an initiator could attempt to serve the
    /// BufferCollection channel itself, which would allow for some problematic
    /// possibilities.
    ///
    /// All the BufferCollectionToken channels of a logical token must be turned
    /// in via BindSharedCollection() for a BufferCollection to be successfully
    /// created.  Else the BufferCollection channel will close.
    ///
    /// When a client calls BindSharedCollection() to turn in a
    /// BufferCollectionToken, the server will process all Duplicate() messages
    /// before closing down the BufferCollectionToken.  This allows the client
    /// to Duplicate() and immediately turn in the BufferCollectionToken using
    /// BindSharedCollection, then later transfer the client end of token_request
    /// to another participant - the server will notice the existence of the
    /// token_request before considering this BufferCollectionToken fully closed.
    ///
    /// `rights_attenuation_mask` rights bits that are zero in this mask will be
    /// absent in the buffer VMO rights obtainable via the client end of
    /// token_request.  This allows an initiator or intermediary participant
    /// to attenuate the rights available to a participant.  This may not be the
    /// only mechanism that attenuates rights on the VMO handles obtainable via
    /// the client end of token_request.  This does not allow a participant
    /// to gain rights that the participant doesn't already have.  The value
    /// ZX_RIGHT_SAME_RIGHTS can be used to specify that no attenuation should
    /// be applied.
    ///
    /// `token_request` is the server end of a BufferCollectionToken channel.
    /// The client end of this channel acts as another handle to the same logical
    /// BufferCollectionToken.  Typically the sender of Duplicate() will transfer
    /// the client end corresponding to collection_request to a/another
    /// participant running in a separate process, but it's also fine for the
    /// additional logical participant to be in the same process.
    ///
    /// After sending one or more Duplicate() messages, and before sending the
    /// created tokens to other participants (or to other Allocator channels),
    /// the client should send a Sync() and wait for its response.  The Sync()
    /// call can be made on the token, or on the BufferCollection obtained by
    /// passing this token to BindSharedCollection().  Either will ensure that
    /// the server knows about the tokens created via Duplicate() before the
    /// other participant sends the token to the server via separate Allocator
    /// channel.  If a client is using FIDL C generated code and doesn't want to
    /// block waiting for a response message, the other option is to notice
    /// arrival of the BufferCollectionEvents::OnBufferCollectionCreated() event
    /// after turning in this token for a BufferCollection.
    //
    // TODO(dustingreen): Consider other mechanisms to ensure the token created
    // here is recognized by the server.
    Duplicate(uint32 rights_attenuation_mask,
              request<BufferCollectionToken> token_request);

    /// Ensure that previous Duplicate() messages have been received server side,
    /// so that it's safe to send the client end of token_request to another
    /// participant knowing the server will recognize the token when it's sent
    /// into BindSharedCollection by the other participant.
    ///
    /// Other options include waiting for each Duplicate() to complete
    /// individually (using separate call to BufferCollectionToken.Sync() after
    /// each), or calling Sync() on BufferCollection after this token has
    /// been turned in via BindSharedCollection(), or noticing arrival of
    /// BufferCollectionEvents::OnDuplicatedTokensKnownByServer().
    ///
    /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
    /// valid sysmem token risks the Sync() hanging forever.  See
    /// ValidateBufferCollectionToken() for one way to mitigate the possiblity
    /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
    ///
    /// Another way to mitigate is to avoid calling Sync() on the token, and
    /// instead later deal with potential failure of BufferCollection.Sync() if
    /// the original token was invalid.  This option can be preferable from a
    /// performance point of view, but requires client code to delay sending
    /// tokens duplicated from this token until after client code has converted
    /// this token to a BufferCollection and received successful response from
    /// BufferCollection.Sync() (or received OnDuplicatedTokensKnownByServer()).
    ///
    /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
    /// When BufferCollection.Sync() isn't feasible, the caller must already
    /// know that this token is/was valid, or BufferCollectionToken.Sync() may
    /// hang forever.  See ValidateBufferCollectionToken() to check token
    /// validity first if the token isn't already known to be (is/was) valid.
    Sync() -> ();

    /// Normally a participant will convert the token into a BufferCollection
    /// view, but a particpant is also free to Close() the token (and then close
    /// the channel immediately or shortly later in response to server closing
    /// its end), which avoids causing LogicalBufferCollection failure.
    /// Normally an unexpected token channel close will cause
    /// LogicalBufferCollection failure.
    Close();
};

/// BufferCollection is a connection directly from a participant to sysmem re.
/// a logical BufferCollection; typically the logical BufferCollection is shared
/// with other participants.  In other words, an instance of the BufferCollection
/// interface is a view of a "LogicalBufferCollection".
///
/// This connection exists to facilitate async indication of when the logical
/// BufferCollection has been populated with buffers.
///
/// Also, the channel's closure by the server is an indication to the client
/// that the client should close all VMO handles that were obtained from the
/// BufferCollection ASAP.
///
/// Also, this interface may in future allow specifying constraints in other
/// ways, and may allow for back-and-forth negotiation of constraints to some
/// degree.
///
/// This interface may in future allow for more than 64 VMO handles per
/// BufferCollection, but currently the limit is 64.
///
/// This interface may in future allow for allocating/deallocating single
/// buffers.
///
/// Some initiators may wait a short duration until all old logical
/// BufferCollection VMO handles have closed (or until the short duration times
/// out) before allocating a new BufferCollection, to help control physical
/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
/// the old and new collections. Collections can be large enough that it's worth
/// avoiding allocation overlap (in time).
[Discoverable, Layout = "Simple"]
protocol BufferCollection {
    /// At least for now, the only way to get events from a BufferCollection is
    /// to set a reverse BufferCollectionEvents channel.  This can be sent up to
    /// once at any point during BufferCollection channel lifetime.  All events
    /// are one-shot events, and will be sent immediately via `events` if the
    /// one-shot event's condition has already become true (once true will stay
    /// true; only goes from false to true once).
    ///
    /// `events` is the client end of a BufferCollectionEvents which will be sent
    /// one-way messages indicating events relevant to this BufferCollection
    /// channel (some may be specific to this BufferCollection channel and some
    /// may be relevant to the overall logical BufferCollection).
    SetEventSink(BufferCollectionEvents events);

    /// See comments on BufferCollectionToken::Sync().
    Sync() -> ();

    /// Provide BufferCollectionConstraints to the logical BufferCollection.
    ///
    /// Participants with read but not write can only call SetConstraints() once.
    ///
    /// Participants with write can call SetConstraints() more than once.  The
    /// initial buffer allocation will use the constraints in the first call to
    /// SetConstraints().  Among other things, this allows a decoder to attempt
    /// to allocate a new buffer that's larger to hold an output frame that's
    /// larger.
    ///
    /// Sometimes the initiator is a participant only in the sense of wanting to
    /// keep an eye on success/failure to populate with buffers, and zx.status on
    /// failure.  In that case, `has_constraints` can be false, and `constraints`
    /// will be ignored.
    ///
    /// VMO handles will not be provided to the client that sends null
    /// constraints - that can be intentional for an initiator that doesn't need
    /// VMO handles.  Not having VMO handles doesn't prevent the initator from
    /// adjusting which portion of a buffer is considered valid and similar, but
    /// the initiator can't hold a VMO handle open to prevent the logical
    /// BufferCollection from cleaning up if the logical BufferCollection needs
    /// to go away regardless of the initiator's degree of involvement for
    /// whatever reason.
    ///
    /// For population of buffers to be attempted, all holders of a
    /// BufferCollection client channel need to call SetConstraints() before
    /// sysmem will attempt to allocate buffers.
    ///
    /// `has_constraints` if false, the constraints are effectively null, and
    /// `constraints` are ignored.  The sender of null constraints won't get any
    /// VMO handles in BufferCollectionInfo, but can still find out how many
    /// buffers were allocated and can still refer to buffers by their
    /// buffer_index.
    ///
    /// `constraints` are constraints on the buffer collection.
    SetConstraints(bool has_constraints,
                   BufferCollectionConstraints constraints);

    /// This request completes when buffers have been allocated, responds with
    /// some failure detail if allocation has been attempted but failed.
    ///
    /// The following must occur before buffers will be allocated:
    ///   * All BufferCollectionToken(s) of the logical BufferCollectionToken
    ///     must be turned in via BindSharedCollection().
    ///   * All BufferCollection(s) of the logical BufferCollection must have had
    ///     SetConstraints() sent to them.
    ///
    /// A caller using C generated FIDL code who wishes not to block a thread in
    /// a zx_channel_call() for a potentially fairly long duration on this
    /// message/response can use SetEventSink() and
    /// BufferCollectionEvents.OnBuffersPopulated() instead.
    ///
    /// This method is still legal to call despite use of OnBuffersPopulated(),
    /// but in that case the additional BufferCollectionInfo returned here will
    /// include handles that are redundant with other handles in the
    /// BufferCollectionInfo delivered via OnBuffersPopulated() (separate handle
    /// but same underlying VMO objects), so most clients that bother calling
    /// SetEventSink() will prefer to receive BufferCollectionInfo via
    /// OnBuffersPopulated().  This method is mostly here for clients that don't
    /// call SetEventSink().
    ///
    /// Returns `ZX_OK` if successful.
    /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
    /// fulfilled due to resource exhaustion.
    /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
    /// obtain the buffers it requested.
    /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
    /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
    /// satisfied, perhaps due to hardware limitations.
    ///
    /// `buffer_collection_info` has the VMO handles and other related info.
    WaitForBuffersAllocated()
        -> (zx.status status, BufferCollectionInfo_2 buffer_collection_info);

    /// This returns the same result code as WaitForBuffersAllocated if the
    /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
    /// if WaitForBuffersAllocated would block.
    CheckBuffersAllocated() -> (zx.status status);

    /// The CloseBuffer() doesn't immediately force all VMO handles to that
    /// buffer to close, but it does close any handle held by sysmem, and does
    /// notify all participants of the desire to close the buffer at which point
    /// each participant that's listening may close their handle to the buffer.
    ///
    /// Only a particpant with write can do this.  Coordination among multiple
    /// participants with write is outside of the scope of this interface.
    ///
    /// `buffer_index` indicates which buffer to close.  If the buffer is already
    /// closed this has no effect (idempotent).
    CloseSingleBuffer(uint64 buffer_index);

    /// This allocates a new buffer that is consistent with the most recent call
    /// to SetConstraints(), if possible.  If not possible, this indicates the
    /// failure via OnNewBufferAllocated().
    ///
    /// Only a participant with write can do this.  Coordination among multiple
    /// participants with write is outside the scope of this interface.
    ///
    /// The participant is (intentionally) never informed of other participant's
    /// constraints.
    AllocateSingleBuffer(uint64 buffer_index);

    /// Completes when AllocateBuffer is done.  Callers who wish to avoid
    /// blocking a thread while waiting can use OnAllocateSingleBufferDone()
    /// instead.
    WaitForSingleBufferAllocated(uint64 buffer_index)
        -> (zx.status status, SingleBufferInfo buffer_info);

    /// A participant can use this message to have sysmem verify that this
    /// buffer_index exists.  This message is intentionally ignored by the
    /// server if the buffer_index _does_ exist.  In that case, the client will
    /// see OnAllocateSingleBufferDone() soon with status == `ZX_OK` (if the
    /// client hasn't already seen that message).  If on the other hand the
    /// buffer_index does not exist, this message causes the server to send
    /// OnAllocateSingleBufferDone() with status == `ZX_ERR_NOT_FOUND`.  A
    /// particpant will typically use this when the participant receives a new
    /// buffer_index that the participant doesn't yet know about, to ensure that
    /// the participant won't be waiting forever for the
    /// OnAllocateSingleBufferDone() message regarding this buffer_index.
    CheckSingleBufferAllocated(uint64 buffer_index);

    /// The server handles unexpected failure of a BufferCollection by failing
    /// the whole LogicalBufferCollection.  Partly this is to expedite closing
    /// VMO handles.  If a participant would like to cleanly close a
    /// BufferCollection view without causing LogicalBufferCollection failure,
    /// the participant can send Close() before closing the client end of the
    /// BufferCollection channel.  If this is the last BufferCollection view, the
    /// LogicalBufferCollection will still go away.
    Close();
};

/// This interface intentionally doesn't include any event for
/// OnOldBufferClosed(), because such an event could arrive at a participant too
/// soon to be useful.  Instead, such an indication should be made in-band within
/// FIDL interfaces that deliver packets to downstream participants.
[Discoverable, Layout = "Simple"]
protocol BufferCollectionEvents {
    /// See comments on BufferCollectionToken::Sync().
    ///
    /// This message only indicates that the server has reached the point where
    /// it knows about previously created tokens Duplicate()ed from the token
    /// used to create this BufferCollection.
    OnDuplicatedTokensKnownByServer();

    /// This event inidicates that buffer allocation is over, whether succesful
    /// or failed.
    ///
    /// This event will eventually be sent by the server (unless the
    /// BufferCollection channel closes first).
    ///
    /// `status`:
    /// `ZX_OK` if successful.
    /// `ZX_ERR_NO_MEMORY` if the request is valid but cannot be fulfilled due to
    /// resource exhaustion.
    /// `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to obtain the
    /// buffers it requested.
    /// `ZX_ERR_INVALID_ARGS` if the request is malformed.
    /// `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be satisfied,
    /// perhaps due to hardware limitations.
    ///
    /// `buffer_collection_info` The buffer information, including VMO handles.
    /// If `status` is not `ZX_OK`, `buffer_collection_info` is default
    /// initialized and contains no meaningful information.
    OnBuffersAllocated(zx.status status,
                       BufferCollectionInfo_2 buffer_collection_info);

    /// A participant can learn when a new buffer is allocated via this event.
    /// The only participant that will see a failing status is the participant
    /// that attempted the single buffer allocation.  Other participants will
    /// only see successful single buffer allocations.
    ///
    /// `status`:
    ///
    /// `ZX_OK` if successful.  This can be seen by any participant (whether
    /// sender of AllocateSingleBuffer() or not.)
    ///
    /// `ZX_ERR_NOT_FOUND` if the buffer_index sent via
    /// CheckSingleBufferAllocated() isn't known to the server.  This can be seen
    /// by any participant (whether sender of AllocateSingleBuffer() or not.)
    ///
    /// These error codes are only ever seen by the sender of
    /// AllocateSingleBuffer():
    ///
    /// `ZX_ERR_NO_MEMORY` if the request is valid but cannot be fulfilled due to
    /// resource exhaustion.
    /// `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to obtain the
    /// buffers it requested.
    /// `ZX_ERR_INVALID_ARGS` if the request is malformed.
    /// `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be satisfied,
    /// perhaps due to hardware limitations.
    OnAllocateSingleBufferDone(zx.status status,
                               SingleBufferInfo buffer_info);
};
