/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package hardware.google.media.c2@1.0;

import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
import android.hardware.media.omx@1.0::IGraphicBufferSource;

import IConfigurable;
import IComponentInterface;
import IComponentListener;

/**
 * Interface for a Codec 2.0 component corresponding to API level 1.0 or
 * below. Components have two states: stopped and running. The running
 * state has three sub-states: executing, tripped and error.
 */
interface IComponent extends IComponentInterface {

    // METHODS AVAILABLE WHEN RUNNING
    // =========================================================================

    /**
     * Queues up work for the component.
     *
     * This method must be supported in running (including tripped) states.
     *
     * This method must return within 1ms
     *
     * It is acceptable for this method to return OK and return an error value
     * using the onWorkDone() callback.
     *
     * @param workBundle WorkBundle object containing Works to queue to the
     * component.
     * @return status Status of the call, which may be
     *   - OK        - Works in \p workBundle were successfully queued.
     *   - BAD_INDEX - Some component(s) in some Work do(es) not exist.
     *   - CANNOT_DO - The components are not tunneled.
     *   - NO_MEMORY - Not enough memory to queue \p workBundle.
     *   - CORRUPTED - Some unknown error prevented queuing the Works.
     *                 (unexpected).
     */
    queue(WorkBundle workBundle) generates (Status status);

    /**
     * Discards and abandons any pending work for the component.
     *
     * This method must be supported in running (including tripped) states.
     *
     * This method must return within 5ms.
     *
     * Work that could be immediately abandoned/discarded must be returned in
     * \p flushedWorks; this can be done in an arbitrary order.
     *
     * Work that could not be abandoned or discarded immediately must be marked
     * to be discarded at the earliest opportunity, and must be returned via
     * the onWorkDone() callback. This must be completed within 500ms.
     *
     * @return status Status of the call, which may be
     *   - OK        - The component has been successfully flushed.
     *   - TIMED_OUT - The flush could not be completed within the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented flushing from
     *                 completion. (unexpected)
     * @return flushedWorkBundle WorkBundle object containing flushed Works.
     */
    flush(
        ) generates (
            Status status,
            WorkBundle flushedWorkBundle
        );

    /**
     * Drains the component, and optionally downstream components. This is a
     * signalling method; as such it does not wait for any work completion.
     *
     * Marks last work item as "drain-till-here", so component is notified not
     * to wait for further work before it processes work already queued. This
     * method can also be used to set the end-of-stream flag after work has been
     * queued. Client can continue to queue further work immediately after this
     * method returns.
     *
     * This method must be supported in running (including tripped) states.
     *
     * This method must return within 1ms.
     *
     * Work that is completed must be returned via the onWorkDone() callback.
     *
     * @param withEos Whether to drain the component with marking end-of-stream.
     * @return status Status of the call, which may be
     *   - OK        - The drain request has been successfully recorded.
     *   - TIMED_OUT - The flush could not be completed within the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented flushing from completion.
     *                 (unexpected)
     */
    drain(bool withEos) generates (Status status);

    /**
     * Starts using a surface for output.
     *
     * @param blockPoolId The id of the BlockPool to be associated with the
     * output surface.
     * @param surface A surface to use for codec output.
     * @return status Status of the call, which may be
     *   - OK        - The operation completed successfully.
     *   - CANNOT_DO - The component does not support an output surface.
     *   - REFUSED   - The output surface cannot be accessed.
     *   - TIMED_OUT - The component could not be connected within the time
     *                 limit. (unexpected)
     *   - CORRUPTED - Some unknown error prevented connecting the component.
     *                 (unexpected)
     */
    setOutputSurface(
            uint64_t blockPoolId,
            IGraphicBufferProducer surface
        ) generates (
            Status status
        );

    /**
     * Starts using a persistent OMX input surface for a component.
     *
     * The component must be in running state.
     *
     * @param producer Producer component of an OMX persistent input surface.
     * @param source Source component of an OMX persistent input surface.
     * @return status Status of the call, which may be
     *   - OK        - The operation completed successfully.
     *   - CANNOT_DO - The component does not support an input surface.
     *   - BAD_STATE - Component is not in running state.
     *   - DUPLICATE - The component is already connected to an input surface.
     *   - REFUSED   - The input surface is already in use.
     *   - NO_MEMORY - Not enough memory to start the component.
     *   - TIMED_OUT - The component could not be connected within the time
     *                 limit. (unexpected)
     *   - CORRUPTED - Some unknown error prevented connecting the component.
     *                 (unexpected)
     */
    connectToOmxInputSurface(
            IGraphicBufferProducer producer,
            IGraphicBufferSource source
        ) generates (Status status);

    /**
     * Stops using an input surface.
     *
     * This call is used for both Codec 2.0 and OMX input surfaces.
     *
     * The component must be in running state.
     *
     * @return status Status of the call, which may be
     *   - OK        - The operation completed successfully.
     *   - CANNOT_DO - The component does not support an input surface.
     *   - BAD_STATE - Component is not in running state.
     *   - NOT_FOUND - The component is not connected to an input surface.
     *   - TIMED_OUT - The component could not be connected within the time
     *                 limit. (unexpected)
     *   - CORRUPTED - Some unknown error prevented connecting the component.
     *                 (unexpected)
     */
    disconnectFromInputSurface() generates (Status Status);

