/*
 * 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_HARDWARE_INTERFACE_H
#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H

#include <binder/IMemory.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <utils/RefBase.h>
#include <ui/GraphicBuffer.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
#include <system/window.h>
#include <hardware/camera.h>

namespace android {

typedef void (*notify_callback)(int32_t msgType,
                            int32_t ext1,
                            int32_t ext2,
                            void* user);

typedef void (*data_callback)(int32_t msgType,
                            const sp<IMemory> &dataPtr,
                            camera_frame_metadata_t *metadata,
                            void* user);

typedef void (*data_callback_timestamp)(nsecs_t timestamp,
                            int32_t msgType,
                            const sp<IMemory> &dataPtr,
                            void *user);

/**
 * CameraHardwareInterface.h defines the interface to the
 * camera hardware abstraction layer, used for setting and getting
 * parameters, live previewing, and taking pictures. It is used for
 * HAL devices with version CAMERA_DEVICE_API_VERSION_1_0 only.
 *
 * It is a referenced counted interface with RefBase as its base class.
 * CameraService calls openCameraHardware() to retrieve a strong pointer to the
 * instance of this interface and may be called multiple times. The
 * following steps describe a typical sequence:
 *
 *   -# After CameraService calls openCameraHardware(), getParameters() and
 *      setParameters() are used to initialize the camera instance.
 *   -# startPreview() is called.
 *
 * Prior to taking a picture, CameraService often calls autofocus(). When auto
 * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
 * which informs the application whether focusing was successful. The camera instance
 * only sends this message once and it is up  to the application to call autoFocus()
 * again if refocusing is desired.
 *
 * CameraService calls takePicture() to request the camera instance take a
 * picture. At this point, if a shutter, postview, raw, and/or compressed
 * callback is desired, the corresponding message must be enabled. Any memory
 * provided in a data callback must be copied if it's needed after returning.
 */

class CameraHardwareInterface : public virtual RefBase {
public:
    CameraHardwareInterface(const char *name):
            mDevice(nullptr),
            mName(name),
            mPreviewScalingMode(NOT_SET),
            mPreviewTransform(NOT_SET),
            mPreviewWidth(NOT_SET),
            mPreviewHeight(NOT_SET),
            mPreviewFormat(NOT_SET),
            mPreviewUsage(0),
            mPreviewSwapInterval(NOT_SET),
            mPreviewCrop{NOT_SET,NOT_SET,NOT_SET,NOT_SET}
    {
    }

    ~CameraHardwareInterface()
    {
        ALOGI("Destroying camera %s", mName.string());
        if(mDevice) {
            int rc = mDevice->common.close(&mDevice->common);
            if (rc != OK)
                ALOGE("Could not close camera %s: %d", mName.string(), rc);
        }
    }

