// Copyright 2019 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.media.drm;

using fuchsia.media;

table DecryptorParams {
    /// Requires the decryptor [`fuchsia.media/StreamProcessor`] to only output
    /// to secure buffers.
    1: bool require_secure_mode;

    /// Initial format details for the [`fuchsia.media/StreamProcessor`].
    2: fuchsia.media.FormatDetails input_details;
};

/// A protocol for managing content license sessions and providing decryption of
/// media content. There may be zero to many active [`LicenseSession`]s
/// associated with a `ContentDecryptionModule`, each with their own sets of
/// keys.
///
/// From an EME client's perspective, this protocol has a 1:1 relationship with
/// the MediaKeys object.
protocol ContentDecryptionModule {
    /// Indicates that the `ContentDecryptionModule` is provisioned.
    ///
    /// In order to create `LicenseSession`s, a `ContentDecryptionModule` must
    /// be provisioned. A `ContentDecryptionModule` is not considered
    /// provisioned until it meets the requirements for the underlying DRM
    /// system. The DRM system may not require provisioning, may only require
    /// factory provisioning or may require both factory provisioning and
    /// service instance provisioning.
    ///
    /// If the `ContentDecryptionModule` has already has sufficient
    /// provisioning, this event will be sent immediately upon creation. If the
    /// `ContentDecryptionModule` has its provisioning removed, then the server
    /// will close the channel and also close any active `LicenseSession`s or
    /// Decryptors.
    ///
    /// If the DRM system does not require provisioning at all, this
    /// event should still be sent to notify the client that it can create
    /// `LicenseSession`s.
    -> OnProvisioned();

    /// Sets the certificate to be used for encrypting outgoing messages.
    ///
    /// + request `certificate` a buffer containing the certificate to be used.
    /// * error an [`Error`] indicating the reason for failure.
    SetServerCertificate(bytes certificate) -> () error Error;

    /// Creates a new session for the given type.
    ///
    /// The `session_id` will be generated by the [`ContentDecryptionModule`]
    /// and can be used to reload the session after closing. If the
    /// `session_type` is not supported by the underlying DRM system, it will
    /// immediately close the `license_session`.
    ///
    /// + request `session_type` a field containing either
    ///   [`LicenseSessionType.TEMPORARY`],
    ///   [`LicenseSessionType.PERSISTENT_LICENSE`] or
    ///   [`LicenseSessionType.PERSISTENT_USAGE_RECORD`]
    /// + request `license_session` the server endpoint of the
    ///   [`LicenseSession`]
    /// - response `session_id` an identifier that can be used to reload the
    ///   session later (if persistent).
    CreateLicenseSession(LicenseSessionType session_type,
                         request<LicenseSession> license_session)
        -> (SessionId session_id);

    /// Loads an existing session from storage using the given `session_id`.
    ///
    /// If the session is not found, then the `license_session` will be closed.
    ///
    /// + request `session_id` contains an identifier of which session should be
    ///   loaded from storage.
    /// + request `license_session` the server endpoint of the
    ///   [`LicenseSession`].
    LoadLicenseSession(SessionId session_id,
                       request<LicenseSession> license_session);

    /// Creates a Decryptor [`fuchsia.media/StreamProcessor`] to be used to
    /// decrypt content.
    ///
    /// This `decryptor` would have access to the union of keys created by all
    /// the active sessions for this [`ContentDecryptionModule`].
    ///
    /// + request `params` the parameters with which to create the `decryptor`.
    /// + request `decryptor` the server endpoint of the
    ///   `fuchsia.media/StreamProcessor`.
    CreateDecryptor(DecryptorParams params,
                    request<fuchsia.media.StreamProcessor> decryptor);

    /// Queries the status of a hypothetical key associated with an HDCP policy.
    ///
    /// This aids clients in determining which content type to fetch prior to
    /// establishing a [`LicenseSession`]. For example, if the device would
    /// restrict output for HDCP 1.x, then the client can choose to fetch SD
    /// content rather than HD.
    ///
    /// + request `hdcp_version` a field containing the HDCP version to check,
    ///   such as "1.2" or "2.0".
    /// - response `key_status` a field indicating what the status of a
    ///   hypothetical key would be for this device if one could be licensed.
    GetKeyStatusForHdcpVersion(HdcpVersion hdcp_version) -> (KeyStatus key_status);

    /// Queries for the list of supported encryption schemes.
    ///
    /// This returns a list of the supported encryption schemes that the
    /// `ContentDecryptionModule` supports, such as 'cenc' or 'cbcs'. If the
    /// implementation supports passing unencrypted frames through decryption
    /// prior to license arrival, it should also report
    /// `fuchsia.media.UNENCRYPTED` as a supported scheme.
    ///
    /// - response `encryption_schemes` a list of the supported encryption
    ///   schemes.
    GetSupportedEncryptionSchemes() -> (vector<EncryptionScheme>:MAX encryption_schemes);
};
