summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorChien-Yu Chen <cychen@google.com>2015-02-25 16:04:22 -0800
committerChien-Yu Chen <cychen@google.com>2015-03-03 14:07:57 -0800
commitd231fd61ca94441183abda9766ce6906a5b4c3cf (patch)
tree67dd34bd33fd1fcddb9182b34d5ddc754a259d16 /services
parent88da526d97442c80731e01bfc94c6b47c4b0c3c7 (diff)
downloadframeworks_av-d231fd61ca94441183abda9766ce6906a5b4c3cf.zip
frameworks_av-d231fd61ca94441183abda9766ce6906a5b4c3cf.tar.gz
frameworks_av-d231fd61ca94441183abda9766ce6906a5b4c3cf.tar.bz2
camera: implement flashlight for HAL v1 devices
Implement flashlight for HAL v1 devices and remove CameraHardwareInterface's dependency on CameraService to avoid circular dependency. Bug: 2682206 Change-Id: Id5bbccef085b607a6189763fd7fbe2e3f26868c8
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/CameraFlashlight.cpp252
-rw-r--r--services/camera/libcameraservice/CameraFlashlight.h50
-rw-r--r--services/camera/libcameraservice/CameraService.cpp13
-rw-r--r--services/camera/libcameraservice/CameraService.h1
-rw-r--r--services/camera/libcameraservice/common/CameraModule.cpp17
-rw-r--r--services/camera/libcameraservice/common/CameraModule.h2
-rw-r--r--services/camera/libcameraservice/device1/CameraHardwareInterface.h3
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.cpp3
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp4
9 files changed, 322 insertions, 23 deletions
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index a00a49f..8e894cd 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -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);
}
}
@@ -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
+
}
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index ae502b9..30f01f0 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -23,6 +23,7 @@
#include "gui/GLConsumer.h"
#include "gui/Surface.h"
#include "common/CameraDeviceBase.h"
+#include "device1/CameraHardwareInterface.h"
namespace android {
@@ -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;
@@ -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
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 8fdfaa8..6f37f16 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -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:
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 74b3623..22afc8c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -150,7 +150,6 @@ public:
/////////////////////////////////////////////////////////////////////
// Shared utilities
- static status_t filterOpenErrorCode(status_t err);
static status_t filterGetInfoErrorCode(status_t err);
/////////////////////////////////////////////////////////////////////
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index 85a4df9..5f767ad 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -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(
@@ -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
diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h
index 31b9ae2..16207aa 100644
--- a/services/camera/libcameraservice/common/CameraModule.h
+++ b/services/camera/libcameraservice/common/CameraModule.h
@@ -50,6 +50,8 @@ public:
private:
// Derive camera characteristics keys defined after HAL device version
static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+ status_t filterOpenErrorCode(status_t err);
+
camera_module_t *mModule;
CameraMetadata mCameraCharacteristics[MAX_CAMERAS_PER_MODULE];
camera_info mCameraInfo[MAX_CAMERAS_PER_MODULE];
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 9e1cdc9..f5ebbf8 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -104,8 +104,7 @@ public:
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
- rc = CameraService::filterOpenErrorCode(module->open(
- mName.string(), (hw_device_t **)&mDevice));
+ rc = module->open(mName.string(), (hw_device_t **)&mDevice);
}
if (rc != OK) {
ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index be66c4d..43c8307 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -68,8 +68,7 @@ status_t Camera2Device::initialize(CameraModule *module)
camera2_device_t *device;
- res = CameraService::filterOpenErrorCode(module->open(
- name, reinterpret_cast<hw_device_t**>(&device)));
+ res = module->open(name, reinterpret_cast<hw_device_t**>(&device));
if (res != OK) {
ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 9a4e5ac..bca9bfd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -106,8 +106,8 @@ status_t Camera3Device::initialize(CameraModule *module)
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
- res = CameraService::filterOpenErrorCode(module->open(
- deviceName.string(), reinterpret_cast<hw_device_t**>(&device)));
+ res = module->open(deviceName.string(),
+ reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (res != OK) {