    status_t initialize(CameraModule *module)
    {
        ALOGI("Opening camera %s", mName.string());
        camera_info info;
        status_t res = module->getCameraInfo(atoi(mName.string()), &info);
        if (res != OK) {
            return res;
        }

        int rc = OK;
        if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
            info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
            // Open higher version camera device as HAL1.0 device.
            rc = module->openLegacy(mName.string(),
                                     CAMERA_DEVICE_API_VERSION_1_0,
                                     (hw_device_t **)&mDevice);
        } else {
            rc = module->open(mName.string(), (hw_device_t **)&mDevice);
        }
        if (rc != OK) {
            ALOGE("Could not open camera %s: %d", mName.string(), rc);
            return rc;
        }
        initHalPreviewWindow();
        return rc;
    }

    /** Set the ANativeWindow to which preview frames are sent */
    status_t setPreviewWindow(const sp<ANativeWindow>& buf)
    {
        ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
        if (mDevice->ops->set_preview_window) {
            mPreviewWindow = buf;
            if (buf != nullptr) {
                if (mPreviewScalingMode != NOT_SET) {
                    setPreviewScalingMode(mPreviewScalingMode);
                }
                if (mPreviewTransform != NOT_SET) {
                    setPreviewTransform(mPreviewTransform);
                }
            }
            mHalPreviewWindow.user = this;
            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
                    &mHalPreviewWindow, mHalPreviewWindow.user);
            return mDevice->ops->set_preview_window(mDevice,
                    buf.get() ? &mHalPreviewWindow.nw : 0);
        }
        return INVALID_OPERATION;
    }

    status_t setPreviewScalingMode(int scalingMode)
    {
        int rc = OK;
        mPreviewScalingMode = scalingMode;
        if (mPreviewWindow != nullptr) {
            rc = native_window_set_scaling_mode(mPreviewWindow.get(),
                    scalingMode);
        }
        return rc;
    }

    status_t setPreviewTransform(int transform) {
        int rc = OK;
        mPreviewTransform = transform;
        if (mPreviewWindow != nullptr) {
            rc = native_window_set_buffers_transform(mPreviewWindow.get(),
                    mPreviewTransform);
        }
        return rc;
    }

    /** Set the notification and data callbacks */
    void setCallbacks(notify_callback notify_cb,
                      data_callback data_cb,
                      data_callback_timestamp data_cb_timestamp,
                      void* user)
    {
        mNotifyCb = notify_cb;
        mDataCb = data_cb;
        mDataCbTimestamp = data_cb_timestamp;
        mCbUser = user;

        ALOGV("%s(%s)", __FUNCTION__, mName.string());

        if (mDevice->ops->set_callbacks) {
            mDevice->ops->set_callbacks(mDevice,
                                   __notify_cb,
                                   __data_cb,
                                   __data_cb_timestamp,
                                   __get_memory,
                                   this);
        }
    }

    /**
     * The following three functions all take a msgtype,
     * which is a bitmask of the messages defined in
     * include/ui/Camera.h
     */

    /**
     * Enable a message, or set of messages.
     */
    void enableMsgType(int32_t msgType)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->enable_msg_type)
            mDevice->ops->enable_msg_type(mDevice, msgType);
    }

    /**
     * Disable a message, or a set of messages.
     *
     * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
     * should not rely on its client to call releaseRecordingFrame() to release
     * video recording frames sent out by the cameral hal before and after the
     * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
     * modify/access any video recording frame after calling
     * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
     */
    void disableMsgType(int32_t msgType)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->disable_msg_type)
            mDevice->ops->disable_msg_type(mDevice, msgType);
    }

    /**
     * Query whether a message, or a set of messages, is enabled.
     * Note that this is operates as an AND, if any of the messages
     * queried are off, this will return false.
     */
    int msgTypeEnabled(int32_t msgType)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->msg_type_enabled)
            return mDevice->ops->msg_type_enabled(mDevice, msgType);
        return false;
    }

    /**
     * Start preview mode.
     */
    status_t startPreview()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->start_preview)
            return mDevice->ops->start_preview(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Stop a previously started preview.
     */
    void stopPreview()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->stop_preview)
            mDevice->ops->stop_preview(mDevice);
    }

    /**
     * Returns true if preview is enabled.
     */
    int previewEnabled()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->preview_enabled)
            return mDevice->ops->preview_enabled(mDevice);
        return false;
    }

    /**
     * Request the camera hal to store meta data or real YUV data in
     * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
     * recording session. If it is not called, the default camera
     * hal behavior is to store real YUV data in the video buffers.
     *
     * This method should be called before startRecording() in order
     * to be effective.
     *
     * If meta data is stored in the video buffers, it is up to the
     * receiver of the video buffers to interpret the contents and
     * to find the actual frame data with the help of the meta data
     * in the buffer. How this is done is outside of the scope of
     * this method.
     *
     * Some camera hal may not support storing meta data in the video
     * buffers, but all camera hal should support storing real YUV data
     * in the video buffers. If the camera hal does not support storing
     * the meta data in the video buffers when it is requested to do
     * do, INVALID_OPERATION must be returned. It is very useful for
     * the camera hal to pass meta data rather than the actual frame
     * data directly to the video encoder, since the amount of the
     * uncompressed frame data can be very large if video size is large.
     *
     * @param enable if true to instruct the camera hal to store
     *      meta data in the video buffers; false to instruct
     *      the camera hal to store real YUV data in the video
     *      buffers.
     *
     * @return OK on success.
     */

    status_t storeMetaDataInBuffers(int enable)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->store_meta_data_in_buffers)
            return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
        return enable ? INVALID_OPERATION: OK;
    }

    /**
     * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
     * message is sent with the corresponding frame. Every record frame must be released
     * by a cameral hal client via releaseRecordingFrame() before the client calls
     * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
     * to manage the life-cycle of the video recording frames, and the client must
     * not modify/access any video recording frames.
     */
    status_t startRecording()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->start_recording)
            return mDevice->ops->start_recording(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Stop a previously started recording.
     */
    void stopRecording()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->stop_recording)
            mDevice->ops->stop_recording(mDevice);
    }

    /**
     * Returns true if recording is enabled.
     */
    int recordingEnabled()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->recording_enabled)
            return mDevice->ops->recording_enabled(mDevice);
        return false;
    }

    /**
     * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
     *
     * It is camera hal client's responsibility to release video recording
     * frames sent out by the camera hal before the camera hal receives
     * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
     * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
     * responsibility of managing the life-cycle of the video recording
     * frames.
     */
    void releaseRecordingFrame(const sp<IMemory>& mem)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->release_recording_frame) {
            ssize_t offset;
            size_t size;
            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
            void *data = ((uint8_t *)heap->base()) + offset;
            return mDevice->ops->release_recording_frame(mDevice, data);
        }
    }

    /**
     * Start auto focus, the notification callback routine is called
     * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
     * will be called again if another auto focus is needed.
     */
    status_t autoFocus()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->auto_focus)
            return mDevice->ops->auto_focus(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Cancels auto-focus function. If the auto-focus is still in progress,
     * this function will cancel it. Whether the auto-focus is in progress
     * or not, this function will return the focus position to the default.
     * If the camera does not support auto-focus, this is a no-op.
     */
    status_t cancelAutoFocus()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->cancel_auto_focus)
            return mDevice->ops->cancel_auto_focus(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Take a picture.
     */
    status_t takePicture()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->take_picture)
            return mDevice->ops->take_picture(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Cancel a picture that was started with takePicture.  Calling this
     * method when no picture is being taken is a no-op.
     */
    status_t cancelPicture()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->cancel_picture)
            return mDevice->ops->cancel_picture(mDevice);
        return INVALID_OPERATION;
    }

    /**
     * Set the camera parameters. This returns BAD_VALUE if any parameter is
     * invalid or not supported. */
    status_t setParameters(const CameraParameters &params)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->set_parameters)
            return mDevice->ops->set_parameters(mDevice,
                                               params.flatten().string());
        return INVALID_OPERATION;
    }

    /** Return the camera parameters. */
    CameraParameters getParameters() const
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        CameraParameters parms;
        if (mDevice->ops->get_parameters) {
            char *temp = mDevice->ops->get_parameters(mDevice);
            String8 str_parms(temp);
            if (mDevice->ops->put_parameters)
                mDevice->ops->put_parameters(mDevice, temp);
            else
                free(temp);
            parms.unflatten(str_parms);
        }
        return parms;
    }

    /**
     * Send command to camera driver.
     */
    status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->send_command)
            return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
        return INVALID_OPERATION;
    }

    /**
     * Release the hardware resources owned by this object.  Note that this is
     * *not* done in the destructor.
     */
    void release() {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->release)
            mDevice->ops->release(mDevice);
    }

    /**
     * Dump state of the camera hardware
     */
    status_t dump(int fd, const Vector<String16>& /*args*/) const
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->dump)
            return mDevice->ops->dump(mDevice, fd);
        return OK; // It's fine if the HAL doesn't implement dump()
    }