    /**
     * Creates a local block pool backed by the given allocator and returns its
     * identifier.
     *
     * This call must return within 100 msec.
     *
     * @param allocatorId The Codec 2.0 allocator ID
     * @return status Status of the call, which may be
     *   - OK        - The operation completed successfully.
     *   - NO_MEMORY - Not enough memory to create the pool.
     *   - BAD_VALUE - Invalid allocator.
     *   - TIMED_OUT - The pool could not be created within the time
     *                 limit. (unexpected)
     *   - CORRUPTED - Some unknown error prevented creating the pool.
     *                 (unexpected)
     * @return blockPoolId The Codec 2.0 blockpool ID for the created pool.
     * @return configurable Configuration interface for the created pool.
     */
    createBlockPool(uint32_t allocatorId) generates (
        Status status,
        uint64_t blockPoolId,
        IConfigurable configurable
    );

    /**
     * Destroys a local block pool previously created by createBlockPool().
     *
     * This call must return within 100 msec.
     *
     * @param blockPoolId The block pool id previously returned by
     *      createBlockPool().
     * @return status Status of the call, which may be
     *   - OK        - The operation completed successfully.
     *   - NOT_FOUND - The supplied blockPoolId is not valid.
     *   - TIMED_OUT - The pool could not be destroyedwithin the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented destruction of the pool.
     *                 (unexpected)
     */
    destroyBlockPool(uint64_t blockPoolId) generates (Status status);

    // STATE CHANGE METHODS
    // =========================================================================

    /**
     * Starts the component.
     *
     * This method must be supported in stopped state as well as tripped state.
     *
     * If the return value is OK, the component must be in the running state.
     * If the return value is BAD_STATE or DUPLICATE, no state change is
     * expected as a response to this call.
     * Otherwise, the component must be in the stopped state.
     *
     * If a component is in the tripped state and start() is called while the
     * component configuration still results in a trip, start must succeed and
     * a new onTripped callback must be used to communicate the configuration
     * conflict that results in the new trip.
     *
     * This method must return within 500ms.
     *
     * @return status Status of the call, which may be
     *   - OK        - The component has started successfully.
     *   - BAD_STATE - Component is not in stopped or tripped state.
     *   - DUPLICATE - When called during another start call from another
     *                 thread.
     *   - NO_MEMORY - Not enough memory to start the component.
     *   - TIMED_OUT - The component could not be started within the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented starting the component.
     *                 (unexpected)
     */
    start() generates (Status status);

    /**
     * Stops the component.
     *
     * This method must be supported in running (including tripped) state.
     *
     * This method must return withing 500ms.
     *
     * Upon this call, all pending work must be abandoned.
     * If the return value is BAD_STATE or DUPLICATE, no state change is
     * expected as a response to this call.
     * For all other return values, the component must be in the stopped state.
     *
     * This does not alter any settings and tunings that may have resulted in a
     * tripped state.
     *
     * @return status Status of the call, which may be
     *   - OK        - The component has stopped successfully.
     *   - BAD_STATE - Component is not in running state.
     *   - DUPLICATE - When called during another stop call from another thread.
     *   - TIMED_OUT - The component could not be stopped within the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented starting the component.
     *                 (unexpected)
     */
    stop() generates (Status status);

    /**
     * Resets the component.
     *
     * This method must be supported in all (including tripped) states other
     * than released.
     *
     * This method must be supported during any other blocking call.
     *
     * This method must return withing 500ms.
     *
     * After this call returns all work must have been abandoned, all references
     * must have been released.
     *
     * If the return value is BAD_STATE or DUPLICATE, no state change is
     * expected as a response to this call.
     * For all other return values, the component shall be in the stopped state.
     *
     * This brings settings back to their default - "guaranteeing" no tripped
     * state.
     *
     * @return status Status of the call, which may be
     *   - OK        - The component has been reset.
     *   - BAD_STATE - Component is in released state.
     *   - DUPLICATE - When called during another reset call from another
     *                 thread.
     *   - TIMED_OUT - The component could not be reset within the time limit.
     *                 (unexpected)
     *   - CORRUPTED - Some unknown error prevented resetting the component.
     *                 (unexpected)
     */
    reset() generates (Status status);

    /**
     * Releases the component.
     *
     * This method must be supported in stopped state.
     *
     * This method must return withing 500ms. Upon return all references must
     * be abandoned.
     *
     * @return status Status of the call, which may be
     *   - OK        - The component has been released.
     *   - BAD_STATE - The component is running.
     *   - DUPLICATE - The component is already released.
     *   - TIMED_OUT - The component could not be released within the time
     *                 limit. (unexpected)
     *   - CORRUPTED - Some unknown error prevented releasing the component.
     *                 (unexpected)
     */
    release() generates (Status status);

};