/*
 * Copyright (C) 2013 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.
 */

#ifndef ANDROID_SERVERS_CAMERA3_STREAM_H
#define ANDROID_SERVERS_CAMERA3_STREAM_H

#include <gui/Surface.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/List.h>

#include "hardware/camera3.h"

#include "Camera3StreamBufferListener.h"
#include "Camera3StreamInterface.h"

namespace android {

namespace camera3 {

/**
 * A class for managing a single stream of input or output data from the camera
 * device.
 *
 * The stream has an internal state machine to track whether it's
 * connected/configured/etc.
 *
 * States:
 *
 *  STATE_ERROR: A serious error has occurred, stream is unusable. Outstanding
 *    buffers may still be returned.
 *
 *  STATE_CONSTRUCTED: The stream is ready for configuration, but buffers cannot
 *    be gotten yet. Not connected to any endpoint, no buffers are registered
 *    with the HAL.
 *
 *  STATE_IN_CONFIG: Configuration has started, but not yet concluded. During this
 *    time, the usage, max_buffers, and priv fields of camera3_stream returned by
 *    startConfiguration() may be modified.
 *
 *  STATE_IN_RE_CONFIG: Configuration has started, and the stream has been
 *    configured before. Need to track separately from IN_CONFIG to avoid
 *    re-registering buffers with HAL.
 *
 *  STATE_CONFIGURED: Stream is configured, and has registered buffers with the
 *    HAL (if necessary). The stream's getBuffer/returnBuffer work. The priv
 *    pointer may still be modified.
 *
 *  STATE_PREPARING: The stream's buffers are being pre-allocated for use.  On
 *    older HALs, this is done as part of configuration, but in newer HALs
 *    buffers may be allocated at time of first use. But some use cases require
 *    buffer allocation upfront, to minmize disruption due to lengthy allocation
 *    duration.  In this state, only prepareNextBuffer() and cancelPrepare()
 *    may be called.
 *
 * Transition table:
 *
 *    <none>               => STATE_CONSTRUCTED:
 *        When constructed with valid arguments
 *    <none>               => STATE_ERROR:
 *        When constructed with invalid arguments
 *    STATE_CONSTRUCTED    => STATE_IN_CONFIG:
 *        When startConfiguration() is called
 *    STATE_IN_CONFIG      => STATE_CONFIGURED:
 *        When finishConfiguration() is called
 *    STATE_IN_CONFIG      => STATE_ERROR:
 *        When finishConfiguration() fails to allocate or register buffers.
 *    STATE_CONFIGURED     => STATE_IN_RE_CONFIG:  *
 *        When startConfiguration() is called again, after making sure stream is
 *        idle with waitUntilIdle().
 *    STATE_IN_RE_CONFIG   => STATE_CONFIGURED:
 *        When finishConfiguration() is called.
 *    STATE_IN_RE_CONFIG   => STATE_ERROR:
 *        When finishConfiguration() fails to allocate or register buffers.
 *    STATE_CONFIGURED     => STATE_CONSTRUCTED:
 *        When disconnect() is called after making sure stream is idle with
 *        waitUntilIdle().
 *    STATE_CONFIGURED     => STATE_PREPARING:
 *        When startPrepare is called before the stream has a buffer
 *        queued back into it for the first time.
 *    STATE_PREPARING      => STATE_CONFIGURED:
 *        When sufficient prepareNextBuffer calls have been made to allocate
 *        all stream buffers, or cancelPrepare is called.
 *    STATE_CONFIGURED     => STATE_ABANDONED:
 *        When the buffer queue of the stream is abandoned.
 *
 * Status Tracking:
 *    Each stream is tracked by StatusTracker as a separate component,
 *    depending on the handed out buffer count. The state must be STATE_CONFIGURED
 *    in order for the component to be marked.
 *
 *    It's marked in one of two ways:
 *
 *    - ACTIVE: One or more buffers have been handed out (with #getBuffer).
 *    - IDLE: All buffers have been returned (with #returnBuffer), and their
 *          respective release_fence(s) have been signaled.
 *
 *    A typical use case is output streams. When the HAL has any buffers
 *    dequeued, the stream is marked ACTIVE. When the HAL returns all buffers
 *    (e.g. if no capture requests are active), the stream is marked IDLE.
 *    In this use case, the app consumer does not affect the component status.
 *
 */
class Camera3Stream :
        protected camera3_stream,
        public virtual Camera3StreamInterface,
        public virtual RefBase {
  public:

    virtual ~Camera3Stream();

    static Camera3Stream*       cast(camera3_stream *stream);
    static const Camera3Stream* cast(const camera3_stream *stream);

    /**
     * Get the stream's ID
     */
    int              getId() const;

    /**
     * Get the output stream set id.
     */
    int              getStreamSetId() const;

    /**
     * Get the stream's dimensions and format
     */
    uint32_t          getWidth() const;
    uint32_t          getHeight() const;
    int               getFormat() const;
    android_dataspace getDataSpace() const;

    camera3_stream*   asHalStream() override {
        return this;
    }

    /**
     * Start the stream configuration process. Returns a handle to the stream's
     * information to be passed into the HAL device's configure_streams call.
     *
     * Until finishConfiguration() is called, no other methods on the stream may be
     * called. The usage and max_buffers fields of camera3_stream may be modified
     * between start/finishConfiguration, but may not be changed after that.
     * The priv field of camera3_stream may be modified at any time after
     * startConfiguration.
     *
     * Returns NULL in case of error starting configuration.
     */
    camera3_stream*  startConfiguration();

    /**
     * Check if the stream is mid-configuration (start has been called, but not
     * finish).  Used for lazy completion of configuration.
     */
    bool             isConfiguring() const;

    /**
     * Completes the stream configuration process. The stream information
     * structure returned by startConfiguration() may no longer be modified
     * after this call, but can still be read until the destruction of the
     * stream.
     *
     * Returns:
     *   OK on a successful configuration
     *   NO_INIT in case of a serious error from the HAL device
     *   NO_MEMORY in case of an error registering buffers
     *   INVALID_OPERATION in case connecting to the consumer failed or consumer
     *       doesn't exist yet.
     */
    status_t         finishConfiguration();

    /**
     * Cancels the stream configuration process. This returns the stream to the
     * initial state, allowing it to be configured again later.
     * This is done if the HAL rejects the proposed combined stream configuration
     */
    status_t         cancelConfiguration();

    /**
     * Determine whether the stream has already become in-use (has received
     * a valid filled buffer), which determines if a stream can still have
     * prepareNextBuffer called on it.
     */
    bool             isUnpreparable();

    /**
     * Start stream preparation. May only be called in the CONFIGURED state,
     * when no valid buffers have yet been returned to this stream. Prepares
     * up to maxCount buffers, or the maximum number of buffers needed by the
     * pipeline if maxCount is ALLOCATE_PIPELINE_MAX.
     *
     * If no prepartion is necessary, returns OK and does not transition to
     * PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions
     * to PREPARING.
     *
     * This call performs no allocation, so is quick to call.
     *
     * Returns:
     *    OK if no more buffers need to be preallocated
     *    NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish
     *        buffer pre-allocation, and transitions to the PREPARING state.
     *    NO_INIT in case of a serious error from the HAL device
     *    INVALID_OPERATION if called when not in CONFIGURED state, or a
     *        valid buffer has already been returned to this stream.
     */
    status_t         startPrepare(int maxCount);

    /**
     * Check if the stream is mid-preparing.
     */
    bool             isPreparing() const;

    /**
     * Continue stream buffer preparation by allocating the next
     * buffer for this stream.  May only be called in the PREPARED state.
     *
     * Returns OK and transitions to the CONFIGURED state if all buffers
     * are allocated after the call concludes. Otherwise returns NOT_ENOUGH_DATA.
     *
     * This call allocates one buffer, which may take several milliseconds for
     * large buffers.
     *
     * Returns:
     *    OK if no more buffers need to be preallocated, and transitions
     *        to the CONFIGURED state.
     *    NOT_ENOUGH_DATA if more calls to prepareNextBuffer are needed to finish
     *        buffer pre-allocation.
     *    NO_INIT in case of a serious error from the HAL device
     *    INVALID_OPERATION if called when not in CONFIGURED state, or a
     *        valid buffer has already been returned to this stream.
     */
    status_t         prepareNextBuffer();

    /**
     * Cancel stream preparation early. In case allocation needs to be
     * stopped, this method transitions the stream back to the CONFIGURED state.
     * Buffers that have been allocated with prepareNextBuffer remain that way,
     * but a later use of prepareNextBuffer will require just as many
     * calls as if the earlier prepare attempt had not existed.
     *
     * Returns:
     *    OK if cancellation succeeded, and transitions to the CONFIGURED state
     *    INVALID_OPERATION if not in the PREPARING state
     *    NO_INIT in case of a serious error from the HAL device
     */
    status_t        cancelPrepare();

    /**
     * Tear down memory for this stream. This frees all unused gralloc buffers
     * allocated for this stream, but leaves it ready for operation afterward.
     *
     * May only be called in the CONFIGURED state, and keeps the stream in
     * the CONFIGURED state.
     *
     * Returns:
     *    OK if teardown succeeded.
     *    INVALID_OPERATION if not in the CONFIGURED state
     *    NO_INIT in case of a serious error from the HAL device
     */
    status_t       tearDown();

    /**
     * Fill in the camera3_stream_buffer with the next valid buffer for this
     * stream, to hand over to the HAL.
     *
     * Multiple surfaces could share the same HAL stream, but a request may
     * be only for a subset of surfaces. In this case, the
     * Camera3StreamInterface object needs the surface ID information to acquire
     * buffers for those surfaces.
     *
     * This method may only be called once finishConfiguration has been called.
     * For bidirectional streams, this method applies to the output-side
     * buffers.
     *
     */
    status_t         getBuffer(camera3_stream_buffer *buffer,
            const std::vector<size_t>& surface_ids = std::vector<size_t>());

    /**
     * Return a buffer to the stream after use by the HAL.
     *
     * This method may only be called for buffers provided by getBuffer().
     * For bidirectional streams, this method applies to the output-side buffers
     */
    status_t         returnBuffer(const camera3_stream_buffer &buffer,
            nsecs_t timestamp);

    /**
     * Fill in the camera3_stream_buffer with the next valid buffer for this
     * stream, to hand over to the HAL.
     *
     * This method may only be called once finishConfiguration has been called.
     * For bidirectional streams, this method applies to the input-side
     * buffers.
     *
     */
    status_t         getInputBuffer(camera3_stream_buffer *buffer);

    /**
     * Return a buffer to the stream after use by the HAL.
     *
     * This method may only be called for buffers provided by getBuffer().
     * For bidirectional streams, this method applies to the input-side buffers
     */
    status_t         returnInputBuffer(const camera3_stream_buffer &buffer);

    // get the buffer producer of the input buffer queue.
    // only apply to input streams.
    status_t         getInputBufferProducer(sp<IGraphicBufferProducer> *producer);

    /**
     * Whether any of the stream's buffers are currently in use by the HAL,
     * including buffers that have been returned but not yet had their
     * release fence signaled.
     */
    bool             hasOutstandingBuffers() const;

    enum {
        TIMEOUT_NEVER = -1
    };

    /**
     * Set the status tracker to notify about idle transitions
     */
    virtual status_t setStatusTracker(sp<StatusTracker> statusTracker);

    /**
     * Disconnect stream from its non-HAL endpoint. After this,
     * start/finishConfiguration must be called before the stream can be used
     * again. This cannot be called if the stream has outstanding dequeued
     * buffers.
     */
    status_t         disconnect();

    /**
     * Debug dump of the stream's state.
     */
    virtual void     dump(int fd, const Vector<String16> &args) const = 0;

    /**
     * Add a camera3 buffer listener. Adding the same listener twice has
     * no effect.
     */
    void             addBufferListener(
            wp<Camera3StreamBufferListener> listener);

    /**
     * Remove a camera3 buffer listener. Removing the same listener twice
     * or the listener that was never added has no effect.
     */
    void             removeBufferListener(
            const sp<Camera3StreamBufferListener>& listener);


    // Setting listener will remove previous listener (if exists)
    virtual void     setBufferFreedListener(
            Camera3StreamBufferFreedListener* listener) override;

    /**
     * Return if the buffer queue of the stream is abandoned.
     */
    bool             isAbandoned() const;

  protected:
    const int mId;
    /**
     * Stream set id, used to indicate which group of this stream belongs to for buffer sharing
     * across multiple streams.
     *
     * The default value is set to CAMERA3_STREAM_SET_ID_INVALID, which indicates that this stream
     * doesn't intend to share buffers with any other streams, and this stream will fall back to
     * the existing BufferQueue mechanism to manage the buffer allocations and buffer circulation.
     * When a valid stream set id is set, this stream intends to use the Camera3BufferManager to
     * manage the buffer allocations; the BufferQueue will only handle the buffer transaction
     * between the producer and consumer. For this case, upon successfully registration, the streams
     * with the same stream set id will potentially share the buffers allocated by
     * Camera3BufferManager.
     */
    const int mSetId;

    const String8 mName;
    // Zero for formats with fixed buffer size for given dimensions.
    const size_t mMaxSize;

    enum {
        STATE_ERROR,
        STATE_CONSTRUCTED,
        STATE_IN_CONFIG,
        STATE_IN_RECONFIG,
        STATE_CONFIGURED,
        STATE_PREPARING,
        STATE_ABANDONED
    } mState;

    mutable Mutex mLock;

    Camera3Stream(int id, camera3_stream_type type,
            uint32_t width, uint32_t height, size_t maxSize, int format,
            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
            int setId);

    Camera3StreamBufferFreedListener* mBufferFreedListener;

    /**
     * Interface to be implemented by derived classes
     */

    // getBuffer / returnBuffer implementations

    // Since camera3_stream_buffer includes a raw pointer to the stream,
    // cast to camera3_stream*, implementations must increment the
    // refcount of the stream manually in getBufferLocked, and decrement it in
    // returnBufferLocked.
    virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
            const std::vector<size_t>& surface_ids = std::vector<size_t>());
    virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
            nsecs_t timestamp);
    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
    virtual status_t returnInputBufferLocked(
            const camera3_stream_buffer &buffer);
    virtual bool     hasOutstandingBuffersLocked() const = 0;
    // Get the buffer producer of the input buffer queue. Only apply to input streams.
    virtual status_t getInputBufferProducerLocked(sp<IGraphicBufferProducer> *producer);

