Loading services/camera/libcameraservice/CameraFlashlight.cpp +250 −2 Original line number Diff line number Diff line Loading @@ -89,8 +89,9 @@ status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { mFlashControl = flashControl; } else { // todo: implement for device api 1 return INVALID_OPERATION; mFlashControl = new CameraHardwareInterfaceFlashControl(*mCameraModule, *mCallbacks); } } Loading Loading @@ -623,4 +624,251 @@ status_t CameraDeviceClientFlashControl::setTorchMode( } // CameraDeviceClientFlashControl implementation ends ///////////////////////////////////////////////////////////////////// // CameraHardwareInterfaceFlashControl implementation begins // Flash control for camera module <= v2.3 and camera HAL v1 ///////////////////////////////////////////////////////////////////// CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( CameraModule& cameraModule, const camera_module_callbacks_t& callbacks) : mCameraModule(&cameraModule), mCallbacks(&callbacks), mTorchEnabled(false) { } CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { disconnectCameraDevice(); mAnw.clear(); mSurfaceTexture.clear(); mProducer.clear(); mConsumer.clear(); if (mTorchEnabled) { if (mCallbacks) { ALOGV("%s: notify the framework that torch was turned off", __FUNCTION__); mCallbacks->torch_mode_status_change(mCallbacks, mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); } } } status_t CameraHardwareInterfaceFlashControl::setTorchMode( const String8& cameraId, bool enabled) { Mutex::Autolock l(mLock); // pre-check status_t res; if (enabled) { bool hasFlash = false; res = hasFlashUnitLocked(cameraId, &hasFlash); // invalid camera? if (res) { // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to // another camera device. return res == BAD_INDEX ? BAD_INDEX : -EINVAL; } // no flash unit? if (!hasFlash) { return -ENOSYS; } } else if (mDevice == NULL || cameraId != mCameraId) { // disabling the torch mode of an un-opened or different device. return OK; } else { // disabling the torch mode of currently opened device disconnectCameraDevice(); mTorchEnabled = false; mCallbacks->torch_mode_status_change(mCallbacks, cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); return OK; } res = startPreviewAndTorch(); if (res) { return res; } mTorchEnabled = true; mCallbacks->torch_mode_status_change(mCallbacks, cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); return OK; } status_t CameraHardwareInterfaceFlashControl::hasFlashUnit( const String8& cameraId, bool *hasFlash) { Mutex::Autolock l(mLock); return hasFlashUnitLocked(cameraId, hasFlash); } status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( const String8& cameraId, bool *hasFlash) { if (!hasFlash) { return BAD_VALUE; } status_t res; if (mDevice == NULL) { res = connectCameraDevice(cameraId); if (res) { return res; } } if (cameraId != mCameraId) { return BAD_INDEX; } const char *flashMode = mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { *hasFlash = true; } else { *hasFlash = false; } return OK; } status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { status_t res = OK; res = mDevice->startPreview(); if (res) { ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, strerror(-res), res); return res; } mParameters.set(CameraParameters::KEY_FLASH_MODE, CameraParameters::FLASH_MODE_TORCH); return mDevice->setParameters(mParameters); } status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( int32_t *width, int32_t *height) { if (!width || !height) { return BAD_VALUE; } int32_t w = INT32_MAX; int32_t h = 1; Vector<Size> sizes; mParameters.getSupportedPreviewSizes(sizes); for (size_t i = 0; i < sizes.size(); i++) { Size s = sizes[i]; if (w * h > s.width * s.height) { w = s.width; h = s.height; } } if (w == INT32_MAX) { return NAME_NOT_FOUND; } *width = w; *height = h; return OK; } status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( sp<CameraHardwareInterface> device, int32_t width, int32_t height) { status_t res; BufferQueue::createBufferQueue(&mProducer, &mConsumer); mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, true, true); if (mSurfaceTexture == NULL) { return NO_MEMORY; } int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; res = mSurfaceTexture->setDefaultBufferSize(width, height); if (res) { return res; } res = mSurfaceTexture->setDefaultBufferFormat(format); if (res) { return res; } mAnw = new Surface(mProducer, /*useAsync*/ true); if (mAnw == NULL) { return NO_MEMORY; } res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); if (res) { ALOGE("%s: Unable to connect to native window", __FUNCTION__); return res; } return device->setPreviewWindow(mAnw); } status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( const String8& cameraId) { sp<CameraHardwareInterface> device = new CameraHardwareInterface(cameraId.string()); status_t res = device->initialize(mCameraModule); if (res) { ALOGE("%s: initializing camera %s failed", __FUNCTION__, cameraId.string()); return res; } // need to set __get_memory in set_callbacks(). device->setCallbacks(NULL, NULL, NULL, NULL); mParameters = device->getParameters(); int32_t width, height; res = getSmallestSurfaceSize(&width, &height); if (res) { ALOGE("%s: failed to get smallest surface size for camera %s", __FUNCTION__, cameraId.string()); return res; } res = initializePreviewWindow(device, width, height); if (res) { ALOGE("%s: failed to initialize preview window for camera %s", __FUNCTION__, cameraId.string()); return res; } mCameraId = cameraId; mDevice = device; return OK; } status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { if (mDevice == NULL) { return OK; } mParameters.set(CameraParameters::KEY_FLASH_MODE, CameraParameters::FLASH_MODE_OFF); mDevice->setParameters(mParameters); mDevice->stopPreview(); status_t res = native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); if (res) { ALOGW("%s: native_window_api_disconnect failed: %s (%d)", __FUNCTION__, strerror(-res), res); } mDevice->setPreviewWindow(NULL); mDevice->release(); return OK; } // CameraHardwareInterfaceFlashControl implementation ends } services/camera/libcameraservice/CameraFlashlight.h +50 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "gui/GLConsumer.h" #include "gui/Surface.h" #include "common/CameraDeviceBase.h" #include "device1/CameraHardwareInterface.h" namespace android { Loading Loading @@ -147,6 +148,7 @@ class CameraDeviceClientFlashControl : public FlashControlBase { status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width, int32_t *height); // protected by mLock status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash); CameraModule *mCameraModule; Loading @@ -170,6 +172,54 @@ class CameraDeviceClientFlashControl : public FlashControlBase { Mutex mLock; }; /** * Flash control for camera module <= v2.3 and camera HAL v1 */ class CameraHardwareInterfaceFlashControl : public FlashControlBase { public: CameraHardwareInterfaceFlashControl(CameraModule& cameraModule, const camera_module_callbacks_t& callbacks); virtual ~CameraHardwareInterfaceFlashControl(); // FlashControlBase status_t setTorchMode(const String8& cameraId, bool enabled); status_t hasFlashUnit(const String8& cameraId, bool *hasFlash); private: // connect to a camera device status_t connectCameraDevice(const String8& cameraId); // disconnect and free mDevice status_t disconnectCameraDevice(); // initialize the preview window status_t initializePreviewWindow(sp<CameraHardwareInterface> device, int32_t width, int32_t height); // start preview and enable torch status_t startPreviewAndTorch(); // get the smallest surface status_t getSmallestSurfaceSize(int32_t *width, int32_t *height); // protected by mLock status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash); CameraModule *mCameraModule; const camera_module_callbacks_t *mCallbacks; sp<CameraHardwareInterface> mDevice; String8 mCameraId; CameraParameters mParameters; bool mTorchEnabled; sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; sp<GLConsumer> mSurfaceTexture; sp<ANativeWindow> mAnw; Mutex mLock; }; } // namespace android #endif services/camera/libcameraservice/CameraService.cpp +0 −13 Original line number Diff line number Diff line Loading @@ -496,19 +496,6 @@ int CameraService::getDeviceVersion(int cameraId, int* facing) { return deviceVersion; } status_t CameraService::filterOpenErrorCode(status_t err) { switch(err) { case NO_ERROR: case -EBUSY: case -EINVAL: case -EUSERS: return err; default: break; } return -ENODEV; } status_t CameraService::filterGetInfoErrorCode(status_t err) { switch(err) { case NO_ERROR: Loading services/camera/libcameraservice/CameraService.h +0 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,6 @@ public: ///////////////////////////////////////////////////////////////////// // Shared utilities static status_t filterOpenErrorCode(status_t err); static status_t filterGetInfoErrorCode(status_t err); ///////////////////////////////////////////////////////////////////// Loading services/camera/libcameraservice/common/CameraModule.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { } int CameraModule::open(const char* id, struct hw_device_t** device) { return mModule->common.methods->open(&mModule->common, id, device); return filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device)); } int CameraModule::openLegacy( Loading Loading @@ -125,5 +125,20 @@ int CameraModule::setTorchMode(const char* camera_id, bool enable) { return mModule->set_torch_mode(camera_id, enable); } status_t CameraModule::filterOpenErrorCode(status_t err) { switch(err) { case NO_ERROR: case -EBUSY: case -EINVAL: case -EUSERS: return err; default: break; } return -ENODEV; } }; // namespace android Loading
services/camera/libcameraservice/CameraFlashlight.cpp +250 −2 Original line number Diff line number Diff line Loading @@ -89,8 +89,9 @@ status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { mFlashControl = flashControl; } else { // todo: implement for device api 1 return INVALID_OPERATION; mFlashControl = new CameraHardwareInterfaceFlashControl(*mCameraModule, *mCallbacks); } } Loading Loading @@ -623,4 +624,251 @@ status_t CameraDeviceClientFlashControl::setTorchMode( } // CameraDeviceClientFlashControl implementation ends ///////////////////////////////////////////////////////////////////// // CameraHardwareInterfaceFlashControl implementation begins // Flash control for camera module <= v2.3 and camera HAL v1 ///////////////////////////////////////////////////////////////////// CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl( CameraModule& cameraModule, const camera_module_callbacks_t& callbacks) : mCameraModule(&cameraModule), mCallbacks(&callbacks), mTorchEnabled(false) { } CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() { disconnectCameraDevice(); mAnw.clear(); mSurfaceTexture.clear(); mProducer.clear(); mConsumer.clear(); if (mTorchEnabled) { if (mCallbacks) { ALOGV("%s: notify the framework that torch was turned off", __FUNCTION__); mCallbacks->torch_mode_status_change(mCallbacks, mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); } } } status_t CameraHardwareInterfaceFlashControl::setTorchMode( const String8& cameraId, bool enabled) { Mutex::Autolock l(mLock); // pre-check status_t res; if (enabled) { bool hasFlash = false; res = hasFlashUnitLocked(cameraId, &hasFlash); // invalid camera? if (res) { // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to // another camera device. return res == BAD_INDEX ? BAD_INDEX : -EINVAL; } // no flash unit? if (!hasFlash) { return -ENOSYS; } } else if (mDevice == NULL || cameraId != mCameraId) { // disabling the torch mode of an un-opened or different device. return OK; } else { // disabling the torch mode of currently opened device disconnectCameraDevice(); mTorchEnabled = false; mCallbacks->torch_mode_status_change(mCallbacks, cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); return OK; } res = startPreviewAndTorch(); if (res) { return res; } mTorchEnabled = true; mCallbacks->torch_mode_status_change(mCallbacks, cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); return OK; } status_t CameraHardwareInterfaceFlashControl::hasFlashUnit( const String8& cameraId, bool *hasFlash) { Mutex::Autolock l(mLock); return hasFlashUnitLocked(cameraId, hasFlash); } status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked( const String8& cameraId, bool *hasFlash) { if (!hasFlash) { return BAD_VALUE; } status_t res; if (mDevice == NULL) { res = connectCameraDevice(cameraId); if (res) { return res; } } if (cameraId != mCameraId) { return BAD_INDEX; } const char *flashMode = mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) { *hasFlash = true; } else { *hasFlash = false; } return OK; } status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() { status_t res = OK; res = mDevice->startPreview(); if (res) { ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__, strerror(-res), res); return res; } mParameters.set(CameraParameters::KEY_FLASH_MODE, CameraParameters::FLASH_MODE_TORCH); return mDevice->setParameters(mParameters); } status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize( int32_t *width, int32_t *height) { if (!width || !height) { return BAD_VALUE; } int32_t w = INT32_MAX; int32_t h = 1; Vector<Size> sizes; mParameters.getSupportedPreviewSizes(sizes); for (size_t i = 0; i < sizes.size(); i++) { Size s = sizes[i]; if (w * h > s.width * s.height) { w = s.width; h = s.height; } } if (w == INT32_MAX) { return NAME_NOT_FOUND; } *width = w; *height = h; return OK; } status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( sp<CameraHardwareInterface> device, int32_t width, int32_t height) { status_t res; BufferQueue::createBufferQueue(&mProducer, &mConsumer); mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL, true, true); if (mSurfaceTexture == NULL) { return NO_MEMORY; } int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; res = mSurfaceTexture->setDefaultBufferSize(width, height); if (res) { return res; } res = mSurfaceTexture->setDefaultBufferFormat(format); if (res) { return res; } mAnw = new Surface(mProducer, /*useAsync*/ true); if (mAnw == NULL) { return NO_MEMORY; } res = native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); if (res) { ALOGE("%s: Unable to connect to native window", __FUNCTION__); return res; } return device->setPreviewWindow(mAnw); } status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( const String8& cameraId) { sp<CameraHardwareInterface> device = new CameraHardwareInterface(cameraId.string()); status_t res = device->initialize(mCameraModule); if (res) { ALOGE("%s: initializing camera %s failed", __FUNCTION__, cameraId.string()); return res; } // need to set __get_memory in set_callbacks(). device->setCallbacks(NULL, NULL, NULL, NULL); mParameters = device->getParameters(); int32_t width, height; res = getSmallestSurfaceSize(&width, &height); if (res) { ALOGE("%s: failed to get smallest surface size for camera %s", __FUNCTION__, cameraId.string()); return res; } res = initializePreviewWindow(device, width, height); if (res) { ALOGE("%s: failed to initialize preview window for camera %s", __FUNCTION__, cameraId.string()); return res; } mCameraId = cameraId; mDevice = device; return OK; } status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() { if (mDevice == NULL) { return OK; } mParameters.set(CameraParameters::KEY_FLASH_MODE, CameraParameters::FLASH_MODE_OFF); mDevice->setParameters(mParameters); mDevice->stopPreview(); status_t res = native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); if (res) { ALOGW("%s: native_window_api_disconnect failed: %s (%d)", __FUNCTION__, strerror(-res), res); } mDevice->setPreviewWindow(NULL); mDevice->release(); return OK; } // CameraHardwareInterfaceFlashControl implementation ends }
services/camera/libcameraservice/CameraFlashlight.h +50 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "gui/GLConsumer.h" #include "gui/Surface.h" #include "common/CameraDeviceBase.h" #include "device1/CameraHardwareInterface.h" namespace android { Loading Loading @@ -147,6 +148,7 @@ class CameraDeviceClientFlashControl : public FlashControlBase { status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width, int32_t *height); // protected by mLock status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash); CameraModule *mCameraModule; Loading @@ -170,6 +172,54 @@ class CameraDeviceClientFlashControl : public FlashControlBase { Mutex mLock; }; /** * Flash control for camera module <= v2.3 and camera HAL v1 */ class CameraHardwareInterfaceFlashControl : public FlashControlBase { public: CameraHardwareInterfaceFlashControl(CameraModule& cameraModule, const camera_module_callbacks_t& callbacks); virtual ~CameraHardwareInterfaceFlashControl(); // FlashControlBase status_t setTorchMode(const String8& cameraId, bool enabled); status_t hasFlashUnit(const String8& cameraId, bool *hasFlash); private: // connect to a camera device status_t connectCameraDevice(const String8& cameraId); // disconnect and free mDevice status_t disconnectCameraDevice(); // initialize the preview window status_t initializePreviewWindow(sp<CameraHardwareInterface> device, int32_t width, int32_t height); // start preview and enable torch status_t startPreviewAndTorch(); // get the smallest surface status_t getSmallestSurfaceSize(int32_t *width, int32_t *height); // protected by mLock status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash); CameraModule *mCameraModule; const camera_module_callbacks_t *mCallbacks; sp<CameraHardwareInterface> mDevice; String8 mCameraId; CameraParameters mParameters; bool mTorchEnabled; sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; sp<GLConsumer> mSurfaceTexture; sp<ANativeWindow> mAnw; Mutex mLock; }; } // namespace android #endif
services/camera/libcameraservice/CameraService.cpp +0 −13 Original line number Diff line number Diff line Loading @@ -496,19 +496,6 @@ int CameraService::getDeviceVersion(int cameraId, int* facing) { return deviceVersion; } status_t CameraService::filterOpenErrorCode(status_t err) { switch(err) { case NO_ERROR: case -EBUSY: case -EINVAL: case -EUSERS: return err; default: break; } return -ENODEV; } status_t CameraService::filterGetInfoErrorCode(status_t err) { switch(err) { case NO_ERROR: Loading
services/camera/libcameraservice/CameraService.h +0 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,6 @@ public: ///////////////////////////////////////////////////////////////////// // Shared utilities static status_t filterOpenErrorCode(status_t err); static status_t filterGetInfoErrorCode(status_t err); ///////////////////////////////////////////////////////////////////// Loading
services/camera/libcameraservice/common/CameraModule.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { } int CameraModule::open(const char* id, struct hw_device_t** device) { return mModule->common.methods->open(&mModule->common, id, device); return filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device)); } int CameraModule::openLegacy( Loading Loading @@ -125,5 +125,20 @@ int CameraModule::setTorchMode(const char* camera_id, bool enable) { return mModule->set_torch_mode(camera_id, enable); } status_t CameraModule::filterOpenErrorCode(status_t err) { switch(err) { case NO_ERROR: case -EBUSY: case -EINVAL: case -EUSERS: return err; default: break; } return -ENODEV; } }; // namespace android