// 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.io;

/// A sentinel value for use with [`KeySystem.CreateContentDecryptionModule2`]
/// to create a [`ContentDecryptionModule`] without a client data store.
const uint32 NO_DATA_STORE = 0;

protocol KeySystem {
    /// Get various static properties of the `KeySystem` implementation.
    ///
    /// The properties include the capabilities and requirements of the
    /// `KeySystem`, such as whether the implementation is hardware-based or
    /// whether it requires client-provided data stores to operate.
    ///
    /// - response `properties` the properties of the `KeySystem`
    ///   implementation.
    GetProperties() -> (KeySystemProperties properties);

    /// Adds a client data store to the `KeySystem`.
    ///
    /// DRM systems generate data on behalf of clients as part of provisioning
    /// and license management. This data is only usable by the DRM system, but
    /// the client is the owner of the data. The client controls the lifetime of
    /// the data and can select which data set is to be used for a
    /// [`ContentDecryptionModule`].
    ///
    /// + request `data_store_id` a client-assigned identifier for the data
    ///   store. The identifier is scoped to the `KeySystem` channel. It is
    ///   invalid for the client to provide [`NO_DATA_STORE`] or an already
    ///   added `data_store_id` and the server should close the channel.
    /// + request `data_store_params` the parameters to be used for this data
    ///   store.
    AddDataStore(uint32 data_store_id,
                 DataStoreParams data_store_params) -> () error Error;

    /// Destroys the client data store.
    ///
    /// This method permanently removes this data store and all of its contents.
    /// All provisioning and license data will be removed and any active
    /// [`ContentDecryptionModule`] using this data store will be closed.
    ///
    /// + request `data_store_id` the client-assigned identifier for the data
    ///  store to be removed. It is invalid for the client to provide
    ///  [`NO_DATA_STORE`] or a `data_store_id` value that has not previously
    ///  been added or has been previously destroyed.
    DestroyDataStoreAndConfirm(uint32 data_store_id) -> ();

    /// Creates a new [`ContentDecryptionModule`].
    ///
    /// Creates a `ContentDecryptionModule` that will use the associated data
    /// store, if provided. If [`NO_DATA_STORE`] is provided for the
    /// `data_store_id`, then the created `ContentDecryptionModule` will only
    /// support [`LicenseSession`]s of [`LicenseSessionType.TEMPORARY`] type.
    /// If a `data_store_id` is provided, then the created
    /// `ContentDecryptionModule` will persist data to that data store. If the
    /// `KeySystem` requires a data store and `NO_DATA_STORE` was provided or
    /// the `KeySystem` does not support data stores and one was provided, then
    /// the server should close the `cdm`.
    ///
    /// If the `data_store_id` does not exist, the `cdm` will be closed with a
    /// `ZX_ERR_NOT_FOUND` epitaph.
    ///
    /// + request `data_store_id` the data store that should be used by the
    ///   `ContentDecryptionModule`.
    /// + request `cdm` the server endpoint of the `ContentDecryptionModule`.
    CreateContentDecryptionModule2(uint32 data_store_id,
                                   request<ContentDecryptionModule> cdm);
};

resource table DataStoreParams {
    /// Directory into which this data store should write persistent
    /// provisioning and licenses, or their proxy. This field is required.
    1: fuchsia.io.Directory data_directory;

    /// Certificate to use for encrypting provisioning messages. This field is
    /// optional.
    2: bytes provision_server_certificate;

    /// The client endpoint of the [`ProvisioningFetcher`] to be used when this
    /// data store requires provisioning. If the DRM system requires data store
    /// provisioning, then this field is required to be set. Otherwise, it is
    /// optional.
    3: ProvisioningFetcher provisioning_fetcher;
};

// TODO(fxbug.dev/13674): Convert these protocols to services once available.

/// A service hub providing access to the ClearKey key system. This key system
/// is defined by the [`W3C Encrypted Media Extensions`]. It uses plain-text
/// keys to decrypt the source.
///
/// If the client closes the `ClearKey` channel, derived
/// `ContentDecryptionModule`s will remain active.
///
/// [`W3C Encrypted Media Extensions`]:
///   https://www.w3.org/TR/encrypted-media
[Discoverable]
protocol ClearKey {
    compose KeySystem;
};

/// A service hub providing access to the Widevine key system.
///
/// If the client closes the `Widevine` channel, derived
/// `ContentDecryptionModule`s will remain active.
[Discoverable]
protocol Widevine {
    compose KeySystem;
};

/// A service hub providing access to the PlayReady key system.
///
/// If the client closes the `PlayReady` channel, derived
/// `ContentDecryptionModule`s will remain active.
[Discoverable]
protocol PlayReady {
    compose KeySystem;
};
