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 ¶ms) 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