/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <semaphore.h> #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <ui/DisplayInfo.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> #include <system/camera.h> #include <camera/Camera.h> #include <camera/ICamera.h> #include <camera/CameraParameters.h> #include <utils/RefBase.h> #include <binder/IPCThreadState.h> #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <cutils/properties.h> #include <cutils/memory.h> #include "qcamera_test.h" namespace qcamera { using namespace android; int CameraContext::JpegIdx = 0; /*=========================================================================== * FUNCTION : previewCallback * * DESCRIPTION: preview callback preview mesages are enabled * * PARAMETERS : * @mem : preview buffer * * RETURN : None *==========================================================================*/ void CameraContext::previewCallback(const sp<IMemory>& mem) { printf("PREVIEW Callback 0x%x", ( unsigned int ) mem->pointer()); uint8_t *ptr = (uint8_t*) mem->pointer(); printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9]); } /*=========================================================================== * FUNCTION : saveFile * * DESCRIPTION: helper function for saving buffers on filesystem * * PARAMETERS : * @mem : buffer to save to filesystem * @path: File path * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path) { unsigned char *buff = NULL; int size; int fd = -1; if (mem == NULL) { return BAD_VALUE; } fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0655); if(fd < 0) { printf("Unable to open file %s %s\n", path.string(), strerror(fd)); return -errno; } size = mem->size(); if (size <= 0) { printf("IMemory object is of zero size\n"); close(fd); return BAD_VALUE; } buff = (unsigned char *)mem->pointer(); if (!buff) { printf("Buffer pointer is invalid\n"); close(fd); return BAD_VALUE; } if ( size != write(fd, buff, size) ) { printf("Bad Write error (%d)%s\n", errno, strerror(errno)); close(fd); return INVALID_OPERATION; } printf("%s: buffer=%08X, size=%d stored at %s\n", __FUNCTION__, (int)buff, size, path.string()); if (fd >= 0) close(fd); return NO_ERROR; } /*=========================================================================== * FUNCTION : notify * * DESCRIPTION: notify callback * * PARAMETERS : * @msgType : type of callback * @ext1: extended parameters * @ext2: extended parameters * * RETURN : None *==========================================================================*/ void CameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2) { printf("Notify cb: %d %d %d\n", msgType, ext1, ext2); if ( msgType & CAMERA_MSG_FOCUS ) { printf("AutoFocus %s \n", (ext1) ? "OK" : "FAIL"); } if ( msgType & CAMERA_MSG_SHUTTER ) { printf("Shutter done \n"); } if ( msgType & CAMERA_MSG_ERROR) { printf("Camera Test CAMERA_MSG_ERROR\n"); stopPreview(); closeCamera(); } } /*=========================================================================== * FUNCTION : postData * * DESCRIPTION: handles data callbacks * * PARAMETERS : * @msgType : type of callback * @dataPtr: buffer data * @metadata: additional metadata where available * * RETURN : None *==========================================================================*/ void CameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) { printf("Data cb: %d\n", msgType); if ( msgType & CAMERA_MSG_PREVIEW_FRAME ) { previewCallback(dataPtr); } if ( msgType & CAMERA_MSG_RAW_IMAGE ) { printf("RAW done \n"); } if (msgType & CAMERA_MSG_POSTVIEW_FRAME) { printf("Postview frame \n"); } if (msgType & CAMERA_MSG_COMPRESSED_IMAGE ) { printf("JPEG done\n"); String8 jpegPath; jpegPath = jpegPath.format("/sdcard/img_%d.jpg", JpegIdx); saveFile(dataPtr, jpegPath); JpegIdx++; } if ( ( msgType & CAMERA_MSG_PREVIEW_METADATA ) && ( NULL != metadata ) ) { printf("Face detected %d \n", metadata->number_of_faces); } } /*=========================================================================== * FUNCTION : postDataTimestamp * * DESCRIPTION: handles recording callbacks * * PARAMETERS : * @timestamp : timestamp of buffer * @msgType : type of buffer * @dataPtr : buffer data * * RETURN : None *==========================================================================*/ void CameraContext::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { printf("Recording cb: %d %lld %p\n", msgType, timestamp, dataPtr.get()); } /*=========================================================================== * FUNCTION : printSupportedParams * * DESCRIPTION: dump common supported parameters * * PARAMETERS : None * * RETURN : None *==========================================================================*/ void CameraContext::printSupportedParams() { printf("\n\r\tSupported Cameras: %s", mParams.get("camera-indexes")? mParams.get("camera-indexes") : "NULL"); printf("\n\r\tSupported Picture Sizes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES)? mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES) : "NULL"); printf("\n\r\tSupported Picture Formats: %s", mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)? mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS) : "NULL"); printf("\n\r\tSupported Preview Sizes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES)? mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES) : "NULL"); printf("\n\r\tSupported Preview Formats: %s", mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS)? mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS) : "NULL"); printf("\n\r\tSupported Preview Frame Rates: %s", mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)? mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES) : "NULL"); printf("\n\r\tSupported Thumbnail Sizes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES)? mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES) : "NULL"); printf("\n\r\tSupported Whitebalance Modes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE)? mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE) : "NULL"); printf("\n\r\tSupported Effects: %s", mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS)? mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS) : "NULL"); printf("\n\r\tSupported Scene Modes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES)? mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES) : "NULL"); printf("\n\r\tSupported Focus Modes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES)? mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES) : "NULL"); printf("\n\r\tSupported Antibanding Options: %s", mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING)? mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING) : "NULL"); printf("\n\r\tSupported Flash Modes: %s", mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES)? mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES) : "NULL"); printf("\n\r\tSupported Focus Areas: %d", mParams.getInt(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS)); printf("\n\r\tSupported FPS ranges : %s", mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE)? mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE) : "NULL"); printf("\n\r\tFocus Distances: %s \n", mParams.get(CameraParameters::KEY_FOCUS_DISTANCES)? mParams.get(CameraParameters::KEY_FOCUS_DISTANCES) : "NULL"); } /*=========================================================================== * FUNCTION : createPreviewSurface * * DESCRIPTION: helper function for creating preview surfaces * * PARAMETERS : * @width : preview width * @height: preview height * @pixFormat : surface pixelformat * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::createPreviewSurface(unsigned int width, unsigned int height, int32_t pixFormat) { int ret = NO_ERROR; DisplayInfo dinfo; sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( ISurfaceComposer::eDisplayIdMain)); SurfaceComposerClient::getDisplayInfo(display, &dinfo); unsigned int previewWidth, previewHeight; if ( dinfo.w < width ) { previewWidth = dinfo.w; } else { previewWidth = width; } if ( dinfo.h < height ) { previewHeight = dinfo.h; } else { previewHeight = height; } mClient = new SurfaceComposerClient(); if ( NULL == mClient.get() ) { printf("Unable to establish connection to Surface Composer \n"); return NO_INIT; } mSurfaceControl = mClient->createSurface(String8("QCamera_Test"), previewWidth, previewHeight, pixFormat, 0); if ( NULL == mSurfaceControl.get() ) { printf("Unable to create preview surface \n"); return NO_INIT; } mPreviewSurface = mSurfaceControl->getSurface(); if ( NULL != mPreviewSurface.get() ) { mClient->openGlobalTransaction(); ret |= mSurfaceControl->setLayer(0x7fffffff); ret |= mSurfaceControl->setPosition(0, 0); ret |= mSurfaceControl->setSize(previewWidth, previewHeight); ret |= mSurfaceControl->show(); mClient->closeGlobalTransaction(); if ( NO_ERROR != ret ) { printf("Preview surface configuration failed! \n"); } } else { ret = NO_INIT; } return ret; } /*=========================================================================== * FUNCTION : destroyPreviewSurface * * DESCRIPTION: closes previously open preview surface * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::destroyPreviewSurface() { if ( NULL != mPreviewSurface.get() ) { mPreviewSurface.clear(); } if ( NULL != mSurfaceControl.get() ) { mSurfaceControl->clear(); mSurfaceControl.clear(); } if ( NULL != mClient.get() ) { mClient->dispose(); mClient.clear(); } return NO_ERROR; } /*=========================================================================== * FUNCTION : ~CameraContext * * DESCRIPTION: camera context destructor * * PARAMETERS : None * * RETURN : None *==========================================================================*/ CameraContext::~CameraContext() { stopPreview(); closeCamera(); } /*=========================================================================== * FUNCTION : openCamera * * DESCRIPTION: connects to and initializes camera * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::openCamera() { if ( NULL != mCamera.get() ) { printf("Camera already open! \n"); return NO_ERROR; } printf("openCamera(camera_index=%d)\n", mCameraIndex); mCamera = Camera::connect(mCameraIndex); if ( NULL == mCamera.get() ) { printf("Unable to connect to CameraService\n"); return NO_INIT; } mParams = mCamera->getParameters(); mParams.getSupportedPreviewSizes(mSupportedPreviewSizes); mParams.getSupportedPictureSizes(mSupportedPictureSizes); mCurrentPictureSizeIdx = mSupportedPictureSizes.size() / 2; mCurrentPreviewSizeIdx = mSupportedPreviewSizes.size() / 2; mCamera->setListener(this); mHardwareActive = true; return NO_ERROR; } /*=========================================================================== * FUNCTION : getNumberOfCameras * * DESCRIPTION: returns the number of supported camera by the system * * PARAMETERS : None * * RETURN : supported camera count *==========================================================================*/ int CameraContext::getNumberOfCameras() { int ret = -1; if ( NULL != mCamera.get() ) { ret = mCamera->getNumberOfCameras(); } return ret; } /*=========================================================================== * FUNCTION : closeCamera * * DESCRIPTION: closes a previously the initialized camera reference * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::closeCamera() { if ( NULL == mCamera.get() ) { return NO_INIT; } mCamera->disconnect(); mCamera.clear(); mHardwareActive = false; mPreviewRunning = false; return NO_ERROR; } /*=========================================================================== * FUNCTION : startPreview * * DESCRIPTION: starts camera preview * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::startPreview() { int ret = NO_ERROR; int previewWidth, previewHeight; Size currentPreviewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx); Size currentPictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx); if ( mPreviewRunning || !mHardwareActive ) { printf("Preview already running or camera not active! \n"); return NO_INIT; } if (mResizePreview) { previewWidth = currentPreviewSize.width; previewHeight = currentPreviewSize.height; ret = createPreviewSurface(previewWidth, previewHeight, HAL_PIXEL_FORMAT_YCrCb_420_SP); if ( NO_ERROR != ret ) { printf("Error while creating preview surface\n"); return ret; } mParams.setPreviewSize(previewWidth, previewHeight); mParams.setPictureSize(currentPictureSize.width, currentPictureSize.height); ret |= mCamera->setParameters(mParams.flatten()); ret |= mCamera->setPreviewDisplay(mPreviewSurface); ret |= mCamera->startPreview(); if ( NO_ERROR != ret ) { printf("Preview start failed! \n"); return ret; } mPreviewRunning = true; mResizePreview = false; } return ret; } /*=========================================================================== * FUNCTION : autoFocus * * DESCRIPTION: Triggers autofocus * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::autoFocus() { status_t ret = NO_ERROR; if ( mPreviewRunning ) { ret = mCamera->autoFocus(); } return ret; } /*=========================================================================== * FUNCTION : enablePreviewCallbacks * * DESCRIPTION: Enables preview callback messages * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::enablePreviewCallbacks() { if ( mHardwareActive ) { mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); } return NO_ERROR; } /*=========================================================================== * FUNCTION : takePicture * * DESCRIPTION: triggers image capture * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::takePicture() { status_t ret = NO_ERROR; if ( mPreviewRunning ) { ret = mCamera->takePicture(CAMERA_MSG_COMPRESSED_IMAGE|CAMERA_MSG_RAW_IMAGE); } return ret; } /*=========================================================================== * FUNCTION : stopPreview * * DESCRIPTION: stops camera preview * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::stopPreview() { status_t ret = NO_ERROR; if ( mHardwareActive ) { mCamera->stopPreview(); ret = destroyPreviewSurface(); } mPreviewRunning = false; mResizePreview = true; return ret; } /*=========================================================================== * FUNCTION : resumePreview * * DESCRIPTION: resumes camera preview after image capture * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::resumePreview() { status_t ret = NO_ERROR; if ( mHardwareActive ) { ret = mCamera->startPreview(); } else { ret = NO_INIT; } return ret; } /*=========================================================================== * FUNCTION : nextPreviewSize * * DESCRIPTION: Iterates through all supported preview sizes. * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::nextPreviewSize() { if ( mHardwareActive ) { mCurrentPreviewSizeIdx += 1; mCurrentPreviewSizeIdx %= mSupportedPreviewSizes.size(); Size previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx); mParams.setPreviewSize(previewSize.width, previewSize.height); mResizePreview = true; if ( mPreviewRunning ) { mCamera->stopPreview(); mCamera->setParameters(mParams.flatten()); mCamera->startPreview(); } else { mCamera->setParameters(mParams.flatten()); } } return NO_ERROR; } /*=========================================================================== * FUNCTION : getCurrentPreviewSize * * DESCRIPTION: queries the currently configured preview size * * PARAMETERS : * @previewSize : preview size currently configured * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::getCurrentPreviewSize(Size &previewSize) { if ( mHardwareActive ) { previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx); } return NO_ERROR; } /*=========================================================================== * FUNCTION : nextPictureSize * * DESCRIPTION: Iterates through all supported picture sizes. * * PARAMETERS : None * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::nextPictureSize() { if ( mHardwareActive ) { mCurrentPictureSizeIdx += 1; mCurrentPictureSizeIdx %= mSupportedPictureSizes.size(); Size pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx); mParams.setPictureSize(pictureSize.width, pictureSize.height); mCamera->setParameters(mParams.flatten()); } return NO_ERROR; } /*=========================================================================== * FUNCTION : getCurrentPictureSize * * DESCRIPTION: queries the currently configured picture size * * PARAMETERS : * @pictureSize : picture size currently configured * * RETURN : status_t type of status * NO_ERROR -- success * none-zero failure code *==========================================================================*/ status_t CameraContext::getCurrentPictureSize(Size &pictureSize) { if ( mHardwareActive ) { pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx); } return NO_ERROR; } }; //namespace qcamera ends here using namespace qcamera; /*=========================================================================== * FUNCTION : printMenu * * DESCRIPTION: prints the available camera options * * PARAMETERS : * @currentCamera : camera context currently being used * * RETURN : None *==========================================================================*/ void printMenu(sp<CameraContext> currentCamera) { Size currentPictureSize, currentPreviewSize; assert(currentCamera.get()); currentCamera->getCurrentPictureSize(currentPictureSize); currentCamera->getCurrentPreviewSize(currentPreviewSize); printf("\n\n=========== FUNCTIONAL TEST MENU ===================\n\n"); printf(" \n\nSTART / STOP / GENERAL SERVICES \n"); printf(" -----------------------------\n"); printf(" %c. Switch camera - Current Index: %d\n", SWITCH_CAMERA_CMD, currentCamera->getCameraIndex()); printf(" %c. Resume Preview after capture \n", RESUME_PREVIEW_CMD); printf(" %c. Quit \n", EXIT_CMD); printf(" %c. Camera Capability Dump", DUMP_CAPS_CMD); printf(" \n\n PREVIEW SUB MENU \n"); printf(" -----------------------------\n"); printf(" %c. Start Preview\n", START_PREVIEW_CMD); printf(" %c. Stop Preview\n", STOP_PREVIEW_CMD); printf(" %c. Preview size: %dx%d\n", CHANGE_PREVIEW_SIZE_CMD, currentPreviewSize.width, currentPreviewSize.height); printf(" %c. Enable preview frames\n", ENABLE_PRV_CALLBACKS_CMD); printf(" %c. Trigger autofocus \n", AUTOFOCUS_CMD); printf(" \n\n IMAGE CAPTURE SUB MENU \n"); printf(" -----------------------------\n"); printf(" %c. Take picture/Full Press\n", TAKEPICTURE_CMD); printf(" %c. Picture size: %dx%d\n", CHANGE_PICTURE_SIZE_CMD, currentPictureSize.width, currentPictureSize.height); printf("\n"); printf(" Choice: "); } /*=========================================================================== * FUNCTION : functionalTest * * DESCRIPTION: queries and executes client supplied commands for testing a * particular camera. * * PARAMETERS : * @availableCameras : List with all cameras supported * * RETURN : status_t type of status * NO_ERROR -- continue testing * none-zero -- quit test *==========================================================================*/ status_t functionalTest(Vector< sp<CameraContext> > &availableCameras) { int cmd; status_t stat = NO_ERROR; static int currentCameraIdx = 0; assert(availableCameras.size()); sp<CameraContext> currentCamera = availableCameras.itemAt(currentCameraIdx); printMenu(currentCamera); cmd = getchar(); switch (cmd) { case SWITCH_CAMERA_CMD: { currentCameraIdx++; currentCameraIdx %= availableCameras.size(); currentCamera = availableCameras.itemAt(currentCameraIdx); } break; case RESUME_PREVIEW_CMD: { stat = currentCamera->resumePreview(); } break; case START_PREVIEW_CMD: { stat = currentCamera->startPreview(); } break; case STOP_PREVIEW_CMD: { stat = currentCamera->stopPreview(); } break; case CHANGE_PREVIEW_SIZE_CMD: { stat = currentCamera->nextPreviewSize(); } break; case CHANGE_PICTURE_SIZE_CMD: { stat = currentCamera->nextPictureSize(); } break; case DUMP_CAPS_CMD: { currentCamera->printSupportedParams(); } break; case AUTOFOCUS_CMD: { stat = currentCamera->autoFocus(); } break; case TAKEPICTURE_CMD: { stat = currentCamera->takePicture(); } break; case ENABLE_PRV_CALLBACKS_CMD: { stat = currentCamera->enablePreviewCallbacks(); } break; case EXIT_CMD: { currentCamera->stopPreview(); return -1; } break; default: { } break; } printf("Command status 0x%x \n", stat); return NO_ERROR; } int main() { sp<ProcessState> proc(ProcessState::self()); Vector< sp<CameraContext> > availableCameras; sp<CameraContext> camera; int i = 0; ProcessState::self()->startThreadPool(); do { camera = new CameraContext(i); if ( NULL == camera.get() ) { return NO_INIT; } status_t stat = camera->openCamera(); if ( NO_ERROR != stat ) { printf("Error encountered during camera open \n"); return stat; } availableCameras.add(camera); i++; } while ( i < camera->getNumberOfCameras() ) ; while ( true ) { if ( NO_ERROR != functionalTest(availableCameras) ) { break; } }; for ( size_t j = 0 ; j < availableCameras.size() ; j++ ) { camera = availableCameras.itemAt(j); camera->closeCamera(); camera.clear(); } availableCameras.clear(); return 0; }