// 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, ForDeprecatedCBindings]
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();

    /// Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name
    /// only affects VMOs allocated after it's set - this call does not rename existing VMOs. If
    /// multiple clients set different names then the larger priority value will win.
    [Transitional]
    SetName(uint32 priority, string:64 name);

    /// Set information about the current client that can be used by sysmem to
    /// help debug leaking memory and hangs waiting for constraints. |name| can
    /// be an arbitrary string, but the current process name (see
    /// fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary
    /// id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a
    /// good default.
    SetDebugClientInfo(string:64 name, uint64 id);

    /// Sysmem logs a warning if not all clients have set constraints 5 seconds
    /// after creating a collection. Clients can call this method to change
    /// when the log is printed. If multiple client set the deadline, it's
    /// unspecified which deadline will take effect.
    SetDebugTimeoutLogDeadline(zx.time deadline);
};

/// 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, ForDeprecatedCBindings]
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();

    /// Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name
    /// only affects VMOs allocated after it's set - this call does not rename existing VMOs. If
    /// multiple clients set different names then the larger priority value will win.
    SetName(uint32 priority, string:64 name);

    /// See BufferCollectionToken.SetClientDebugInfo.
    SetDebugClientInfo(string:64 name, uint64 id);

    /// Optionally sent before SetConstraints() to set constraints related to
    /// clear (not encrypted, not in protected/secure memory) aux buffers.  This
    /// is only valid when sent before SetConstraints().  Invalid settings may
    /// not result in channel closure until SetConstraints() is received by
    /// sysmem.
    SetConstraintsAuxBuffers(
        BufferCollectionConstraintsAuxBuffers constraints);

    /// Allows getting any aux buffers allocated after using
    /// SetConstraintsAuxBuffers().
    ///
    /// Sending this message is not permitted until at least one of the
    /// following has occurred:
    ///   * WaitForBuffersAllocated() completing
    ///   * OnBuffersAllocated() being received
    ///
    /// On failure, status will be a failing status and
    /// buffer_collection_info_aux_buffers won't be filled out, and won't have
    /// any handles.
    ///
    /// On success, status will be ZX_OK, and buffer_count will be the same as
    /// the main buffer_count from WaitForBuffersAllocated() or
    /// OnBuffersAllocated().
    ///
    /// If a participant specified "allow_clear_aux_buffers_for_secure" true but
    /// "need_clear_aux_buffers_for_secure" false (or not set), the participant
    /// can determine if aux buffers were allocated by looking at buffer[0].vmo.
    /// If buffer 0 has no vmo, aux VMOs were not allocated.  The resulting
    /// status will still be ZX_OK in this case, and buffer_count will still be
    /// filled out to match the main buffer_count.
    ///
    /// It's legal for a participant that set
    /// "allow_clear_aux_buffers_for_secure" false to call GetAuxBuffers(), in
    /// which case buffer[0].vmo will not be set.
    GetAuxBuffers()
        -> (zx.status status,
            BufferCollectionInfo_2 buffer_collection_info_aux_buffers);
};

/// 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, ForDeprecatedCBindings]
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);
};
