// 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 NO_DATA_STORE uint32 = 0;

closed 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.
    strict GetProperties() -> (struct {
        properties KeySystemProperties;
    });

    /// 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.
    strict AddDataStore(resource struct {
        data_store_id uint32;
        data_store_params DataStoreParams;
    }) -> () 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.
    strict DestroyDataStoreAndConfirm(struct {
        data_store_id uint32;
    }) -> ();

    /// 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`.
    strict CreateContentDecryptionModule2(resource struct {
        data_store_id uint32;
        cdm server_end:ContentDecryptionModule;
    });
};

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

    /// Certificate to use for encrypting provisioning messages. This field is
    /// optional.
    2: provision_server_certificate vector<uint8>:MAX;

    /// 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: provisioning_fetcher client_end:ProvisioningFetcher;
};

// TODO(https://fxbug.dev/42086383): 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
closed 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
closed 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
closed protocol PlayReady {
    compose KeySystem;
};