private:
    camera_device_t *mDevice;
    String8 mName;

    static void __notify_cb(int32_t msg_type, int32_t ext1,
                            int32_t ext2, void *user)
    {
        ALOGV("%s", __FUNCTION__);
        CameraHardwareInterface *__this =
                static_cast<CameraHardwareInterface *>(user);
        __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
    }

    static void __data_cb(int32_t msg_type,
                          const camera_memory_t *data, unsigned int index,
                          camera_frame_metadata_t *metadata,
                          void *user)
    {
        ALOGV("%s", __FUNCTION__);
        CameraHardwareInterface *__this =
                static_cast<CameraHardwareInterface *>(user);
        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
        if (index >= mem->mNumBufs) {
            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
                 index, mem->mNumBufs);
            return;
        }
        __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
    }

    static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
                             const camera_memory_t *data, unsigned index,
                             void *user)
    {
        ALOGV("%s", __FUNCTION__);
        CameraHardwareInterface *__this =
                static_cast<CameraHardwareInterface *>(user);
        // Start refcounting the heap object from here on.  When the clients
        // drop all references, it will be destroyed (as well as the enclosed
        // MemoryHeapBase.
        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
        if (index >= mem->mNumBufs) {
            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
                 index, mem->mNumBufs);
            return;
        }
        __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser);
    }

    // This is a utility class that combines a MemoryHeapBase and a MemoryBase
    // in one.  Since we tend to use them in a one-to-one relationship, this is
    // handy.

    class CameraHeapMemory : public RefBase {
    public:
        CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) :
                         mBufSize(buf_size),
                         mNumBufs(num_buffers)
        {
            mHeap = new MemoryHeapBase(fd, buf_size * num_buffers);
            commonInitialization();
        }

        CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1) :
                         mBufSize(buf_size),
                         mNumBufs(num_buffers)
        {
            mHeap = new MemoryHeapBase(buf_size * num_buffers);
            commonInitialization();
        }

        void commonInitialization()
        {
            handle.data = mHeap->base();
            handle.size = mBufSize * mNumBufs;
            handle.handle = this;

            mBuffers = new sp<MemoryBase>[mNumBufs];
            for (uint_t i = 0; i < mNumBufs; i++)
                mBuffers[i] = new MemoryBase(mHeap,
                                             i * mBufSize,
                                             mBufSize);

            handle.release = __put_memory;
        }

        virtual ~CameraHeapMemory()
        {
            delete [] mBuffers;
        }

        size_t mBufSize;
        uint_t mNumBufs;
        sp<MemoryHeapBase> mHeap;
        sp<MemoryBase> *mBuffers;

        camera_memory_t handle;
    };

    static camera_memory_t* __get_memory(int fd, size_t buf_size, uint_t num_bufs,
                                         void *user __attribute__((unused)))
    {
        CameraHeapMemory *mem;
        if (fd < 0)
            mem = new CameraHeapMemory(buf_size, num_bufs);
        else
            mem = new CameraHeapMemory(fd, buf_size, num_bufs);
        mem->incStrong(mem);
        return &mem->handle;
    }

    static void __put_memory(camera_memory_t *data)
    {
        if (!data)
            return;

        CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
        mem->decStrong(mem);
    }

    static ANativeWindow *__to_anw(void *user)
    {
        CameraHardwareInterface *__this =
                reinterpret_cast<CameraHardwareInterface *>(user);
        return __this->mPreviewWindow.get();
    }
