/*
 * Copyright (C) 2008 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_HARDWARE_CAMERA_H
#define ANDROID_HARDWARE_CAMERA_H

#include <utils/Timers.h>

#include <android/hardware/ICameraService.h>

#include <gui/IGraphicBufferProducer.h>
#include <system/camera.h>
#include <camera/ICameraRecordingProxy.h>
#include <camera/android/hardware/ICamera.h>
#include <camera/android/hardware/ICameraClient.h>
#include <camera/CameraBase.h>

namespace android {

class Surface;
class String8;
class String16;

// ref-counted object for callbacks
class CameraListener: virtual public RefBase
{
public:
    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
                          camera_frame_metadata_t *metadata) = 0;
    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
    virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle) = 0;
    virtual void postRecordingFrameHandleTimestampBatch(
            const std::vector<nsecs_t>& timestamps,
            const std::vector<native_handle_t*>& handles) = 0;
};

class Camera;

template <>
struct CameraTraits<Camera>
{
    typedef CameraListener                     TCamListener;
    typedef ::android::hardware::ICamera       TCamUser;
    typedef ::android::hardware::ICameraClient TCamCallbacks;
    typedef ::android::binder::Status (::android::hardware::ICameraService::*TCamConnectService)
        (const sp<::android::hardware::ICameraClient>&,
        int, const std::string&, int, int, int, bool, bool,
        /*out*/
        sp<::android::hardware::ICamera>*);
    static TCamConnectService     fnConnectService;
};


class Camera :
    public CameraBase<Camera>,
    public ::android::hardware::BnCameraClient
{
public:
    enum {
        USE_CALLING_UID = ::android::hardware::ICameraService::USE_CALLING_UID
    };
    enum {
        USE_CALLING_PID = ::android::hardware::ICameraService::USE_CALLING_PID
    };

            // construct a camera client from an existing remote
    static  sp<Camera>  create(const sp<::android::hardware::ICamera>& camera);
    static  sp<Camera>  connect(int cameraId,
                                const std::string& clientPackageName,
                                int clientUid, int clientPid, int targetSdkVersion,
                                bool overrideToPortrait, bool forceSlowJpegMode);

            virtual     ~Camera();

            status_t    reconnect();
            status_t    lock();
            status_t    unlock();

            // pass the buffered IGraphicBufferProducer to the camera service
            status_t    setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer);

            // start preview mode, must call setPreviewTarget first
            status_t    startPreview();

            // stop preview mode
            void        stopPreview();

            // get preview state
            bool        previewEnabled();

            // start recording mode, must call setPreviewTarget first
            status_t    startRecording();

            // stop recording mode
            void        stopRecording();

            // get recording state
            bool        recordingEnabled();

            // release a recording frame
            void        releaseRecordingFrame(const sp<IMemory>& mem);

            // release a recording frame handle
            void        releaseRecordingFrameHandle(native_handle_t *handle);

            // release a batch of recording frame handles
            void        releaseRecordingFrameHandleBatch(
                    const std::vector<native_handle_t*> handles);

            // autoFocus - status returned from callback
            status_t    autoFocus();

            // cancel auto focus
            status_t    cancelAutoFocus();

            // take a picture - picture returned from callback
            status_t    takePicture(int msgType);

            // set preview/capture parameters - key/value pairs
            status_t    setParameters(const String8& params);

            // get preview/capture parameters - key/value pairs
            String8     getParameters() const;

            // send command to camera driver
            status_t    sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);

            // Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*.
            // Returns OK if the specified video buffer mode is supported. If videoBufferMode is
            // VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting
            // video recording.
            status_t    setVideoBufferMode(int32_t videoBufferMode);

            // Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE
            // mode.
            status_t    setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);

            void        setListener(const sp<CameraListener>& listener);

            // Configure preview callbacks to app. Only one of the older
            // callbacks or the callback surface can be active at the same time;
            // enabling one will disable the other if active. Flags can be
            // disabled by calling it with CAMERA_FRAME_CALLBACK_FLAG_NOOP, and
            // Target by calling it with a NULL interface.
            void        setPreviewCallbackFlags(int preview_callback_flag);
            status_t    setPreviewCallbackTarget(
                    const sp<IGraphicBufferProducer>& callbackProducer);

            sp<ICameraRecordingProxy> getRecordingProxy();

            status_t     setAudioRestriction(int32_t mode);
            int32_t      getGlobalAudioRestriction();

    // ICameraClient interface
    virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
                                     camera_frame_metadata_t *metadata);
    virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
    virtual void        recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle);
    virtual void        recordingFrameHandleCallbackTimestampBatch(
                                const std::vector<nsecs_t>& timestamps,
                                const std::vector<native_handle_t*>& handles);


    class RecordingProxy : public BnCameraRecordingProxy
    {
    public:
        explicit RecordingProxy(const sp<Camera>& camera);

        // ICameraRecordingProxy interface
        virtual status_t startRecording();
        virtual void stopRecording();

    private:
        sp<Camera>         mCamera;
    };

protected:
    explicit            Camera(int cameraId);
                        Camera(const Camera&);
                        Camera& operator=(const Camera);

    friend class        CameraBase;
};

}; // namespace android

#endif