    // Can return -ENOTCONN when we are already disconnected (not an error)
    virtual status_t disconnectLocked() = 0;

    // Configure the buffer queue interface to the other end of the stream,
    // after the HAL has provided usage and max_buffers values. After this call,
    // the stream must be ready to produce all buffers for registration with
    // HAL.
    virtual status_t configureQueueLocked() = 0;

    // Get the total number of buffers in the queue
    virtual size_t   getBufferCountLocked() = 0;

    // Get handout output buffer count.
    virtual size_t   getHandoutOutputBufferCountLocked() = 0;

    // Get handout input buffer count.
    virtual size_t   getHandoutInputBufferCountLocked() = 0;

    // Get the usage flags for the other endpoint, or return
    // INVALID_OPERATION if they cannot be obtained.
    virtual status_t getEndpointUsage(uint32_t *usage) const = 0;

    // Tracking for idle state
    wp<StatusTracker> mStatusTracker;
    // Status tracker component ID
    int mStatusId;

    // Tracking for stream prepare - whether this stream can still have
    // prepareNextBuffer called on it.
    bool mStreamUnpreparable;

  private:
    uint32_t mOldUsage;
    uint32_t mOldMaxBuffers;
    Condition mOutputBufferReturnedSignal;
    Condition mInputBufferReturnedSignal;
    static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms

    void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
                                  bool acquired, bool output);
    List<wp<Camera3StreamBufferListener> > mBufferListenerList;

    status_t        cancelPrepareLocked();

    // Return whether the buffer is in the list of outstanding buffers.
    bool isOutstandingBuffer(const camera3_stream_buffer& buffer);

    // Remove the buffer from the list of outstanding buffers.
    void removeOutstandingBuffer(const camera3_stream_buffer& buffer);

    // Tracking for PREPARING state

    // State of buffer preallocation. Only true if either prepareNextBuffer
    // has been called sufficient number of times, or stream configuration
    // had to register buffers with the HAL
    bool mPrepared;

    Vector<camera3_stream_buffer_t> mPreparedBuffers;
    size_t mPreparedBufferIdx;

    // Number of buffers allocated on last prepare call.
    size_t mLastMaxCount;

    // Outstanding buffers dequeued from the stream's buffer queue.
    List<buffer_handle_t> mOutstandingBuffers;

}; // class Camera3Stream

}; // namespace camera3

}; // namespace android

#endif
