/*
 * 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;

    /**
     * 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. During this call, the stream
     * may call the device's register_stream_buffers() method. 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
     */
    status_t         finishConfiguration(camera3_device *hal3Device);

    /**
     * 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.
     *
     * 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);

    /**
     * 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);

    /**
     * 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);

    /**
     * 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);
    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

    // Gets all buffers from endpoint and registers them with the HAL.
    status_t registerBuffersLocked(camera3_device *hal3Device);

    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
