1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include <stdlib.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <time.h>
34#include <semaphore.h>
35#include <pthread.h>
36
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <sys/wait.h>
40
41#include <ui/DisplayInfo.h>
42#include <gui/Surface.h>
43#include <gui/SurfaceComposerClient.h>
44#include <gui/ISurfaceComposer.h>
45
46#include <system/camera.h>
47#include <camera/Camera.h>
48#include <camera/ICamera.h>
49#include <camera/CameraParameters.h>
50
51#include <utils/RefBase.h>
52#include <binder/IPCThreadState.h>
53#include <binder/ProcessState.h>
54#include <binder/IServiceManager.h>
55#include <cutils/properties.h>
56#include <cutils/memory.h>
57
58#include "qcamera_test.h"
59
60namespace qcamera {
61
62using namespace android;
63
64int CameraContext::JpegIdx = 0;
65
66/*===========================================================================
67 * FUNCTION   : previewCallback
68 *
69 * DESCRIPTION: preview callback preview mesages are enabled
70 *
71 * PARAMETERS :
72 *   @mem : preview buffer
73 *
74 * RETURN     : None
75 *==========================================================================*/
76void CameraContext::previewCallback(const sp<IMemory>& mem)
77{
78    printf("PREVIEW Callback 0x%x", ( unsigned int ) mem->pointer());
79    uint8_t *ptr = (uint8_t*) mem->pointer();
80    printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
81           ptr[0],
82           ptr[1],
83           ptr[2],
84           ptr[3],
85           ptr[4],
86           ptr[5],
87           ptr[6],
88           ptr[7],
89           ptr[8],
90           ptr[9]);
91}
92
93/*===========================================================================
94 * FUNCTION   : saveFile
95 *
96 * DESCRIPTION: helper function for saving buffers on filesystem
97 *
98 * PARAMETERS :
99 *   @mem : buffer to save to filesystem
100 *   @path: File path
101 *
102 * RETURN     : status_t type of status
103 *              NO_ERROR  -- success
104 *              none-zero failure code
105 *==========================================================================*/
106status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path)
107{
108    unsigned char *buff = NULL;
109    int size;
110    int fd = -1;
111
112    if (mem == NULL) {
113        return BAD_VALUE;
114    }
115
116    fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0655);
117    if(fd < 0) {
118        printf("Unable to open file %s %s\n", path.string(), strerror(fd));
119        return -errno;
120    }
121
122    size = mem->size();
123    if (size <= 0) {
124        printf("IMemory object is of zero size\n");
125        close(fd);
126        return BAD_VALUE;
127    }
128
129    buff = (unsigned char *)mem->pointer();
130    if (!buff) {
131        printf("Buffer pointer is invalid\n");
132        close(fd);
133        return BAD_VALUE;
134    }
135
136    if ( size != write(fd, buff, size) ) {
137        printf("Bad Write error (%d)%s\n",
138               errno,
139               strerror(errno));
140        close(fd);
141        return INVALID_OPERATION;
142    }
143
144    printf("%s: buffer=%08X, size=%d stored at %s\n",
145           __FUNCTION__, (int)buff, size, path.string());
146
147    if (fd >= 0)
148        close(fd);
149
150    return NO_ERROR;
151}
152
153/*===========================================================================
154 * FUNCTION   : notify
155 *
156 * DESCRIPTION: notify callback
157 *
158 * PARAMETERS :
159 *   @msgType : type of callback
160 *   @ext1: extended parameters
161 *   @ext2: extended parameters
162 *
163 * RETURN     : None
164 *==========================================================================*/
165void CameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2)
166{
167    printf("Notify cb: %d %d %d\n", msgType, ext1, ext2);
168
169    if ( msgType & CAMERA_MSG_FOCUS ) {
170        printf("AutoFocus %s \n",
171               (ext1) ? "OK" : "FAIL");
172    }
173
174    if ( msgType & CAMERA_MSG_SHUTTER ) {
175        printf("Shutter done \n");
176    }
177
178    if ( msgType & CAMERA_MSG_ERROR) {
179        printf("Camera Test CAMERA_MSG_ERROR\n");
180        stopPreview();
181        closeCamera();
182    }
183}
184
185/*===========================================================================
186 * FUNCTION   : postData
187 *
188 * DESCRIPTION: handles data callbacks
189 *
190 * PARAMETERS :
191 *   @msgType : type of callback
192 *   @dataPtr: buffer data
193 *   @metadata: additional metadata where available
194 *
195 * RETURN     : None
196 *==========================================================================*/
197void CameraContext::postData(int32_t msgType,
198                             const sp<IMemory>& dataPtr,
199                             camera_frame_metadata_t *metadata)
200{
201    printf("Data cb: %d\n", msgType);
202
203    if ( msgType & CAMERA_MSG_PREVIEW_FRAME ) {
204        previewCallback(dataPtr);
205    }
206
207    if ( msgType & CAMERA_MSG_RAW_IMAGE ) {
208        printf("RAW done \n");
209    }
210
211    if (msgType & CAMERA_MSG_POSTVIEW_FRAME) {
212        printf("Postview frame \n");
213    }
214
215    if (msgType & CAMERA_MSG_COMPRESSED_IMAGE ) {
216        printf("JPEG done\n");
217        String8 jpegPath;
218        jpegPath = jpegPath.format("/sdcard/img_%d.jpg", JpegIdx);
219        saveFile(dataPtr, jpegPath);
220        JpegIdx++;
221    }
222
223    if ( ( msgType & CAMERA_MSG_PREVIEW_METADATA ) &&
224         ( NULL != metadata ) ) {
225        printf("Face detected %d \n", metadata->number_of_faces);
226    }
227}
228
229/*===========================================================================
230 * FUNCTION   : postDataTimestamp
231 *
232 * DESCRIPTION: handles recording callbacks
233 *
234 * PARAMETERS :
235 *   @timestamp : timestamp of buffer
236 *   @msgType : type of buffer
237 *   @dataPtr : buffer data
238 *
239 * RETURN     : None
240 *==========================================================================*/
241void CameraContext::postDataTimestamp(nsecs_t timestamp,
242                                      int32_t msgType,
243                                      const sp<IMemory>& dataPtr)
244{
245    printf("Recording cb: %d %lld %p\n", msgType, timestamp, dataPtr.get());
246}
247
248/*===========================================================================
249 * FUNCTION   : printSupportedParams
250 *
251 * DESCRIPTION: dump common supported parameters
252 *
253 * PARAMETERS : None
254 *
255 * RETURN     : None
256 *==========================================================================*/
257void CameraContext::printSupportedParams()
258{
259    printf("\n\r\tSupported Cameras: %s",
260           mParams.get("camera-indexes")? mParams.get("camera-indexes") : "NULL");
261    printf("\n\r\tSupported Picture Sizes: %s",
262           mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES)?
263           mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES) : "NULL");
264    printf("\n\r\tSupported Picture Formats: %s",
265           mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)?
266           mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS) : "NULL");
267    printf("\n\r\tSupported Preview Sizes: %s",
268           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES)?
269           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES) : "NULL");
270    printf("\n\r\tSupported Preview Formats: %s",
271           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS)?
272           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS) : "NULL");
273    printf("\n\r\tSupported Preview Frame Rates: %s",
274           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)?
275           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES) : "NULL");
276    printf("\n\r\tSupported Thumbnail Sizes: %s",
277           mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES)?
278           mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES) : "NULL");
279    printf("\n\r\tSupported Whitebalance Modes: %s",
280           mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE)?
281           mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE) : "NULL");
282    printf("\n\r\tSupported Effects: %s",
283           mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS)?
284           mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS) : "NULL");
285    printf("\n\r\tSupported Scene Modes: %s",
286           mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES)?
287           mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES) : "NULL");
288    printf("\n\r\tSupported Focus Modes: %s",
289           mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES)?
290           mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES) : "NULL");
291    printf("\n\r\tSupported Antibanding Options: %s",
292           mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING)?
293           mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING) : "NULL");
294    printf("\n\r\tSupported Flash Modes: %s",
295           mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES)?
296           mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES) : "NULL");
297    printf("\n\r\tSupported Focus Areas: %d",
298           mParams.getInt(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS));
299    printf("\n\r\tSupported FPS ranges : %s",
300           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE)?
301           mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE) : "NULL");
302    printf("\n\r\tFocus Distances: %s \n",
303           mParams.get(CameraParameters::KEY_FOCUS_DISTANCES)?
304           mParams.get(CameraParameters::KEY_FOCUS_DISTANCES) : "NULL");
305}
306
307/*===========================================================================
308 * FUNCTION   : createPreviewSurface
309 *
310 * DESCRIPTION: helper function for creating preview surfaces
311 *
312 * PARAMETERS :
313 *   @width : preview width
314 *   @height: preview height
315 *   @pixFormat : surface pixelformat
316 *
317 * RETURN     : status_t type of status
318 *              NO_ERROR  -- success
319 *              none-zero failure code
320 *==========================================================================*/
321status_t CameraContext::createPreviewSurface(unsigned int width,
322                                             unsigned int height,
323                                             int32_t pixFormat)
324{
325    int ret = NO_ERROR;
326    DisplayInfo dinfo;
327    sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
328                        ISurfaceComposer::eDisplayIdMain));
329    SurfaceComposerClient::getDisplayInfo(display, &dinfo);
330    unsigned int previewWidth, previewHeight;
331
332    if ( dinfo.w < width ) {
333        previewWidth = dinfo.w;
334    } else {
335        previewWidth = width;
336    }
337
338    if ( dinfo.h < height ) {
339        previewHeight = dinfo.h;
340    } else {
341        previewHeight = height;
342    }
343
344    mClient = new SurfaceComposerClient();
345
346    if ( NULL == mClient.get() ) {
347        printf("Unable to establish connection to Surface Composer \n");
348        return NO_INIT;
349    }
350
351    mSurfaceControl = mClient->createSurface(String8("QCamera_Test"),
352                                             previewWidth,
353                                             previewHeight,
354                                             pixFormat,
355                                             0);
356    if ( NULL == mSurfaceControl.get() ) {
357        printf("Unable to create preview surface \n");
358        return NO_INIT;
359    }
360
361    mPreviewSurface = mSurfaceControl->getSurface();
362    if ( NULL != mPreviewSurface.get() ) {
363        mClient->openGlobalTransaction();
364        ret |= mSurfaceControl->setLayer(0x7fffffff);
365        ret |= mSurfaceControl->setPosition(0, 0);
366        ret |= mSurfaceControl->setSize(previewWidth, previewHeight);
367        ret |= mSurfaceControl->show();
368        mClient->closeGlobalTransaction();
369
370        if ( NO_ERROR != ret ) {
371            printf("Preview surface configuration failed! \n");
372        }
373    } else {
374        ret = NO_INIT;
375    }
376
377    return ret;
378}
379
380/*===========================================================================
381 * FUNCTION   : destroyPreviewSurface
382 *
383 * DESCRIPTION: closes previously open preview surface
384 *
385 * PARAMETERS : None
386 *
387 * RETURN     : status_t type of status
388 *              NO_ERROR  -- success
389 *              none-zero failure code
390 *==========================================================================*/
391status_t CameraContext::destroyPreviewSurface()
392{
393    if ( NULL != mPreviewSurface.get() ) {
394        mPreviewSurface.clear();
395    }
396
397    if ( NULL != mSurfaceControl.get() ) {
398        mSurfaceControl->clear();
399        mSurfaceControl.clear();
400    }
401
402    if ( NULL != mClient.get() ) {
403        mClient->dispose();
404        mClient.clear();
405    }
406
407    return NO_ERROR;
408}
409
410/*===========================================================================
411 * FUNCTION   : ~CameraContext
412 *
413 * DESCRIPTION: camera context destructor
414 *
415 * PARAMETERS : None
416 *
417 * RETURN     : None
418 *==========================================================================*/
419CameraContext::~CameraContext()
420{
421    stopPreview();
422    closeCamera();
423}
424
425/*===========================================================================
426 * FUNCTION   : openCamera
427 *
428 * DESCRIPTION: connects to and initializes camera
429 *
430 * PARAMETERS : None
431 *
432 * RETURN     : status_t type of status
433 *              NO_ERROR  -- success
434 *              none-zero failure code
435 *==========================================================================*/
436status_t  CameraContext::openCamera()
437{
438    if ( NULL != mCamera.get() ) {
439        printf("Camera already open! \n");
440        return NO_ERROR;
441    }
442
443    printf("openCamera(camera_index=%d)\n", mCameraIndex);
444    mCamera = Camera::connect(mCameraIndex);
445
446    if ( NULL == mCamera.get() ) {
447        printf("Unable to connect to CameraService\n");
448        return NO_INIT;
449    }
450
451    mParams = mCamera->getParameters();
452    mParams.getSupportedPreviewSizes(mSupportedPreviewSizes);
453    mParams.getSupportedPictureSizes(mSupportedPictureSizes);
454    mCurrentPictureSizeIdx = mSupportedPictureSizes.size() / 2;
455    mCurrentPreviewSizeIdx = mSupportedPreviewSizes.size() / 2;
456
457    mCamera->setListener(this);
458    mHardwareActive = true;
459
460    return NO_ERROR;
461}
462
463/*===========================================================================
464 * FUNCTION   : getNumberOfCameras
465 *
466 * DESCRIPTION: returns the number of supported camera by the system
467 *
468 * PARAMETERS : None
469 *
470 * RETURN     : supported camera count
471 *==========================================================================*/
472int CameraContext::getNumberOfCameras()
473{
474    int ret = -1;
475
476    if ( NULL != mCamera.get() ) {
477        ret = mCamera->getNumberOfCameras();
478    }
479
480    return ret;
481}
482
483/*===========================================================================
484 * FUNCTION   : closeCamera
485 *
486 * DESCRIPTION: closes a previously the initialized camera reference
487 *
488 * PARAMETERS : None
489 *
490 * RETURN     : status_t type of status
491 *              NO_ERROR  -- success
492 *              none-zero failure code
493 *==========================================================================*/
494status_t CameraContext::closeCamera()
495{
496    if ( NULL == mCamera.get() ) {
497        return NO_INIT;
498    }
499
500    mCamera->disconnect();
501    mCamera.clear();
502    mHardwareActive = false;
503    mPreviewRunning = false;
504
505    return NO_ERROR;
506}
507
508/*===========================================================================
509 * FUNCTION   : startPreview
510 *
511 * DESCRIPTION: starts camera preview
512 *
513 * PARAMETERS : None
514 *
515 * RETURN     : status_t type of status
516 *              NO_ERROR  -- success
517 *              none-zero failure code
518 *==========================================================================*/
519status_t CameraContext::startPreview()
520{
521    int ret = NO_ERROR;
522    int previewWidth, previewHeight;
523    Size currentPreviewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
524    Size currentPictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
525
526    if ( mPreviewRunning || !mHardwareActive ) {
527        printf("Preview already running or camera not active! \n");
528        return NO_INIT;
529    }
530
531    if (mResizePreview) {
532        previewWidth = currentPreviewSize.width;
533        previewHeight = currentPreviewSize.height;
534
535        ret = createPreviewSurface(previewWidth,
536                                   previewHeight,
537                                   HAL_PIXEL_FORMAT_YCrCb_420_SP);
538        if (  NO_ERROR != ret ) {
539            printf("Error while creating preview surface\n");
540            return ret;
541        }
542
543        mParams.setPreviewSize(previewWidth, previewHeight);
544        mParams.setPictureSize(currentPictureSize.width, currentPictureSize.height);
545
546        ret |= mCamera->setParameters(mParams.flatten());
547        ret |= mCamera->setPreviewDisplay(mPreviewSurface);
548        ret |= mCamera->startPreview();
549        if ( NO_ERROR != ret ) {
550            printf("Preview start failed! \n");
551            return ret;
552        }
553
554        mPreviewRunning = true;
555        mResizePreview = false;
556    }
557
558    return ret;
559}
560
561/*===========================================================================
562 * FUNCTION   : autoFocus
563 *
564 * DESCRIPTION: Triggers autofocus
565 *
566 * PARAMETERS : None
567 *
568 * RETURN     : status_t type of status
569 *              NO_ERROR  -- success
570 *              none-zero failure code
571 *==========================================================================*/
572status_t CameraContext::autoFocus()
573{
574    status_t ret = NO_ERROR;
575
576    if ( mPreviewRunning ) {
577        ret = mCamera->autoFocus();
578    }
579
580    return ret;
581}
582
583/*===========================================================================
584 * FUNCTION   : enablePreviewCallbacks
585 *
586 * DESCRIPTION: Enables preview callback messages
587 *
588 * PARAMETERS : None
589 *
590 * RETURN     : status_t type of status
591 *              NO_ERROR  -- success
592 *              none-zero failure code
593 *==========================================================================*/
594status_t CameraContext::enablePreviewCallbacks()
595{
596    if ( mHardwareActive ) {
597        mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
598    }
599
600    return NO_ERROR;
601}
602
603/*===========================================================================
604 * FUNCTION   : takePicture
605 *
606 * DESCRIPTION: triggers image capture
607 *
608 * PARAMETERS : None
609 *
610 * RETURN     : status_t type of status
611 *              NO_ERROR  -- success
612 *              none-zero failure code
613 *==========================================================================*/
614status_t CameraContext::takePicture()
615{
616    status_t ret = NO_ERROR;
617
618    if ( mPreviewRunning ) {
619        ret = mCamera->takePicture(CAMERA_MSG_COMPRESSED_IMAGE|CAMERA_MSG_RAW_IMAGE);
620    }
621
622    return ret;
623}
624
625/*===========================================================================
626 * FUNCTION   : stopPreview
627 *
628 * DESCRIPTION: stops camera preview
629 *
630 * PARAMETERS : None
631 *
632 * RETURN     : status_t type of status
633 *              NO_ERROR  -- success
634 *              none-zero failure code
635 *==========================================================================*/
636status_t CameraContext::stopPreview()
637{
638    status_t ret = NO_ERROR;
639
640    if ( mHardwareActive ) {
641        mCamera->stopPreview();
642        ret = destroyPreviewSurface();
643    }
644
645    mPreviewRunning  = false;
646    mResizePreview = true;
647
648    return ret;
649}
650
651/*===========================================================================
652 * FUNCTION   : resumePreview
653 *
654 * DESCRIPTION: resumes camera preview after image capture
655 *
656 * PARAMETERS : None
657 *
658 * RETURN     : status_t type of status
659 *              NO_ERROR  -- success
660 *              none-zero failure code
661 *==========================================================================*/
662status_t CameraContext::resumePreview()
663{
664    status_t ret = NO_ERROR;
665
666    if ( mHardwareActive ) {
667        ret = mCamera->startPreview();
668    } else {
669        ret = NO_INIT;
670    }
671
672    return ret;
673}
674
675/*===========================================================================
676 * FUNCTION   : nextPreviewSize
677 *
678 * DESCRIPTION: Iterates through all supported preview sizes.
679 *
680 * PARAMETERS : None
681 *
682 * RETURN     : status_t type of status
683 *              NO_ERROR  -- success
684 *              none-zero failure code
685 *==========================================================================*/
686status_t CameraContext::nextPreviewSize()
687{
688    if ( mHardwareActive ) {
689        mCurrentPreviewSizeIdx += 1;
690        mCurrentPreviewSizeIdx %= mSupportedPreviewSizes.size();
691        Size previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
692        mParams.setPreviewSize(previewSize.width,
693                               previewSize.height);
694        mResizePreview = true;
695
696        if ( mPreviewRunning ) {
697            mCamera->stopPreview();
698            mCamera->setParameters(mParams.flatten());
699            mCamera->startPreview();
700        } else {
701            mCamera->setParameters(mParams.flatten());
702        }
703    }
704
705    return NO_ERROR;
706}
707
708/*===========================================================================
709 * FUNCTION   : getCurrentPreviewSize
710 *
711 * DESCRIPTION: queries the currently configured preview size
712 *
713 * PARAMETERS :
714 *  @previewSize : preview size currently configured
715 *
716 * RETURN     : status_t type of status
717 *              NO_ERROR  -- success
718 *              none-zero failure code
719 *==========================================================================*/
720status_t CameraContext::getCurrentPreviewSize(Size &previewSize)
721{
722    if ( mHardwareActive ) {
723        previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
724    }
725
726    return NO_ERROR;
727}
728
729/*===========================================================================
730 * FUNCTION   : nextPictureSize
731 *
732 * DESCRIPTION: Iterates through all supported picture sizes.
733 *
734 * PARAMETERS : None
735 *
736 * RETURN     : status_t type of status
737 *              NO_ERROR  -- success
738 *              none-zero failure code
739 *==========================================================================*/
740status_t CameraContext::nextPictureSize()
741{
742    if ( mHardwareActive ) {
743        mCurrentPictureSizeIdx += 1;
744        mCurrentPictureSizeIdx %= mSupportedPictureSizes.size();
745        Size pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
746        mParams.setPictureSize(pictureSize.width,
747                               pictureSize.height);
748        mCamera->setParameters(mParams.flatten());
749    }
750    return NO_ERROR;
751}
752
753/*===========================================================================
754 * FUNCTION   : getCurrentPictureSize
755 *
756 * DESCRIPTION: queries the currently configured picture size
757 *
758 * PARAMETERS :
759 *  @pictureSize : picture size currently configured
760 *
761 * RETURN     : status_t type of status
762 *              NO_ERROR  -- success
763 *              none-zero failure code
764 *==========================================================================*/
765status_t CameraContext::getCurrentPictureSize(Size &pictureSize)
766{
767    if ( mHardwareActive ) {
768        pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
769    }
770
771    return NO_ERROR;
772}
773
774}; //namespace qcamera ends here
775
776using namespace qcamera;
777
778/*===========================================================================
779 * FUNCTION   : printMenu
780 *
781 * DESCRIPTION: prints the available camera options
782 *
783 * PARAMETERS :
784 *  @currentCamera : camera context currently being used
785 *
786 * RETURN     : None
787 *==========================================================================*/
788void printMenu(sp<CameraContext> currentCamera)
789{
790    Size currentPictureSize, currentPreviewSize;
791
792    assert(currentCamera.get());
793
794    currentCamera->getCurrentPictureSize(currentPictureSize);
795    currentCamera->getCurrentPreviewSize(currentPreviewSize);
796
797    printf("\n\n=========== FUNCTIONAL TEST MENU ===================\n\n");
798
799    printf(" \n\nSTART / STOP / GENERAL SERVICES \n");
800    printf(" -----------------------------\n");
801    printf("   %c. Switch camera - Current Index: %d\n",
802            SWITCH_CAMERA_CMD,
803            currentCamera->getCameraIndex());
804    printf("   %c. Resume Preview after capture \n",
805            RESUME_PREVIEW_CMD);
806    printf("   %c. Quit \n",
807            EXIT_CMD);
808    printf("   %c. Camera Capability Dump",
809            DUMP_CAPS_CMD);
810
811    printf(" \n\n PREVIEW SUB MENU \n");
812    printf(" -----------------------------\n");
813    printf("   %c. Start Preview\n",
814            START_PREVIEW_CMD);
815    printf("   %c. Stop Preview\n",
816            STOP_PREVIEW_CMD);
817    printf("   %c. Preview size:  %dx%d\n",
818           CHANGE_PREVIEW_SIZE_CMD,
819           currentPreviewSize.width,
820           currentPreviewSize.height);
821    printf("   %c. Enable preview frames\n",
822            ENABLE_PRV_CALLBACKS_CMD);
823    printf("   %c. Trigger autofocus \n",
824            AUTOFOCUS_CMD);
825
826    printf(" \n\n IMAGE CAPTURE SUB MENU \n");
827    printf(" -----------------------------\n");
828    printf("   %c. Take picture/Full Press\n",
829            TAKEPICTURE_CMD);
830    printf("   %c. Picture size:  %dx%d\n",
831           CHANGE_PICTURE_SIZE_CMD,
832           currentPictureSize.width,
833           currentPictureSize.height);
834
835    printf("\n");
836    printf("   Choice: ");
837}
838
839/*===========================================================================
840 * FUNCTION   : functionalTest
841 *
842 * DESCRIPTION: queries and executes client supplied commands for testing a
843 *              particular camera.
844 *
845 * PARAMETERS :
846 *  @availableCameras : List with all cameras supported
847 *
848 * RETURN     : status_t type of status
849 *              NO_ERROR  -- continue testing
850 *              none-zero -- quit test
851 *==========================================================================*/
852status_t functionalTest(Vector< sp<CameraContext> > &availableCameras)
853{
854    int cmd;
855    status_t stat = NO_ERROR;
856    static int currentCameraIdx = 0;
857
858    assert(availableCameras.size());
859
860    sp<CameraContext> currentCamera = availableCameras.itemAt(currentCameraIdx);
861    printMenu(currentCamera);
862    cmd = getchar();
863
864    switch (cmd) {
865    case SWITCH_CAMERA_CMD:
866        {
867            currentCameraIdx++;
868            currentCameraIdx %= availableCameras.size();
869            currentCamera = availableCameras.itemAt(currentCameraIdx);
870        }
871        break;
872
873    case RESUME_PREVIEW_CMD:
874        {
875            stat = currentCamera->resumePreview();
876        }
877        break;
878
879    case START_PREVIEW_CMD:
880        {
881            stat = currentCamera->startPreview();
882        }
883        break;
884
885    case STOP_PREVIEW_CMD:
886        {
887            stat = currentCamera->stopPreview();
888        }
889        break;
890
891    case CHANGE_PREVIEW_SIZE_CMD:
892        {
893            stat = currentCamera->nextPreviewSize();
894        }
895        break;
896
897    case CHANGE_PICTURE_SIZE_CMD:
898        {
899            stat = currentCamera->nextPictureSize();
900        }
901        break;
902
903    case DUMP_CAPS_CMD:
904        {
905            currentCamera->printSupportedParams();
906        }
907        break;
908
909    case AUTOFOCUS_CMD:
910        {
911            stat = currentCamera->autoFocus();
912        }
913        break;
914
915    case TAKEPICTURE_CMD:
916        {
917            stat = currentCamera->takePicture();
918        }
919        break;
920
921    case ENABLE_PRV_CALLBACKS_CMD:
922        {
923            stat = currentCamera->enablePreviewCallbacks();
924        }
925        break;
926
927    case EXIT_CMD:
928        {
929            currentCamera->stopPreview();
930            return -1;
931        }
932
933        break;
934
935    default:
936        {
937        }
938        break;
939    }
940    printf("Command status 0x%x \n", stat);
941
942    return NO_ERROR;
943}
944
945int main()
946{
947    sp<ProcessState> proc(ProcessState::self());
948    Vector< sp<CameraContext> > availableCameras;
949    sp<CameraContext> camera;
950    int i = 0;
951
952    ProcessState::self()->startThreadPool();
953
954    do {
955        camera = new CameraContext(i);
956        if ( NULL == camera.get() ) {
957            return NO_INIT;
958        }
959
960        status_t stat = camera->openCamera();
961        if ( NO_ERROR != stat ) {
962            printf("Error encountered during camera open \n");
963            return stat;
964        }
965
966        availableCameras.add(camera);
967        i++;
968    } while ( i < camera->getNumberOfCameras() ) ;
969
970    while ( true ) {
971        if ( NO_ERROR != functionalTest(availableCameras) ) {
972            break;
973        }
974    };
975
976    for ( size_t j = 0 ; j < availableCameras.size() ; j++ ) {
977        camera = availableCameras.itemAt(j);
978        camera->closeCamera();
979        camera.clear();
980    }
981
982    availableCameras.clear();
983
984    return 0;
985}
986