1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
18#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
19
20#include <binder/IMemory.h>
21#include <binder/MemoryBase.h>
22#include <binder/MemoryHeapBase.h>
23#include <utils/RefBase.h>
24#include <ui/GraphicBuffer.h>
25#include <camera/Camera.h>
26#include <camera/CameraParameters.h>
27#include <system/window.h>
28#include <hardware/camera.h>
29
30namespace android {
31
32typedef void (*notify_callback)(int32_t msgType,
33                            int32_t ext1,
34                            int32_t ext2,
35                            void* user);
36
37typedef void (*data_callback)(int32_t msgType,
38                            const sp<IMemory> &dataPtr,
39                            camera_frame_metadata_t *metadata,
40                            void* user);
41
42typedef void (*data_callback_timestamp)(nsecs_t timestamp,
43                            int32_t msgType,
44                            const sp<IMemory> &dataPtr,
45                            void *user);
46
47/**
48 * CameraHardwareInterface.h defines the interface to the
49 * camera hardware abstraction layer, used for setting and getting
50 * parameters, live previewing, and taking pictures.
51 *
52 * It is a referenced counted interface with RefBase as its base class.
53 * CameraService calls openCameraHardware() to retrieve a strong pointer to the
54 * instance of this interface and may be called multiple times. The
55 * following steps describe a typical sequence:
56 *
57 *   -# After CameraService calls openCameraHardware(), getParameters() and
58 *      setParameters() are used to initialize the camera instance.
59 *      CameraService calls getPreviewHeap() to establish access to the
60 *      preview heap so it can be registered with SurfaceFlinger for
61 *      efficient display updating while in preview mode.
62 *   -# startPreview() is called.  The camera instance then periodically
63 *      sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
64 *      a new preview frame is available.  If data callback code needs to use
65 *      this memory after returning, it must copy the data.
66 *
67 * Prior to taking a picture, CameraService calls autofocus(). When auto
68 * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
69 * which informs the application whether focusing was successful. The camera instance
70 * only sends this message once and it is up  to the application to call autoFocus()
71 * again if refocusing is desired.
72 *
73 * CameraService calls takePicture() to request the camera instance take a
74 * picture. At this point, if a shutter, postview, raw, and/or compressed callback
75 * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
76 * any memory provided in a data callback must be copied if it's needed after returning.
77 */
78
79class CameraHardwareInterface : public virtual RefBase {
80public:
81    CameraHardwareInterface(const char *name)
82    {
83        mDevice = 0;
84        mName = name;
85    }
86
87    ~CameraHardwareInterface()
88    {
89        ALOGI("Destroying camera %s", mName.string());
90        if(mDevice) {
91            int rc = mDevice->common.close(&mDevice->common);
92            if (rc != OK)
93                ALOGE("Could not close camera %s: %d", mName.string(), rc);
94        }
95    }
96
97    status_t initialize(hw_module_t *module)
98    {
99        ALOGI("Opening camera %s", mName.string());
100        int rc = module->methods->open(module, mName.string(),
101                                       (hw_device_t **)&mDevice);
102        if (rc != OK) {
103            ALOGE("Could not open camera %s: %d", mName.string(), rc);
104            return rc;
105        }
106        initHalPreviewWindow();
107        return rc;
108    }
109
110    /** Set the ANativeWindow to which preview frames are sent */
111    status_t setPreviewWindow(const sp<ANativeWindow>& buf)
112    {
113        ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
114
115        if (mDevice->ops->set_preview_window) {
116            mPreviewWindow = buf;
117            mHalPreviewWindow.user = this;
118            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
119                    &mHalPreviewWindow, mHalPreviewWindow.user);
120            return mDevice->ops->set_preview_window(mDevice,
121                    buf.get() ? &mHalPreviewWindow.nw : 0);
122        }
123        return INVALID_OPERATION;
124    }
125
126    /** Set the notification and data callbacks */
127    void setCallbacks(notify_callback notify_cb,
128                      data_callback data_cb,
129                      data_callback_timestamp data_cb_timestamp,
130                      void* user)
131    {
132        mNotifyCb = notify_cb;
133        mDataCb = data_cb;
134        mDataCbTimestamp = data_cb_timestamp;
135        mCbUser = user;
136
137        ALOGV("%s(%s)", __FUNCTION__, mName.string());
138
139        if (mDevice->ops->set_callbacks) {
140            mDevice->ops->set_callbacks(mDevice,
141                                   __notify_cb,
142                                   __data_cb,
143                                   __data_cb_timestamp,
144                                   __get_memory,
145                                   this);
146        }
147    }
148
149    /**
150     * The following three functions all take a msgtype,
151     * which is a bitmask of the messages defined in
152     * include/ui/Camera.h
153     */
154
155    /**
156     * Enable a message, or set of messages.
157     */
158    void enableMsgType(int32_t msgType)
159    {
160        ALOGV("%s(%s)", __FUNCTION__, mName.string());
161        if (mDevice->ops->enable_msg_type)
162            mDevice->ops->enable_msg_type(mDevice, msgType);
163    }
164
165    /**
166     * Disable a message, or a set of messages.
167     *
168     * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
169     * should not rely on its client to call releaseRecordingFrame() to release
170     * video recording frames sent out by the cameral hal before and after the
171     * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
172     * modify/access any video recording frame after calling
173     * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
174     */
175    void disableMsgType(int32_t msgType)
176    {
177        ALOGV("%s(%s)", __FUNCTION__, mName.string());
178        if (mDevice->ops->disable_msg_type)
179            mDevice->ops->disable_msg_type(mDevice, msgType);
180    }
181
182    /**
183     * Query whether a message, or a set of messages, is enabled.
184     * Note that this is operates as an AND, if any of the messages
185     * queried are off, this will return false.
186     */
187    int msgTypeEnabled(int32_t msgType)
188    {
189        ALOGV("%s(%s)", __FUNCTION__, mName.string());
190        if (mDevice->ops->msg_type_enabled)
191            return mDevice->ops->msg_type_enabled(mDevice, msgType);
192        return false;
193    }
194
195    /**
196     * Start preview mode.
197     */
198    status_t startPreview()
199    {
200        ALOGV("%s(%s)", __FUNCTION__, mName.string());
201        if (mDevice->ops->start_preview)
202            return mDevice->ops->start_preview(mDevice);
203        return INVALID_OPERATION;
204    }
205
206    /**
207     * Stop a previously started preview.
208     */
209    void stopPreview()
210    {
211        ALOGV("%s(%s)", __FUNCTION__, mName.string());
212        if (mDevice->ops->stop_preview)
213            mDevice->ops->stop_preview(mDevice);
214    }
215
216    /**
217     * Returns true if preview is enabled.
218     */
219    int previewEnabled()
220    {
221        ALOGV("%s(%s)", __FUNCTION__, mName.string());
222        if (mDevice->ops->preview_enabled)
223            return mDevice->ops->preview_enabled(mDevice);
224        return false;
225    }
226
227    /**
228     * Request the camera hal to store meta data or real YUV data in
229     * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
230     * recording session. If it is not called, the default camera
231     * hal behavior is to store real YUV data in the video buffers.
232     *
233     * This method should be called before startRecording() in order
234     * to be effective.
235     *
236     * If meta data is stored in the video buffers, it is up to the
237     * receiver of the video buffers to interpret the contents and
238     * to find the actual frame data with the help of the meta data
239     * in the buffer. How this is done is outside of the scope of
240     * this method.
241     *
242     * Some camera hal may not support storing meta data in the video
243     * buffers, but all camera hal should support storing real YUV data
244     * in the video buffers. If the camera hal does not support storing
245     * the meta data in the video buffers when it is requested to do
246     * do, INVALID_OPERATION must be returned. It is very useful for
247     * the camera hal to pass meta data rather than the actual frame
248     * data directly to the video encoder, since the amount of the
249     * uncompressed frame data can be very large if video size is large.
250     *
251     * @param enable if true to instruct the camera hal to store
252     *      meta data in the video buffers; false to instruct
253     *      the camera hal to store real YUV data in the video
254     *      buffers.
255     *
256     * @return OK on success.
257     */
258
259    status_t storeMetaDataInBuffers(int enable)
260    {
261        ALOGV("%s(%s)", __FUNCTION__, mName.string());
262        if (mDevice->ops->store_meta_data_in_buffers)
263            return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
264        return enable ? INVALID_OPERATION: OK;
265    }
266
267    /**
268     * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
269     * message is sent with the corresponding frame. Every record frame must be released
270     * by a cameral hal client via releaseRecordingFrame() before the client calls
271     * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
272     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
273     * to manage the life-cycle of the video recording frames, and the client must
274     * not modify/access any video recording frames.
275     */
276    status_t startRecording()
277    {
278        ALOGV("%s(%s)", __FUNCTION__, mName.string());
279        if (mDevice->ops->start_recording)
280            return mDevice->ops->start_recording(mDevice);
281        return INVALID_OPERATION;
282    }
283
284    /**
285     * Stop a previously started recording.
286     */
287    void stopRecording()
288    {
289        ALOGV("%s(%s)", __FUNCTION__, mName.string());
290        if (mDevice->ops->stop_recording)
291            mDevice->ops->stop_recording(mDevice);
292    }
293
294    /**
295     * Returns true if recording is enabled.
296     */
297    int recordingEnabled()
298    {
299        ALOGV("%s(%s)", __FUNCTION__, mName.string());
300        if (mDevice->ops->recording_enabled)
301            return mDevice->ops->recording_enabled(mDevice);
302        return false;
303    }
304
305    /**
306     * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
307     *
308     * It is camera hal client's responsibility to release video recording
309     * frames sent out by the camera hal before the camera hal receives
310     * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
311     * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
312     * responsibility of managing the life-cycle of the video recording
313     * frames.
314     */
315    void releaseRecordingFrame(const sp<IMemory>& mem)
316    {
317        ALOGV("%s(%s)", __FUNCTION__, mName.string());
318        if (mDevice->ops->release_recording_frame) {
319            ssize_t offset;
320            size_t size;
321            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
322            void *data = ((uint8_t *)heap->base()) + offset;
323            return mDevice->ops->release_recording_frame(mDevice, data);
324        }
325    }
326
327    /**
328     * Start auto focus, the notification callback routine is called
329     * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
330     * will be called again if another auto focus is needed.
331     */
332    status_t autoFocus()
333    {
334        ALOGV("%s(%s)", __FUNCTION__, mName.string());
335        if (mDevice->ops->auto_focus)
336            return mDevice->ops->auto_focus(mDevice);
337        return INVALID_OPERATION;
338    }
339
340    /**
341     * Cancels auto-focus function. If the auto-focus is still in progress,
342     * this function will cancel it. Whether the auto-focus is in progress
343     * or not, this function will return the focus position to the default.
344     * If the camera does not support auto-focus, this is a no-op.
345     */
346    status_t cancelAutoFocus()
347    {
348        ALOGV("%s(%s)", __FUNCTION__, mName.string());
349        if (mDevice->ops->cancel_auto_focus)
350            return mDevice->ops->cancel_auto_focus(mDevice);
351        return INVALID_OPERATION;
352    }
353
354    /**
355     * Take a picture.
356     */
357    status_t takePicture()
358    {
359        ALOGV("%s(%s)", __FUNCTION__, mName.string());
360        if (mDevice->ops->take_picture)
361            return mDevice->ops->take_picture(mDevice);
362        return INVALID_OPERATION;
363    }
364
365    /**
366     * Cancel a picture that was started with takePicture.  Calling this
367     * method when no picture is being taken is a no-op.
368     */
369    status_t cancelPicture()
370    {
371        ALOGV("%s(%s)", __FUNCTION__, mName.string());
372        if (mDevice->ops->cancel_picture)
373            return mDevice->ops->cancel_picture(mDevice);
374        return INVALID_OPERATION;
375    }
376
377    /**
378     * Set the camera parameters. This returns BAD_VALUE if any parameter is
379     * invalid or not supported. */
380    status_t setParameters(const CameraParameters &params)
381    {
382        ALOGV("%s(%s)", __FUNCTION__, mName.string());
383        if (mDevice->ops->set_parameters)
384            return mDevice->ops->set_parameters(mDevice,
385                                               params.flatten().string());
386        return INVALID_OPERATION;
387    }
388
389    /** Return the camera parameters. */
390    CameraParameters getParameters() const
391    {
392        ALOGV("%s(%s)", __FUNCTION__, mName.string());
393        CameraParameters parms;
394        if (mDevice->ops->get_parameters) {
395            char *temp = mDevice->ops->get_parameters(mDevice);
396            String8 str_parms(temp);
397            if (mDevice->ops->put_parameters)
398                mDevice->ops->put_parameters(mDevice, temp);
399            else
400                free(temp);
401            parms.unflatten(str_parms);
402        }
403        return parms;
404    }
405
406    /**
407     * Send command to camera driver.
408     */
409    status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
410    {
411        ALOGV("%s(%s)", __FUNCTION__, mName.string());
412        if (mDevice->ops->send_command)
413            return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
414        return INVALID_OPERATION;
415    }
416
417    /**
418     * Release the hardware resources owned by this object.  Note that this is
419     * *not* done in the destructor.
420     */
421    void release() {
422        ALOGV("%s(%s)", __FUNCTION__, mName.string());
423        if (mDevice->ops->release)
424            mDevice->ops->release(mDevice);
425    }
426
427    /**
428     * Dump state of the camera hardware
429     */
430    status_t dump(int fd, const Vector<String16>& args) const
431    {
432        ALOGV("%s(%s)", __FUNCTION__, mName.string());
433        if (mDevice->ops->dump)
434            return mDevice->ops->dump(mDevice, fd);
435        return OK; // It's fine if the HAL doesn't implement dump()
436    }
437
438private:
439    camera_device_t *mDevice;
440    String8 mName;
441
442    static void __notify_cb(int32_t msg_type, int32_t ext1,
443                            int32_t ext2, void *user)
444    {
445        ALOGV("%s", __FUNCTION__);
446        CameraHardwareInterface *__this =
447                static_cast<CameraHardwareInterface *>(user);
448        __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
449    }
450
451    static void __data_cb(int32_t msg_type,
452                          const camera_memory_t *data, unsigned int index,
453                          camera_frame_metadata_t *metadata,
454                          void *user)
455    {
456        ALOGV("%s", __FUNCTION__);
457        CameraHardwareInterface *__this =
458                static_cast<CameraHardwareInterface *>(user);
459        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
460        if (index >= mem->mNumBufs) {
461            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
462                 index, mem->mNumBufs);
463            return;
464        }
465        __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
466    }
467
468    static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
469                             const camera_memory_t *data, unsigned index,
470                             void *user)
471    {
472        ALOGV("%s", __FUNCTION__);
473        CameraHardwareInterface *__this =
474                static_cast<CameraHardwareInterface *>(user);
475        // Start refcounting the heap object from here on.  When the clients
476        // drop all references, it will be destroyed (as well as the enclosed
477        // MemoryHeapBase.
478        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
479        if (index >= mem->mNumBufs) {
480            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
481                 index, mem->mNumBufs);
482            return;
483        }
484        __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser);
485    }
486
487    // This is a utility class that combines a MemoryHeapBase and a MemoryBase
488    // in one.  Since we tend to use them in a one-to-one relationship, this is
489    // handy.
490
491    class CameraHeapMemory : public RefBase {
492    public:
493        CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) :
494                         mBufSize(buf_size),
495                         mNumBufs(num_buffers)
496        {
497            mHeap = new MemoryHeapBase(fd, buf_size * num_buffers);
498            commonInitialization();
499        }
500
501        CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1) :
502                         mBufSize(buf_size),
503                         mNumBufs(num_buffers)
504        {
505            mHeap = new MemoryHeapBase(buf_size * num_buffers);
506            commonInitialization();
507        }
508
509        void commonInitialization()
510        {
511            handle.data = mHeap->base();
512            handle.size = mBufSize * mNumBufs;
513            handle.handle = this;
514
515            mBuffers = new sp<MemoryBase>[mNumBufs];
516            for (uint_t i = 0; i < mNumBufs; i++)
517                mBuffers[i] = new MemoryBase(mHeap,
518                                             i * mBufSize,
519                                             mBufSize);
520
521            handle.release = __put_memory;
522        }
523
524        virtual ~CameraHeapMemory()
525        {
526            delete [] mBuffers;
527        }
528
529        size_t mBufSize;
530        uint_t mNumBufs;
531        sp<MemoryHeapBase> mHeap;
532        sp<MemoryBase> *mBuffers;
533
534        camera_memory_t handle;
535    };
536
537    static camera_memory_t* __get_memory(int fd, size_t buf_size, uint_t num_bufs,
538                                         void *user __attribute__((unused)))
539    {
540        CameraHeapMemory *mem;
541        if (fd < 0)
542            mem = new CameraHeapMemory(buf_size, num_bufs);
543        else
544            mem = new CameraHeapMemory(fd, buf_size, num_bufs);
545        mem->incStrong(mem);
546        return &mem->handle;
547    }
548
549    static void __put_memory(camera_memory_t *data)
550    {
551        if (!data)
552            return;
553
554        CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
555        mem->decStrong(mem);
556    }
557
558    static ANativeWindow *__to_anw(void *user)
559    {
560        CameraHardwareInterface *__this =
561                reinterpret_cast<CameraHardwareInterface *>(user);
562        return __this->mPreviewWindow.get();
563    }
564#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
565
566    static int __dequeue_buffer(struct preview_stream_ops* w,
567                                buffer_handle_t** buffer, int *stride)
568    {
569        int rc;
570        ANativeWindow *a = anw(w);
571        ANativeWindowBuffer* anb;
572        rc = native_window_dequeue_buffer_and_wait(a, &anb);
573        if (!rc) {
574            *buffer = &anb->handle;
575            *stride = anb->stride;
576        }
577        return rc;
578    }
579
580#ifndef container_of
581#define container_of(ptr, type, member) ({                      \
582        const typeof(((type *) 0)->member) *__mptr = (ptr);     \
583        (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
584#endif
585
586    static int __lock_buffer(struct preview_stream_ops* w,
587                      buffer_handle_t* buffer)
588    {
589        ANativeWindow *a = anw(w);
590        return 0;
591    }
592
593    static int __enqueue_buffer(struct preview_stream_ops* w,
594                      buffer_handle_t* buffer)
595    {
596        ANativeWindow *a = anw(w);
597        return a->queueBuffer(a,
598                  container_of(buffer, ANativeWindowBuffer, handle), -1);
599    }
600
601    static int __cancel_buffer(struct preview_stream_ops* w,
602                      buffer_handle_t* buffer)
603    {
604        ANativeWindow *a = anw(w);
605        return a->cancelBuffer(a,
606                  container_of(buffer, ANativeWindowBuffer, handle), -1);
607    }
608
609    static int __set_buffer_count(struct preview_stream_ops* w, int count)
610    {
611        ANativeWindow *a = anw(w);
612        return native_window_set_buffer_count(a, count);
613    }
614
615    static int __set_buffers_geometry(struct preview_stream_ops* w,
616                      int width, int height, int format)
617    {
618        ANativeWindow *a = anw(w);
619        return native_window_set_buffers_geometry(a,
620                          width, height, format);
621    }
622
623    static int __set_crop(struct preview_stream_ops *w,
624                      int left, int top, int right, int bottom)
625    {
626        ANativeWindow *a = anw(w);
627        android_native_rect_t crop;
628        crop.left = left;
629        crop.top = top;
630        crop.right = right;
631        crop.bottom = bottom;
632        return native_window_set_crop(a, &crop);
633    }
634
635    static int __set_timestamp(struct preview_stream_ops *w,
636                               int64_t timestamp) {
637        ANativeWindow *a = anw(w);
638        return native_window_set_buffers_timestamp(a, timestamp);
639    }
640
641    static int __set_usage(struct preview_stream_ops* w, int usage)
642    {
643        ANativeWindow *a = anw(w);
644        return native_window_set_usage(a, usage);
645    }
646
647    static int __set_swap_interval(struct preview_stream_ops *w, int interval)
648    {
649        ANativeWindow *a = anw(w);
650        return a->setSwapInterval(a, interval);
651    }
652
653    static int __get_min_undequeued_buffer_count(
654                      const struct preview_stream_ops *w,
655                      int *count)
656    {
657        ANativeWindow *a = anw(w);
658        return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
659    }
660
661    void initHalPreviewWindow()
662    {
663        mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
664        mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
665        mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
666        mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
667        mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
668        mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
669        mHalPreviewWindow.nw.set_crop = __set_crop;
670        mHalPreviewWindow.nw.set_timestamp = __set_timestamp;
671        mHalPreviewWindow.nw.set_usage = __set_usage;
672        mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
673
674        mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
675                __get_min_undequeued_buffer_count;
676    }
677
678    sp<ANativeWindow>        mPreviewWindow;
679
680    struct camera_preview_window {
681        struct preview_stream_ops nw;
682        void *user;
683    };
684
685    struct camera_preview_window mHalPreviewWindow;
686
687    notify_callback         mNotifyCb;
688    data_callback           mDataCb;
689    data_callback_timestamp mDataCbTimestamp;
690    void *mCbUser;
691};
692
693};  // namespace android
694
695#endif
696