#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
        ((struct camera_preview_window *)n)->user)

    static int __dequeue_buffer(struct preview_stream_ops* w,
                                buffer_handle_t** buffer, int *stride)
    {
        int rc;
        ANativeWindow *a = anw(w);
        ANativeWindowBuffer* anb;
        rc = native_window_dequeue_buffer_and_wait(a, &anb);
        if (!rc) {
            *buffer = &anb->handle;
            *stride = anb->stride;
        }
        return rc;
    }

#ifndef container_of
#define container_of(ptr, type, member) ({                      \
        const __typeof__(((type *) 0)->member) *__mptr = (ptr);     \
        (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
#endif

    static int __lock_buffer(struct preview_stream_ops* w,
                      buffer_handle_t* /*buffer*/)
    {
        ANativeWindow *a = anw(w);
        (void)a;
        return 0;
    }

    static int __enqueue_buffer(struct preview_stream_ops* w,
                      buffer_handle_t* buffer)
    {
        ANativeWindow *a = anw(w);
        return a->queueBuffer(a,
                  container_of(buffer, ANativeWindowBuffer, handle), -1);
    }

    static int __cancel_buffer(struct preview_stream_ops* w,
                      buffer_handle_t* buffer)
    {
        ANativeWindow *a = anw(w);
        return a->cancelBuffer(a,
                  container_of(buffer, ANativeWindowBuffer, handle), -1);
    }

    static int __set_buffer_count(struct preview_stream_ops* w, int count)
    {
        ANativeWindow *a = anw(w);

        if (a != nullptr) {
            // Workaround for b/27039775
            // Previously, setting the buffer count would reset the buffer
            // queue's flag that allows for all buffers to be dequeued on the
            // producer side, instead of just the producer's declared max count,
            // if no filled buffers have yet been queued by the producer.  This
            // reset no longer happens, but some HALs depend on this behavior,
            // so it needs to be maintained for HAL backwards compatibility.
            // Simulate the prior behavior by disconnecting/reconnecting to the
            // window and setting the values again.  This has the drawback of
            // actually causing memory reallocation, which may not have happened
            // in the past.
            CameraHardwareInterface *hw = hwi(w);
            native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
            native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
            if (hw->mPreviewScalingMode != NOT_SET) {
                native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
            }
            if (hw->mPreviewTransform != NOT_SET) {
                native_window_set_buffers_transform(a, hw->mPreviewTransform);
            }
            if (hw->mPreviewWidth != NOT_SET) {
                native_window_set_buffers_dimensions(a,
                        hw->mPreviewWidth, hw->mPreviewHeight);
                native_window_set_buffers_format(a, hw->mPreviewFormat);
            }
            if (hw->mPreviewUsage != 0) {
                native_window_set_usage(a, hw->mPreviewUsage);
            }
            if (hw->mPreviewSwapInterval != NOT_SET) {
                a->setSwapInterval(a, hw->mPreviewSwapInterval);
            }
            if (hw->mPreviewCrop.left != NOT_SET) {
                native_window_set_crop(a, &(hw->mPreviewCrop));
            }
        }

        return native_window_set_buffer_count(a, count);
    }

    static int __set_buffers_geometry(struct preview_stream_ops* w,
                      int width, int height, int format)
    {
        int rc;
        ANativeWindow *a = anw(w);
        CameraHardwareInterface *hw = hwi(w);
        hw->mPreviewWidth = width;
        hw->mPreviewHeight = height;
        hw->mPreviewFormat = format;
        rc = native_window_set_buffers_dimensions(a, width, height);
        if (!rc) {
            rc = native_window_set_buffers_format(a, format);
        }
        return rc;
    }

    static int __set_crop(struct preview_stream_ops *w,
                      int left, int top, int right, int bottom)
    {
        ANativeWindow *a = anw(w);
        CameraHardwareInterface *hw = hwi(w);
        hw->mPreviewCrop.left = left;
        hw->mPreviewCrop.top = top;
        hw->mPreviewCrop.right = right;
        hw->mPreviewCrop.bottom = bottom;
        return native_window_set_crop(a, &(hw->mPreviewCrop));
    }

    static int __set_timestamp(struct preview_stream_ops *w,
                               int64_t timestamp) {
        ANativeWindow *a = anw(w);
        return native_window_set_buffers_timestamp(a, timestamp);
    }

    static int __set_usage(struct preview_stream_ops* w, int usage)
    {
        ANativeWindow *a = anw(w);
        CameraHardwareInterface *hw = hwi(w);
        hw->mPreviewUsage = usage;
        return native_window_set_usage(a, usage);
    }

    static int __set_swap_interval(struct preview_stream_ops *w, int interval)
    {
        ANativeWindow *a = anw(w);
        CameraHardwareInterface *hw = hwi(w);
        hw->mPreviewSwapInterval = interval;
        return a->setSwapInterval(a, interval);
    }

    static int __get_min_undequeued_buffer_count(
                      const struct preview_stream_ops *w,
                      int *count)
    {
        ANativeWindow *a = anw(w);
        return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
    }

    void initHalPreviewWindow()
    {
        mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
        mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
        mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
        mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
        mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
        mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
        mHalPreviewWindow.nw.set_crop = __set_crop;
        mHalPreviewWindow.nw.set_timestamp = __set_timestamp;
        mHalPreviewWindow.nw.set_usage = __set_usage;
        mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;

        mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
                __get_min_undequeued_buffer_count;
    }

    sp<ANativeWindow>        mPreviewWindow;

    struct camera_preview_window {
        struct preview_stream_ops nw;
        void *user;
    };

    struct camera_preview_window mHalPreviewWindow;

    notify_callback         mNotifyCb;
    data_callback           mDataCb;
    data_callback_timestamp mDataCbTimestamp;
    void *mCbUser;

    // Cached values for preview stream parameters
    static const int NOT_SET = -1;
    int mPreviewScalingMode;
    int mPreviewTransform;
    int mPreviewWidth;
    int mPreviewHeight;
    int mPreviewFormat;
    int mPreviewUsage;
    int mPreviewSwapInterval;
    android_native_rect_t mPreviewCrop;
};

};  // namespace android

#endif
