From 2563313c8f9cdbb0237a814e6d89b1932264d225 Mon Sep 17 00:00:00 2001 From: John Lin Date: Mon, 2 Feb 2015 18:10:42 +0800 Subject: camera2: fix various BpCameraDeviceUser methods to return correct result. - submitRequest*(): res is the request ID and not always equals to NO_ERROR. - cancelRequest() and flush(): the result of reading last frame number should be put in resFrameNumber, not in res. Change-Id: Ic81c58f4ac14c05b3db4bdc5c99f48d00665d3fc Signed-off-by: John Lin --- camera/camera2/ICameraDeviceUser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp index ff4a0c2..7d3807a 100644 --- a/camera/camera2/ICameraDeviceUser.cpp +++ b/camera/camera2/ICameraDeviceUser.cpp @@ -107,7 +107,7 @@ public: } } - if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { + if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; @@ -147,7 +147,7 @@ public: resFrameNumber = reply.readInt64(lastFrameNumber); } } - if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { + if ((res < NO_ERROR) || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; @@ -167,7 +167,7 @@ public: status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { - res = reply.readInt64(lastFrameNumber); + resFrameNumber = reply.readInt64(lastFrameNumber); } } if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { @@ -296,7 +296,7 @@ public: status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { - res = reply.readInt64(lastFrameNumber); + resFrameNumber = reply.readInt64(lastFrameNumber); } } if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { -- cgit v1.1 From 2f9c62f3e838f358bd5921270d7b1dec39e0a974 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Fri, 30 Jan 2015 10:29:02 -0800 Subject: CameraService: intercept Camera module Wrap camera module returned from HAL so get_camera_info returns static_camera_characteristics processed by framework, which generates keys added after HAL3.2 is released. Change-Id: Ief423a1571cf06c7ef80b98b403a33969baf95f6 --- services/camera/libcameraservice/Android.mk | 1 + services/camera/libcameraservice/CameraService.cpp | 56 ++++----- services/camera/libcameraservice/CameraService.h | 6 +- .../camera/libcameraservice/api1/Camera2Client.cpp | 2 +- .../camera/libcameraservice/api1/Camera2Client.h | 2 +- .../camera/libcameraservice/api1/CameraClient.cpp | 4 +- .../camera/libcameraservice/api1/CameraClient.h | 2 +- .../libcameraservice/api2/CameraDeviceClient.cpp | 2 +- .../libcameraservice/api2/CameraDeviceClient.h | 2 +- .../libcameraservice/api_pro/ProCamera2Client.cpp | 2 +- .../libcameraservice/api_pro/ProCamera2Client.h | 2 +- .../libcameraservice/common/Camera2ClientBase.cpp | 2 +- .../libcameraservice/common/Camera2ClientBase.h | 3 +- .../libcameraservice/common/CameraDeviceBase.h | 3 +- .../libcameraservice/common/CameraModule.cpp | 130 +++++++++++++++++++++ .../camera/libcameraservice/common/CameraModule.h | 63 ++++++++++ .../device1/CameraHardwareInterface.h | 17 ++- .../libcameraservice/device2/Camera2Device.cpp | 8 +- .../libcameraservice/device2/Camera2Device.h | 2 +- .../libcameraservice/device3/Camera3Device.cpp | 9 +- .../libcameraservice/device3/Camera3Device.h | 2 +- 21 files changed, 259 insertions(+), 61 deletions(-) create mode 100644 services/camera/libcameraservice/common/CameraModule.cpp create mode 100644 services/camera/libcameraservice/common/CameraModule.h diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index e184d97..de9551d 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -25,6 +25,7 @@ LOCAL_SRC_FILES:= \ CameraDeviceFactory.cpp \ common/Camera2ClientBase.cpp \ common/CameraDeviceBase.cpp \ + common/CameraModule.cpp \ common/FrameProcessorBase.cpp \ api1/CameraClient.cpp \ api1/Camera2Client.cpp \ diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 76428da..f3cd9de 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -113,14 +113,17 @@ void CameraService::onFirstRef() BnCameraService::onFirstRef(); + camera_module_t *rawModule; if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, - (const hw_module_t **)&mModule) < 0) { + (const hw_module_t **)&rawModule) < 0) { ALOGE("Could not load camera HAL module"); mNumberOfCameras = 0; } else { - ALOGI("Loaded \"%s\" camera module", mModule->common.name); - mNumberOfCameras = mModule->get_number_of_cameras(); + mModule = new CameraModule(rawModule); + const hw_module_t *common = mModule->getRawModule(); + ALOGI("Loaded \"%s\" camera module", common->name); + mNumberOfCameras = mModule->getNumberOfCameras(); if (mNumberOfCameras > MAX_CAMERAS) { ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", mNumberOfCameras, MAX_CAMERAS); @@ -130,14 +133,13 @@ void CameraService::onFirstRef() setCameraFree(i); } - if (mModule->common.module_api_version >= - CAMERA_MODULE_API_VERSION_2_1) { - mModule->set_callbacks(this); + if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) { + mModule->setCallbacks(this); } VendorTagDescriptor::clearGlobalVendorTagDescriptor(); - if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_2) { + if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_2) { setUpVendorTags(); } @@ -152,6 +154,9 @@ CameraService::~CameraService() { } } + if (mModule) { + delete mModule; + } VendorTagDescriptor::clearGlobalVendorTagDescriptor(); gCameraService = NULL; } @@ -236,7 +241,7 @@ status_t CameraService::getCameraInfo(int cameraId, struct camera_info info; status_t rc = filterGetInfoErrorCode( - mModule->get_camera_info(cameraId, &info)); + mModule->getCameraInfo(cameraId, &info)); cameraInfo->facing = info.facing; cameraInfo->orientation = info.orientation; return rc; @@ -347,7 +352,7 @@ status_t CameraService::getCameraCharacteristics(int cameraId, int facing; status_t ret = OK; - if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0 || + if (mModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_0 || getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) { /** * Backwards compatibility mode for old HALs: @@ -368,7 +373,7 @@ status_t CameraService::getCameraCharacteristics(int cameraId, * Normal HAL 2.1+ codepath. */ struct camera_info info; - ret = filterGetInfoErrorCode(mModule->get_camera_info(cameraId, &info)); + ret = filterGetInfoErrorCode(mModule->getCameraInfo(cameraId, &info)); *cameraInfo = info.static_camera_characteristics; } @@ -387,12 +392,12 @@ status_t CameraService::getCameraVendorTagDescriptor(/*out*/spget_camera_info(cameraId, &info) != OK) { + if (mModule->getCameraInfo(cameraId, &info) != OK) { return -1; } int deviceVersion; - if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) { + if (mModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_0) { deviceVersion = info.device_version; } else { deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; @@ -433,13 +438,13 @@ bool CameraService::setUpVendorTags() { vendor_tag_ops_t vOps = vendor_tag_ops_t(); // Check if vendor operations have been implemented - if (mModule->get_vendor_tag_ops == NULL) { + if (!mModule->isVendorTagDefined()) { ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__); return false; } ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops"); - mModule->get_vendor_tag_ops(&vOps); + mModule->getVendorTagOps(&vOps); ATRACE_END(); // Ensure all vendor operations are present @@ -789,8 +794,9 @@ status_t CameraService::connectLegacy( /*out*/ sp& device) { + int apiVersion = mModule->getRawModule()->module_api_version; if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED && - mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_3) { + apiVersion < CAMERA_MODULE_API_VERSION_2_3) { /* * Either the HAL version is unspecified in which case this just creates * a camera client selected by the latest device version, or @@ -798,7 +804,7 @@ status_t CameraService::connectLegacy( * the open_legacy call */ ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!", - __FUNCTION__, mModule->common.module_api_version); + __FUNCTION__, apiVersion); return INVALID_OPERATION; } @@ -1630,14 +1636,11 @@ status_t CameraService::dump(int fd, const Vector& args) { return NO_ERROR; } - result = String8::format("Camera module HAL API version: 0x%x\n", - mModule->common.hal_api_version); - result.appendFormat("Camera module API version: 0x%x\n", - mModule->common.module_api_version); - result.appendFormat("Camera module name: %s\n", - mModule->common.name); - result.appendFormat("Camera module author: %s\n", - mModule->common.author); + const hw_module_t* common = mModule->getRawModule(); + result = String8::format("Camera module HAL API version: 0x%x\n", common->hal_api_version); + result.appendFormat("Camera module API version: 0x%x\n", common->module_api_version); + result.appendFormat("Camera module name: %s\n", common->name); + result.appendFormat("Camera module author: %s\n", common->author); result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras); sp desc = VendorTagDescriptor::getGlobalVendorTagDescriptor(); @@ -1657,7 +1660,7 @@ status_t CameraService::dump(int fd, const Vector& args) { result = String8::format("Camera %d static information:\n", i); camera_info info; - status_t rc = mModule->get_camera_info(i, &info); + status_t rc = mModule->getCameraInfo(i, &info); if (rc != OK) { result.appendFormat(" Error reading static information!\n"); write(fd, result.string(), result.size()); @@ -1666,8 +1669,7 @@ status_t CameraService::dump(int fd, const Vector& args) { info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT"); result.appendFormat(" Orientation: %d\n", info.orientation); int deviceVersion; - if (mModule->common.module_api_version < - CAMERA_MODULE_API_VERSION_2_0) { + if (common->module_api_version < CAMERA_MODULE_API_VERSION_2_0) { deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; } else { deviceVersion = info.device_version; diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index a7328cf..3f989c8 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -37,6 +37,8 @@ #include +#include "common/CameraModule.h" + /* This needs to be increased if we can have more cameras */ #define MAX_CAMERAS 2 @@ -153,7 +155,7 @@ public: class BasicClient : public virtual RefBase { public: - virtual status_t initialize(camera_module_t *module) = 0; + virtual status_t initialize(CameraModule *module) = 0; virtual void disconnect(); // because we can't virtually inherit IInterface, which breaks @@ -385,7 +387,7 @@ private: sp mSoundPlayer[NUM_SOUNDS]; int mSoundRef; // reference count (release all MediaPlayer when 0) - camera_module_t *mModule; + CameraModule* mModule; Vector > mListenerList; diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index dcab4ad..c129f6f 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -67,7 +67,7 @@ Camera2Client::Camera2Client(const sp& cameraService, mLegacyMode = legacyMode; } -status_t Camera2Client::initialize(camera_module_t *module) +status_t Camera2Client::initialize(CameraModule *module) { ATRACE_CALL(); ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId); diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h index d68bb29..5a8241f 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.h +++ b/services/camera/libcameraservice/api1/Camera2Client.h @@ -94,7 +94,7 @@ public: virtual ~Camera2Client(); - status_t initialize(camera_module_t *module); + status_t initialize(CameraModule *module); virtual status_t dump(int fd, const Vector& args); diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 1a4d9a6..5bdce9b 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -59,7 +59,7 @@ CameraClient::CameraClient(const sp& cameraService, LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId); } -status_t CameraClient::initialize(camera_module_t *module) { +status_t CameraClient::initialize(CameraModule *module) { int callingPid = getCallingPid(); status_t res; @@ -75,7 +75,7 @@ status_t CameraClient::initialize(camera_module_t *module) { snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId); mHardware = new CameraHardwareInterface(camera_device_name); - res = mHardware->initialize(&module->common); + res = mHardware->initialize(module); if (res != OK) { ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h index 63a9d0f..95616b2 100644 --- a/services/camera/libcameraservice/api1/CameraClient.h +++ b/services/camera/libcameraservice/api1/CameraClient.h @@ -68,7 +68,7 @@ public: bool legacyMode = false); ~CameraClient(); - status_t initialize(camera_module_t *module); + status_t initialize(CameraModule *module); status_t dump(int fd, const Vector& args); diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index e6865bb..884b198 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -65,7 +65,7 @@ CameraDeviceClient::CameraDeviceClient(const sp& cameraService, ALOGI("CameraDeviceClient %d: Opened", cameraId); } -status_t CameraDeviceClient::initialize(camera_module_t *module) +status_t CameraDeviceClient::initialize(CameraModule *module) { ATRACE_CALL(); status_t res; diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 84e46b7..e687175 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -119,7 +119,7 @@ public: int servicePid); virtual ~CameraDeviceClient(); - virtual status_t initialize(camera_module_t *module); + virtual status_t initialize(CameraModule *module); virtual status_t dump(int fd, const Vector& args); diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp index 2ea460f..d335d0b 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp @@ -50,7 +50,7 @@ ProCamera2Client::ProCamera2Client(const sp& cameraService, mExclusiveLock = false; } -status_t ProCamera2Client::initialize(camera_module_t *module) +status_t ProCamera2Client::initialize(CameraModule *module) { ATRACE_CALL(); status_t res; diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.h b/services/camera/libcameraservice/api_pro/ProCamera2Client.h index 9d83122..7f5f6ac 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.h +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.h @@ -85,7 +85,7 @@ public: int servicePid); virtual ~ProCamera2Client(); - virtual status_t initialize(camera_module_t *module); + virtual status_t initialize(CameraModule *module); virtual status_t dump(int fd, const Vector& args); diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index d6db151..053d6e3 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -78,7 +78,7 @@ status_t Camera2ClientBase::checkPid(const char* checkLocation) } template -status_t Camera2ClientBase::initialize(camera_module_t *module) { +status_t Camera2ClientBase::initialize(CameraModule *module) { ATRACE_CALL(); ALOGV("%s: Initializing client for camera %d", __FUNCTION__, TClientBase::mCameraId); diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index d198e4e..ca2b74b 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -18,6 +18,7 @@ #define ANDROID_SERVERS_CAMERA_CAMERA2CLIENT_BASE_H #include "common/CameraDeviceBase.h" +#include "common/CameraModule.h" #include "camera/CaptureResult.h" namespace android { @@ -55,7 +56,7 @@ public: int servicePid); virtual ~Camera2ClientBase(); - virtual status_t initialize(camera_module_t *module); + virtual status_t initialize(CameraModule *module); virtual status_t dump(int fd, const Vector& args); /** diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index d26e20c..06615f6 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -29,6 +29,7 @@ #include "hardware/camera3.h" #include "camera/CameraMetadata.h" #include "camera/CaptureResult.h" +#include "common/CameraModule.h" namespace android { @@ -45,7 +46,7 @@ class CameraDeviceBase : public virtual RefBase { */ virtual int getId() const = 0; - virtual status_t initialize(camera_module_t *module) = 0; + virtual status_t initialize(CameraModule *module) = 0; virtual status_t disconnect() = 0; virtual status_t dump(int fd, const Vector &args) = 0; diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp new file mode 100644 index 0000000..bbf47e8 --- /dev/null +++ b/services/camera/libcameraservice/common/CameraModule.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CameraModule" +//#define LOG_NDEBUG 0 + +#include "CameraModule.h" + +namespace android { + +void CameraModule::deriveCameraCharacteristicsKeys( + uint32_t deviceVersion, CameraMetadata &chars) { + // HAL1 devices should not reach here + if (deviceVersion < CAMERA_DEVICE_API_VERSION_2_0) { + ALOGV("%s: Cannot derive keys for HAL version < 2.0"); + return; + } + + // Keys added in HAL3.3 + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) { + Vector controlModes; + uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE; + chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1); + data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE; + chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/1); + controlModes.push(ANDROID_CONTROL_MODE_OFF); + controlModes.push(ANDROID_CONTROL_MODE_AUTO); + camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES); + if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) { + controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE); + } + chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes); + } + return; +} + +CameraModule::CameraModule(camera_module_t *module) { + if (module == NULL) { + ALOGE("%s: camera hardware module must not be null", __FUNCTION__); + assert(0); + } + + mModule = module; + for (int i = 0; i < MAX_CAMERAS_PER_MODULE; i++) { + mCameraInfoCached[i] = false; + } +} + +int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { + Mutex::Autolock lock(mCameraInfoLock); + if (cameraId < 0 || cameraId >= MAX_CAMERAS_PER_MODULE) { + ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId); + return -EINVAL; + } + + camera_info &wrappedInfo = mCameraInfo[cameraId]; + if (!mCameraInfoCached[cameraId]) { + camera_info rawInfo; + int ret = mModule->get_camera_info(cameraId, &rawInfo); + if (ret != 0) { + return ret; + } + CameraMetadata &m = mCameraCharacteristics[cameraId]; + m = rawInfo.static_camera_characteristics; + int deviceVersion; + int apiVersion = mModule->common.module_api_version; + if (apiVersion >= CAMERA_MODULE_API_VERSION_2_0) { + deviceVersion = rawInfo.device_version; + } else { + deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; + } + deriveCameraCharacteristicsKeys(deviceVersion, m); + wrappedInfo = rawInfo; + wrappedInfo.static_camera_characteristics = m.getAndLock(); + mCameraInfoCached[cameraId] = true; + } + *info = wrappedInfo; + return 0; +} + +int CameraModule::open(const char* id, struct hw_device_t** device) { + return mModule->common.methods->open(&mModule->common, id, device); +} + +int CameraModule::openLegacy( + const char* id, uint32_t halVersion, struct hw_device_t** device) { + return mModule->open_legacy(&mModule->common, id, halVersion, device); +} + +const hw_module_t* CameraModule::getRawModule() { + return &mModule->common; +} + +int CameraModule::getNumberOfCameras() { + return mModule->get_number_of_cameras(); +} + +int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) { + return mModule->set_callbacks(callbacks); +} + +bool CameraModule::isVendorTagDefined() { + return mModule->get_vendor_tag_ops != NULL; +} + +void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) { + if (mModule->get_vendor_tag_ops) { + mModule->get_vendor_tag_ops(ops); + } +} + +int CameraModule::setTorchMode(const char* camera_id, bool enable) { + return mModule->set_torch_mode(camera_id, enable); +} + +}; // namespace android + diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h new file mode 100644 index 0000000..31b9ae2 --- /dev/null +++ b/services/camera/libcameraservice/common/CameraModule.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SERVERS_CAMERA_CAMERAMODULE_H +#define ANDROID_SERVERS_CAMERA_CAMERAMODULE_H + +#include +#include +#include + +/* This needs to be increased if we can have more cameras */ +#define MAX_CAMERAS_PER_MODULE 2 + + +namespace android { +/** + * A wrapper class for HAL camera module. + * + * This class wraps camera_module_t returned from HAL to provide a wrapped + * get_camera_info implementation which CameraService generates some + * camera characteristics keys defined in newer HAL version on an older HAL. + */ +class CameraModule { +public: + CameraModule(camera_module_t *module); + + const hw_module_t* getRawModule(); + int getCameraInfo(int cameraId, struct camera_info *info); + int getNumberOfCameras(void); + int open(const char* id, struct hw_device_t** device); + int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device); + int setCallbacks(const camera_module_callbacks_t *callbacks); + bool isVendorTagDefined(); + void getVendorTagOps(vendor_tag_ops_t* ops); + int setTorchMode(const char* camera_id, bool enable); + +private: + // Derive camera characteristics keys defined after HAL device version + static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars); + camera_module_t *mModule; + CameraMetadata mCameraCharacteristics[MAX_CAMERAS_PER_MODULE]; + camera_info mCameraInfo[MAX_CAMERAS_PER_MODULE]; + bool mCameraInfoCached[MAX_CAMERAS_PER_MODULE]; + Mutex mCameraInfoLock; +}; + +} // namespace android + +#endif + diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h index 6386838..16e3a19 100644 --- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h +++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h @@ -89,24 +89,23 @@ public: } } - status_t initialize(hw_module_t *module) + status_t initialize(CameraModule *module) { ALOGI("Opening camera %s", mName.string()); - camera_module_t *cameraModule = reinterpret_cast(module); camera_info info; - status_t res = cameraModule->get_camera_info(atoi(mName.string()), &info); + status_t res = module->getCameraInfo(atoi(mName.string()), &info); if (res != OK) return res; int rc = OK; - if (module->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 && + if (module->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 && info.device_version > CAMERA_DEVICE_API_VERSION_1_0) { // Open higher version camera device as HAL1.0 device. - rc = cameraModule->open_legacy(module, mName.string(), - CAMERA_DEVICE_API_VERSION_1_0, - (hw_device_t **)&mDevice); + rc = module->openLegacy(mName.string(), + CAMERA_DEVICE_API_VERSION_1_0, + (hw_device_t **)&mDevice); } else { - rc = CameraService::filterOpenErrorCode(module->methods->open( - module, mName.string(), (hw_device_t **)&mDevice)); + rc = CameraService::filterOpenErrorCode(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 d1158d6..be66c4d 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -53,7 +53,7 @@ int Camera2Device::getId() const { return mId; } -status_t Camera2Device::initialize(camera_module_t *module) +status_t Camera2Device::initialize(CameraModule *module) { ATRACE_CALL(); ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId); @@ -68,8 +68,8 @@ status_t Camera2Device::initialize(camera_module_t *module) camera2_device_t *device; - res = CameraService::filterOpenErrorCode(module->common.methods->open( - &module->common, name, reinterpret_cast(&device))); + res = CameraService::filterOpenErrorCode(module->open( + name, reinterpret_cast(&device))); if (res != OK) { ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__, @@ -87,7 +87,7 @@ status_t Camera2Device::initialize(camera_module_t *module) } camera_info info; - res = module->get_camera_info(mId, &info); + res = module->getCameraInfo(mId, &info); if (res != OK ) return res; if (info.device_version != device->common.version) { diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 4def8ae..1cc5482 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -43,7 +43,7 @@ class Camera2Device: public CameraDeviceBase { * CameraDevice interface */ virtual int getId() const; - virtual status_t initialize(camera_module_t *module); + virtual status_t initialize(CameraModule *module); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector& args); virtual const CameraMetadata& info() const; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 53e6fa9..9a4e5ac 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -86,7 +86,7 @@ int Camera3Device::getId() const { * CameraDeviceBase interface */ -status_t Camera3Device::initialize(camera_module_t *module) +status_t Camera3Device::initialize(CameraModule *module) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); @@ -106,9 +106,8 @@ status_t Camera3Device::initialize(camera_module_t *module) camera3_device_t *device; ATRACE_BEGIN("camera3->open"); - res = CameraService::filterOpenErrorCode(module->common.methods->open( - &module->common, deviceName.string(), - reinterpret_cast(&device))); + res = CameraService::filterOpenErrorCode(module->open( + deviceName.string(), reinterpret_cast(&device))); ATRACE_END(); if (res != OK) { @@ -127,7 +126,7 @@ status_t Camera3Device::initialize(camera_module_t *module) } camera_info info; - res = CameraService::filterGetInfoErrorCode(module->get_camera_info( + res = CameraService::filterGetInfoErrorCode(module->getCameraInfo( mId, &info)); if (res != OK) return res; diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index ec8dc10..de10cfe 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -73,7 +73,7 @@ class Camera3Device : virtual int getId() const; // Transitions to idle state on success. - virtual status_t initialize(camera_module_t *module); + virtual status_t initialize(CameraModule *module); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector &args); virtual const CameraMetadata& info() const; -- cgit v1.1 From 736a7f7b39637e67becef203bb552010ba071467 Mon Sep 17 00:00:00 2001 From: Chien-Yu Chen Date: Mon, 9 Feb 2015 13:29:57 -0800 Subject: camera: implement flashlight control Implement flashlight API for module v2.4 by calling module APIs and by for hal v2 and v3 by using CameraDeviceBase. Bug: 2682206 Change-Id: Ib8b77f6fd462489d672f27e14fe37801d35b7544 --- camera/ICameraService.cpp | 24 + camera/ICameraServiceListener.cpp | 27 +- camera/tests/ProCameraTests.cpp | 6 + include/camera/ICameraService.h | 7 + include/camera/ICameraServiceListener.h | 24 + services/camera/libcameraservice/Android.mk | 1 + .../camera/libcameraservice/CameraFlashlight.cpp | 520 +++++++++++++++++++++ .../camera/libcameraservice/CameraFlashlight.h | 149 ++++++ services/camera/libcameraservice/CameraService.cpp | 176 ++++++- services/camera/libcameraservice/CameraService.h | 34 ++ 10 files changed, 965 insertions(+), 3 deletions(-) create mode 100644 services/camera/libcameraservice/CameraFlashlight.cpp create mode 100644 services/camera/libcameraservice/CameraFlashlight.h diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp index 5485205..e3f9931 100644 --- a/camera/ICameraService.cpp +++ b/camera/ICameraService.cpp @@ -209,6 +209,20 @@ public: return status; } + virtual status_t setTorchMode(const String16& cameraId, bool enabled, + const sp& clientBinder) + { + Parcel data, reply; + data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); + data.writeString16(cameraId); + data.writeInt32(enabled ? 1 : 0); + data.writeStrongBinder(clientBinder); + remote()->transact(BnCameraService::SET_TORCH_MODE, data, &reply); + + if (readExceptionCode(reply)) return -EPROTO; + return reply.readInt32(); + } + // connect to camera service (pro client) virtual status_t connectPro(const sp& cameraCb, int cameraId, const String16 &clientPackageName, int clientUid, @@ -490,6 +504,16 @@ status_t BnCameraService::onTransact( } return NO_ERROR; } break; + case SET_TORCH_MODE: { + CHECK_INTERFACE(ICameraService, data, reply); + String16 cameraId = data.readString16(); + bool enabled = data.readInt32() != 0 ? true : false; + const sp clientBinder = data.readStrongBinder(); + status_t status = setTorchMode(cameraId, enabled, clientBinder); + reply->writeNoException(); + reply->writeInt32(status); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/camera/ICameraServiceListener.cpp b/camera/ICameraServiceListener.cpp index b2f1729..90a8bc2 100644 --- a/camera/ICameraServiceListener.cpp +++ b/camera/ICameraServiceListener.cpp @@ -29,6 +29,7 @@ namespace android { namespace { enum { STATUS_CHANGED = IBinder::FIRST_CALL_TRANSACTION, + TORCH_STATUS_CHANGED, }; }; // namespace anonymous @@ -54,8 +55,21 @@ public: data, &reply, IBinder::FLAG_ONEWAY); + } - reply.readExceptionCode(); + virtual void onTorchStatusChanged(TorchStatus status, const String16 &cameraId) + { + Parcel data, reply; + data.writeInterfaceToken( + ICameraServiceListener::getInterfaceDescriptor()); + + data.writeInt32(static_cast(status)); + data.writeString16(cameraId); + + remote()->transact(TORCH_STATUS_CHANGED, + data, + &reply, + IBinder::FLAG_ONEWAY); } }; @@ -75,7 +89,16 @@ status_t BnCameraServiceListener::onTransact( int32_t cameraId = data.readInt32(); onStatusChanged(status, cameraId); - reply->writeNoException(); + + return NO_ERROR; + } break; + case TORCH_STATUS_CHANGED: { + CHECK_INTERFACE(ICameraServiceListener, data, reply); + + TorchStatus status = static_cast(data.readInt32()); + String16 cameraId = data.readString16(); + + onTorchStatusChanged(status, cameraId); return NO_ERROR; } break; diff --git a/camera/tests/ProCameraTests.cpp b/camera/tests/ProCameraTests.cpp index 1f5867a..6212678 100644 --- a/camera/tests/ProCameraTests.cpp +++ b/camera/tests/ProCameraTests.cpp @@ -89,6 +89,12 @@ struct ServiceListener : public BnCameraServiceListener { mCondition.broadcast(); } + void onTorchStatusChanged(TorchStatus status, const String16& cameraId) { + dout << "On torch status changed: 0x" << std::hex + << (unsigned int) status << " cameraId " << cameraId.string() + << std::endl; + } + status_t waitForStatusChange(Status& newStatus) { Mutex::Autolock al(mMutex); diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index f7f06bb..cc41efe 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -53,6 +53,7 @@ public: GET_LEGACY_PARAMETERS, SUPPORTS_CAMERA_API, CONNECT_LEGACY, + SET_TORCH_MODE, }; enum { @@ -142,6 +143,12 @@ public: int clientUid, /*out*/ sp& device) = 0; + + /** + * Turn on or off a camera's torch mode. + */ + virtual status_t setTorchMode(const String16& cameraId, bool enabled, + const sp& clientBinder) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/camera/ICameraServiceListener.h b/include/camera/ICameraServiceListener.h index 0a0e43a..9e8b912 100644 --- a/include/camera/ICameraServiceListener.h +++ b/include/camera/ICameraServiceListener.h @@ -66,9 +66,33 @@ public: STATUS_UNKNOWN = 0xFFFFFFFF, }; + /** + * The torch mode status of a camera. + * + * Initial status will be transmitted with onTorchStatusChanged immediately + * after this listener is added to the service listener list. + */ + enum TorchStatus { + // The camera's torch mode has become available to use via + // setTorchMode(). + TORCH_STATUS_AVAILABLE = TORCH_MODE_STATUS_AVAILABLE, + // The camera's torch mode has become not available to use via + // setTorchMode(). + TORCH_STATUS_NOT_AVAILABLE = TORCH_MODE_STATUS_RESOURCE_BUSY, + // The camera's torch mode has been turned off by setTorchMode(). + TORCH_STATUS_OFF = TORCH_MODE_STATUS_OFF, + // The camera's torch mode has been turned on by setTorchMode(). + TORCH_STATUS_ON = 0x80000000, + + // Use to initialize variables only + TORCH_STATUS_UNKNOWN = 0xFFFFFFFF, + }; + DECLARE_META_INTERFACE(CameraServiceListener); virtual void onStatusChanged(Status status, int32_t cameraId) = 0; + + virtual void onTorchStatusChanged(TorchStatus status, const String16& cameraId) = 0; }; // ---------------------------------------------------------------------------- diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index de9551d..5d6423a 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -23,6 +23,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ CameraService.cpp \ CameraDeviceFactory.cpp \ + CameraFlashlight.cpp \ common/Camera2ClientBase.cpp \ common/CameraDeviceBase.cpp \ common/CameraModule.cpp \ diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp new file mode 100644 index 0000000..00a70eb --- /dev/null +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CameraFlashlight" +#define ATRACE_TAG ATRACE_TAG_CAMERA +#define LOG_NDEBUG 0 + +#include +#include +#include + +#include "camera/CameraMetadata.h" +#include "CameraFlashlight.h" +#include "gui/IGraphicBufferConsumer.h" +#include "gui/BufferQueue.h" +#include "camera/camera2/CaptureRequest.h" +#include "CameraDeviceFactory.h" + + +namespace android { + +CameraFlashlight::CameraFlashlight(CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks) : + mCameraModule(&cameraModule), + mCallbacks(&callbacks) { +} + +CameraFlashlight::~CameraFlashlight() { +} + +status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { + ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__, + cameraId.string()); + if (mFlashControl != NULL) { + return INVALID_OPERATION; + } + + status_t res = OK; + + if (mCameraModule->getRawModule()->module_api_version >= + CAMERA_MODULE_API_VERSION_2_4) { + mFlashControl = new FlashControl(*mCameraModule, *mCallbacks); + if (mFlashControl == NULL) { + ALOGV("%s: cannot create flash control for module api v2.4+", + __FUNCTION__); + return NO_MEMORY; + } + } else { + uint32_t deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; + + if (mCameraModule->getRawModule()->module_api_version >= + CAMERA_MODULE_API_VERSION_2_0) { + camera_info info; + res = mCameraModule->getCameraInfo( + atoi(String8(cameraId).string()), &info); + if (res) { + ALOGV("%s: failed to get camera info for camera %s", + __FUNCTION__, cameraId.string()); + return res; + } + deviceVersion = info.device_version; + } + + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) { + CameraDeviceClientFlashControl *flashControl = + new CameraDeviceClientFlashControl(*mCameraModule, + *mCallbacks); + if (!flashControl) { + return NO_MEMORY; + } + + mFlashControl = flashControl; + } + else { + // todo: implement for device api 1 + return INVALID_OPERATION; + } + } + + return OK; +} + +status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) { + if (!mCameraModule) { + return NO_INIT; + } + + ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__, + cameraId.string(), enabled); + + status_t res = OK; + Mutex::Autolock l(mLock); + + if (mFlashControl == NULL) { + res = createFlashlightControl(cameraId); + if (res) { + return res; + } + res = mFlashControl->setTorchMode(cameraId, enabled); + return res; + } + + // if flash control already exists, turning on torch mode may fail if it's + // tied to another camera device for module v2.3 and below. + res = mFlashControl->setTorchMode(cameraId, enabled); + if (res == BAD_INDEX) { + // flash control is tied to another camera device, need to close it and + // try again. + mFlashControl.clear(); + res = createFlashlightControl(cameraId); + if (res) { + return res; + } + res = mFlashControl->setTorchMode(cameraId, enabled); + } + + return res; +} + +bool CameraFlashlight::hasFlashUnit(const String16& cameraId) { + status_t res; + + Mutex::Autolock l(mLock); + + if (mFlashControl == NULL) { + res = createFlashlightControl(cameraId); + if (res) { + ALOGE("%s: failed to create flash control for %s ", + __FUNCTION__, cameraId.string()); + return false; + } + } + + bool flashUnit = false; + + // if flash control already exists, querying if a camera device has a flash + // unit may fail if it's module v1 + res = mFlashControl->hasFlashUnit(cameraId, &flashUnit); + if (res == BAD_INDEX) { + // need to close the flash control before query. + mFlashControl.clear(); + res = createFlashlightControl(cameraId); + if (res) { + ALOGE("%s: failed to create flash control for %s ", __FUNCTION__, + cameraId.string()); + return false; + } + res = mFlashControl->hasFlashUnit(cameraId, &flashUnit); + if (res) { + flashUnit = false; + } + } + + return flashUnit; +} + +status_t CameraFlashlight::prepareDeviceOpen() { + ALOGV("%s: prepare for device open", __FUNCTION__); + + Mutex::Autolock l(mLock); + + if (mCameraModule && mCameraModule->getRawModule()->module_api_version < + CAMERA_MODULE_API_VERSION_2_4) { + // framework is going to open a camera device, all flash light control + // should be closed for backward compatible support. + if (mFlashControl != NULL) { + mFlashControl.clear(); + } + } + + return OK; +} + + +FlashControlBase::~FlashControlBase() { +} + + +FlashControl::FlashControl(CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks) : + mCameraModule(&cameraModule) { +} + +FlashControl::~FlashControl() { +} + +status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) { + if (!hasFlash) { + return BAD_VALUE; + } + + *hasFlash = false; + + Mutex::Autolock l(mLock); + + if (!mCameraModule) { + return NO_INIT; + } + + camera_info info; + status_t res = mCameraModule->getCameraInfo(atoi(String8(cameraId).string()), + &info); + if (res != 0) { + return res; + } + + CameraMetadata metadata; + metadata = info.static_camera_characteristics; + camera_metadata_entry flashAvailable = + metadata.find(ANDROID_FLASH_INFO_AVAILABLE); + if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { + *hasFlash = true; + } + + return OK; +} + +status_t FlashControl::setTorchMode(const String16& cameraId, bool enabled) { + ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__, + cameraId.string(), enabled); + + Mutex::Autolock l(mLock); + if (!mCameraModule) { + return NO_INIT; + } + + return mCameraModule->setTorchMode(String8(cameraId).string(), enabled); +} + +CameraDeviceClientFlashControl::CameraDeviceClientFlashControl( + CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks) : + mCameraModule(&cameraModule), + mCallbacks(&callbacks), + mTorchEnabled(false), + mMetadata(NULL) { +} + +CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { + if (mDevice != NULL) { + mDevice->flush(); + mDevice->deleteStream(mStreamId); + mDevice.clear(); + } + if (mMetadata) { + delete mMetadata; + } + + 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, + String8(mCameraId).string(), TORCH_MODE_STATUS_OFF); + } + } +} + +status_t CameraDeviceClientFlashControl::initializeSurface(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; + } + + bool useAsync = false; + int32_t consumerUsage; + res = mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage); + if (res) { + return res; + } + + if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) { + useAsync = true; + } + + mAnw = new Surface(mProducer, useAsync); + if (mAnw == NULL) { + return NO_MEMORY; + } + res = mDevice->createStream(mAnw, width, height, format, &mStreamId); + if (res) { + return res; + } + + res = mDevice->configureStreams(); + if (res) { + return res; + } + + return res; +} + +status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( + const camera_info& info, int32_t *width, int32_t *height) { + if (!width || !height) { + return BAD_VALUE; + } + + int32_t w = INT32_MAX; + int32_t h = 1; + + CameraMetadata metadata; + metadata = info.static_camera_characteristics; + camera_metadata_entry streamConfigs = + metadata.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); + for (size_t i = 0; i < streamConfigs.count; i += 4) { + int32_t fmt = streamConfigs.data.i32[i]; + if (fmt == ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED) { + int32_t ww = streamConfigs.data.i32[i + 1]; + int32_t hh = streamConfigs.data.i32[i + 2]; + + if (w* h > ww * hh) { + w = ww; + h = hh; + } + } + } + + if (w == INT32_MAX) { + return NAME_NOT_FOUND; + } + + *width = w; + *height = h; + + return OK; +} + +status_t CameraDeviceClientFlashControl::connectCameraDevice( + const String16& cameraId) { + String8 id = String8(cameraId); + camera_info info; + status_t res = mCameraModule->getCameraInfo(atoi(id.string()), &info); + if (res != 0) { + ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, + mCameraId.string()); + return res; + } + + mDevice = CameraDeviceFactory::createDevice(atoi(id.string())); + if (mDevice == NULL) { + return NO_MEMORY; + } + + res = mDevice->initialize(mCameraModule); + if (res) { + goto fail; + } + + int32_t width, height; + res = getSmallestSurfaceSize(info, &width, &height); + if (res) { + return res; + } + res = initializeSurface(width, height); + if (res) { + goto fail; + } + + mCameraId = cameraId; + + return OK; + +fail: + mDevice.clear(); + return res; +} + + +status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId, + bool *hasFlash) { + ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, + cameraId.string()); + + Mutex::Autolock l(mLock); + return hasFlashUnitLocked(cameraId, hasFlash); + +} + +status_t CameraDeviceClientFlashControl::hasFlashUnitLocked( + const String16& cameraId, bool *hasFlash) { + if (!mCameraModule) { + ALOGE("%s: camera module is NULL", __FUNCTION__); + return NO_INIT; + } + + if (!hasFlash) { + return BAD_VALUE; + } + + camera_info info; + status_t res = mCameraModule->getCameraInfo( + atoi(String8(cameraId).string()), &info); + if (res != 0) { + ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, + cameraId.string()); + return res; + } + + CameraMetadata metadata; + metadata = info.static_camera_characteristics; + camera_metadata_entry flashAvailable = + metadata.find(ANDROID_FLASH_INFO_AVAILABLE); + if (flashAvailable.count == 1 && flashAvailable.data.u8[0] == 1) { + *hasFlash = true; + } + + return OK; +} + +status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) { + status_t res; + + if (mMetadata == NULL) { + mMetadata = new CameraMetadata(); + if (mMetadata == NULL) { + return NO_MEMORY; + } + res = mDevice->createDefaultRequest( + CAMERA3_TEMPLATE_PREVIEW, mMetadata); + if (res) { + return res; + } + } + + uint8_t torchOn = enabled ? ANDROID_FLASH_MODE_TORCH : + ANDROID_FLASH_MODE_OFF; + + mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); + mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); + + int32_t requestId = 0; + mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); + + List metadataRequestList; + metadataRequestList.push_back(*mMetadata); + + int64_t lastFrameNumber = 0; + res = mDevice->captureList(metadataRequestList, &lastFrameNumber); + + return res; +} + + +status_t CameraDeviceClientFlashControl::setTorchMode( + const String16& cameraId, bool enabled) { + bool hasFlash = false; + + Mutex::Autolock l(mLock); + status_t res = hasFlashUnitLocked(cameraId, &hasFlash); + + // pre-check + if (enabled) { + // invalid camera? + if (res) { + return -EINVAL; + } + // no flash unit? + if (!hasFlash) { + return -ENOSYS; + } + // already opened for a different device? + if (mDevice != NULL && cameraId != mCameraId) { + return BAD_INDEX; + } + } else if (mDevice == NULL || cameraId != mCameraId) { + // disabling the torch mode of an un-opened or different device. + return OK; + } + + if (mDevice == NULL) { + res = connectCameraDevice(cameraId); + if (res) { + return res; + } + } + + res = submitTorchRequest(enabled); + if (res) { + return res; + } + + mTorchEnabled = enabled; + return OK; +} + +} diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h new file mode 100644 index 0000000..a0de0b0 --- /dev/null +++ b/services/camera/libcameraservice/CameraFlashlight.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H +#define ANDROID_SERVERS_CAMERA_CAMERAFLASHLIGHT_H + +#include "hardware/camera_common.h" +#include "utils/KeyedVector.h" +#include "gui/GLConsumer.h" +#include "gui/Surface.h" +#include "common/CameraDeviceBase.h" + +namespace android { + +/** + * FlashControlBase is a base class for flash control. It defines the functions + * that a flash control for each camera module/device version should implement. + */ +class FlashControlBase : public virtual VirtualLightRefBase { + public: + virtual ~FlashControlBase(); + + // Whether a camera device has a flash unit. Calling this function may + // cause the torch mode to be turned off in HAL v1 devices. If + // previously-on torch mode is turned off, + // callbacks.torch_mode_status_change() should be invoked. + virtual status_t hasFlashUnit(const String16& cameraId, + bool *hasFlash) = 0; + + // set the torch mode to on or off. + virtual status_t setTorchMode(const String16& cameraId, + bool enabled) = 0; +}; + +/** + * CameraFlashlight can be used by camera service to control flashflight. + */ +class CameraFlashlight : public virtual VirtualLightRefBase { + public: + CameraFlashlight(CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks); + virtual ~CameraFlashlight(); + + // set the torch mode to on or off. + status_t setTorchMode(const String16& cameraId, bool enabled); + + // Whether a camera device has a flash unit. Calling this function may + // cause the torch mode to be turned off in HAL v1 devices. + bool hasFlashUnit(const String16& cameraId); + + // Notify CameraFlashlight that camera service is going to open a camera + // device. CameraFlashlight will free the resources that may cause the + // camera open to fail. Camera service must call this function before + // opening a camera device. + status_t prepareDeviceOpen(); + + private: + // create flashlight control based on camera module API and camera + // device API versions. + status_t createFlashlightControl(const String16& cameraId); + + sp mFlashControl; + CameraModule *mCameraModule; + const camera_module_callbacks_t *mCallbacks; + + Mutex mLock; +}; + +/** + * Flash control for camera module v2.4 and above. + */ +class FlashControl : public FlashControlBase { + public: + FlashControl(CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks); + virtual ~FlashControl(); + + // FlashControlBase + status_t hasFlashUnit(const String16& cameraId, bool *hasFlash); + status_t setTorchMode(const String16& cameraId, bool enabled); + + private: + CameraModule *mCameraModule; + + Mutex mLock; +}; + +/** + * Flash control for camera module <= v2.3 and camera HAL v2-v3 + */ +class CameraDeviceClientFlashControl : public FlashControlBase { + public: + CameraDeviceClientFlashControl(CameraModule& cameraModule, + const camera_module_callbacks_t& callbacks); + virtual ~CameraDeviceClientFlashControl(); + + // FlashControlBase + status_t setTorchMode(const String16& cameraId, bool enabled); + status_t hasFlashUnit(const String16& cameraId, bool *hasFlash); + + private: + // connect to a camera device + status_t connectCameraDevice(const String16& cameraId); + + // initialize a surface + status_t initializeSurface(int32_t width, int32_t height); + + // submit a request with the given torch mode + status_t submitTorchRequest(bool enabled); + + // get the smallest surface size of IMPLEMENTATION_DEFINED + status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width, + int32_t *height); + + status_t hasFlashUnitLocked(const String16& cameraId, bool *hasFlash); + + CameraModule *mCameraModule; + const camera_module_callbacks_t *mCallbacks; + String16 mCameraId; + bool mTorchEnabled; + CameraMetadata *mMetadata; + + sp mDevice; + + sp mProducer; + sp mConsumer; + sp mSurfaceTexture; + sp mAnw; + int32_t mStreamId; + + Mutex mLock; +}; + +} // namespace android + +#endif diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index f3cd9de..f35f7f0 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -86,6 +86,38 @@ static void camera_device_status_change( camera_id, new_status); } + +static void torch_mode_status_change( + const struct camera_module_callbacks* callbacks, + const char* camera_id, + int new_status) { + if (!callbacks || !camera_id) { + ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__, + callbacks, camera_id); + } + sp cs = const_cast( + static_cast(callbacks)); + + ICameraServiceListener::TorchStatus status; + switch (new_status) { + case TORCH_MODE_STATUS_AVAILABLE: + status = ICameraServiceListener::TORCH_STATUS_AVAILABLE; + break; + case TORCH_MODE_STATUS_RESOURCE_BUSY: + status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; + break; + case TORCH_MODE_STATUS_OFF: + status = ICameraServiceListener::TORCH_STATUS_OFF; + break; + default: + ALOGE("Unknown torch status %d", new_status); + return; + } + + cs->onTorchStatusChanged( + String16(camera_id), + status); +} } // extern "C" // ---------------------------------------------------------------------------- @@ -95,7 +127,7 @@ static void camera_device_status_change( static CameraService *gCameraService; CameraService::CameraService() - :mSoundRef(0), mModule(0) + :mSoundRef(0), mModule(0), mFlashlight(0) { ALOGI("CameraService started (pid=%d)", getpid()); gCameraService = this; @@ -105,6 +137,8 @@ CameraService::CameraService() } this->camera_device_status_change = android::camera_device_status_change; + this->torch_mode_status_change = android::torch_mode_status_change; + } void CameraService::onFirstRef() @@ -121,6 +155,8 @@ void CameraService::onFirstRef() } else { mModule = new CameraModule(rawModule); + mFlashlight = new CameraFlashlight(*mModule, *this); + const hw_module_t *common = mModule->getRawModule(); ALOGI("Loaded \"%s\" camera module", common->name); mNumberOfCameras = mModule->getNumberOfCameras(); @@ -131,6 +167,12 @@ void CameraService::onFirstRef() } for (int i = 0; i < mNumberOfCameras; i++) { setCameraFree(i); + + String16 cameraName = String16(String8::format("%d", i)); + if (mFlashlight->hasFlashUnit(cameraName)) { + mTorchStatusMap.add(cameraName, + ICameraServiceListener::TORCH_STATUS_AVAILABLE); + } } if (common->module_api_version >= CAMERA_MODULE_API_VERSION_2_1) { @@ -225,6 +267,37 @@ void CameraService::onDeviceStatusChanged(int cameraId, } +void CameraService::onTorchStatusChanged(const String16& cameraId, + ICameraServiceListener::TorchStatus newStatus) { + Mutex::Autolock al(mTorchStatusMutex); + onTorchStatusChangedLocked(cameraId, newStatus); +} + +void CameraService::onTorchStatusChangedLocked(const String16& cameraId, + ICameraServiceListener::TorchStatus newStatus) { + ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d", + __FUNCTION__, cameraId.string(), newStatus); + + if (getTorchStatusLocked(cameraId) == newStatus) { + ALOGE("%s: Torch state transition to the same status 0x%x not allowed", + __FUNCTION__, (uint32_t)newStatus); + return; + } + + status_t res = setTorchStatusLocked(cameraId, newStatus); + if (res) { + ALOGE("%s: Failed to set the torch status", __FUNCTION__, + (uint32_t)newStatus); + return; + } + + Vector >::const_iterator it; + for (it = mListenerList.begin(); it != mListenerList.end(); ++it) { + (*it)->onTorchStatusChanged(newStatus, cameraId); + } +} + + int32_t CameraService::getNumberOfCameras() { return mNumberOfCameras; } @@ -676,6 +749,9 @@ status_t CameraService::connectHelperLocked( int halVersion, bool legacyMode) { + // give flashlight a chance to close devices if necessary. + mFlashlight->prepareDeviceOpen(); + int facing = -1; int deviceVersion = getDeviceVersion(cameraId, &facing); @@ -852,6 +928,47 @@ status_t CameraService::connectLegacy( return OK; } +status_t CameraService::setTorchMode(const String16& cameraId, bool enabled, + const sp& clientBinder) { + if (enabled && clientBinder == NULL) { + ALOGE("%s: torch client binder is NULL", __FUNCTION__); + return -ENOSYS; + } + + Mutex::Autolock al(mTorchStatusMutex); + status_t res = mFlashlight->setTorchMode(cameraId, enabled); + if (res) { + ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__, + cameraId.string(), enabled); + return res; + } + + // update the link to client's death + ssize_t index = mTorchClientMap.indexOfKey(cameraId); + if (enabled) { + if (index == NAME_NOT_FOUND) { + mTorchClientMap.add(cameraId, clientBinder); + } else { + const sp oldBinder = mTorchClientMap.valueAt(index); + oldBinder->unlinkToDeath(this); + + mTorchClientMap.replaceValueAt(index, clientBinder); + } + clientBinder->linkToDeath(this); + } else if (index != NAME_NOT_FOUND) { + sp oldBinder = mTorchClientMap.valueAt(index); + oldBinder->unlinkToDeath(this); + } + + // notify the listeners the change. + ICameraServiceListener::TorchStatus status = enabled ? + ICameraServiceListener::TORCH_STATUS_ON : + ICameraServiceListener::TORCH_STATUS_OFF; + onTorchStatusChangedLocked(cameraId, status); + + return OK; +} + status_t CameraService::connectFinishUnsafe(const sp& client, const sp& remoteCallback) { status_t status = client->initialize(mModule); @@ -977,6 +1094,9 @@ status_t CameraService::connectDevice( int facing = -1; int deviceVersion = getDeviceVersion(cameraId, &facing); + // give flashlight a chance to close devices if necessary. + mFlashlight->prepareDeviceOpen(); + switch(deviceVersion) { case CAMERA_DEVICE_API_VERSION_1_0: ALOGW("Camera using old HAL version: %d", deviceVersion); @@ -1048,6 +1168,16 @@ status_t CameraService::addListener( } } + /* Immediately signal current torch status to this listener only */ + { + Mutex::Autolock al(mTorchStatusMutex); + for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) { + listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), + mTorchStatusMap.keyAt(i)); + } + + } + return OK; } status_t CameraService::removeListener( @@ -1724,6 +1854,23 @@ status_t CameraService::dump(int fd, const Vector& args) { return NO_ERROR; } +void CameraService::handleTorchClientBinderDied(const wp &who) { + Mutex::Autolock al(mTorchStatusMutex); + for (size_t i = 0; i < mTorchClientMap.size(); i++) { + if (mTorchClientMap[i] == who) { + // turn off the torch mode that was turned on by dead client + String16 cameraId = mTorchClientMap.keyAt(i); + mFlashlight->setTorchMode(cameraId, false); + mTorchClientMap.removeItemsAt(i); + + // notify torch mode was turned off + onTorchStatusChangedLocked(cameraId, + ICameraServiceListener::TORCH_STATUS_OFF); + break; + } + } +} + /*virtual*/void CameraService::binderDied( const wp &who) { @@ -1734,6 +1881,10 @@ status_t CameraService::dump(int fd, const Vector& args) { ALOGV("java clients' binder died"); + // check torch client + handleTorchClientBinderDied(who); + + // check camera device client sp cameraClient = getClientByRemote(who); if (cameraClient == 0) { @@ -1827,4 +1978,27 @@ ICameraServiceListener::Status CameraService::getStatus(int cameraId) const { return mStatusList[cameraId]; } +ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked( + const String16& cameraId) const { + ssize_t index = mTorchStatusMap.indexOfKey(cameraId); + if (index == NAME_NOT_FOUND) { + return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; + } + + return mTorchStatusMap.valueAt(index); +} + +status_t CameraService::setTorchStatusLocked(const String16& cameraId, + ICameraServiceListener::TorchStatus status) { + ssize_t index = mTorchStatusMap.indexOfKey(cameraId); + if (index == NAME_NOT_FOUND) { + return BAD_VALUE; + } + ICameraServiceListener::TorchStatus& item = + mTorchStatusMap.editValueAt(index); + item = status; + + return OK; +} + }; // namespace android diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 3f989c8..158825e 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -36,6 +36,8 @@ #include #include +#include "CameraFlashlight.h" + #include "common/CameraModule.h" @@ -70,6 +72,9 @@ public: // HAL Callbacks virtual void onDeviceStatusChanged(int cameraId, int newStatus); + virtual void onTorchStatusChanged(const String16& cameraId, + ICameraServiceListener::TorchStatus + newStatus); ///////////////////////////////////////////////////////////////////// // ICameraService @@ -112,6 +117,9 @@ public: /*out*/ String16* parameters); + virtual status_t setTorchMode(const String16& cameraId, bool enabled, + const sp& clientBinder); + // OK = supports api of that version, -EOPNOTSUPP = does not support virtual status_t supportsCameraApi( int cameraId, int apiVersion); @@ -408,6 +416,32 @@ private: int32_t cameraId, const StatusVector *rejectSourceStates = NULL); + // flashlight control + sp mFlashlight; + // guard mTorchStatusMap and mTorchClientMap + Mutex mTorchStatusMutex; + // camera id -> torch status + KeyedVector mTorchStatusMap; + // camera id -> torch client binder + // only store the last client that turns on each camera's torch mode + KeyedVector > mTorchClientMap; + + // check and handle if torch client's process has died + void handleTorchClientBinderDied(const wp &who); + + // handle torch mode status change and invoke callbacks. mTorchStatusMutex + // should be locked. + void onTorchStatusChangedLocked(const String16& cameraId, + ICameraServiceListener::TorchStatus newStatus); + + // get a camera's torch status. mTorchStatusMutex should be locked. + ICameraServiceListener::TorchStatus getTorchStatusLocked( + const String16 &cameraId) const; + + // set a camera's torch status. mTorchStatusMutex should be locked. + status_t setTorchStatusLocked(const String16 &cameraId, + ICameraServiceListener::TorchStatus status); + // IBinder::DeathRecipient implementation virtual void binderDied(const wp &who); -- cgit v1.1 From 4f2a5eb6a861f09a458ab2530e7a64b1b9411bb1 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 13 Feb 2015 13:25:39 -0800 Subject: Look up user-specific device policy for disabling camera Camera can be disabled on a per-user basis by device admins. Changed the system property format to be per-user so that the policy can be applied based on calling user. TODO: Ideally this policy information should be pulled from the DevicePolicyManager rather than relying on system properties. Property changes will not be applied immediately either, if there's no listener. Bug: 19345698 Change-Id: Ia00034726260bc9ff28ac592f20a27b5c9a77d58 --- services/camera/libcameraservice/CameraService.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index f35f7f0..e2747ad 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -670,7 +671,10 @@ status_t CameraService::validateConnect(int cameraId, } char value[PROPERTY_VALUE_MAX]; - property_get("sys.secpolicy.camera.disabled", value, "0"); + char key[PROPERTY_KEY_MAX]; + int clientUserId = multiuser_get_user_id(clientUid); + snprintf(key, PROPERTY_KEY_MAX, "sys.secpolicy.camera.off_%d", clientUserId); + property_get(key, value, "0"); if (strcmp(value, "1") == 0) { // Camera is disabled by DevicePolicyManager. ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); -- cgit v1.1 From c30e34c11e987c8661d7f0da4c98873a257d9df4 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Wed, 18 Feb 2015 14:42:16 -0800 Subject: CameraService: fix invalid access of camera metadata static_camera_characteristics is not defined in API1. Change-Id: I422953081b0a5581e12fc4b16052b67ca8062186 --- services/camera/libcameraservice/common/CameraModule.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp index bbf47e8..85a4df9 100644 --- a/services/camera/libcameraservice/common/CameraModule.cpp +++ b/services/camera/libcameraservice/common/CameraModule.cpp @@ -66,6 +66,12 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { return -EINVAL; } + // Only override static_camera_characteristics for API2 devices + int apiVersion = mModule->common.module_api_version; + if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) { + return mModule->get_camera_info(cameraId, info); + } + camera_info &wrappedInfo = mCameraInfo[cameraId]; if (!mCameraInfoCached[cameraId]) { camera_info rawInfo; @@ -75,14 +81,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { } CameraMetadata &m = mCameraCharacteristics[cameraId]; m = rawInfo.static_camera_characteristics; - int deviceVersion; - int apiVersion = mModule->common.module_api_version; - if (apiVersion >= CAMERA_MODULE_API_VERSION_2_0) { - deviceVersion = rawInfo.device_version; - } else { - deviceVersion = CAMERA_DEVICE_API_VERSION_1_0; - } - deriveCameraCharacteristicsKeys(deviceVersion, m); + deriveCameraCharacteristicsKeys(rawInfo.device_version, m); wrappedInfo = rawInfo; wrappedInfo.static_camera_characteristics = m.getAndLock(); mCameraInfoCached[cameraId] = true; -- cgit v1.1 From 297344faa3c908bb932bdee6197770f21eddc2fb Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Thu, 19 Feb 2015 16:26:13 -0800 Subject: Camera: Remove RAW_SENSOR in favor of RAW16 Change-Id: I69ca24c69f58be958efdef300b127401d2b2e880 --- camera/CameraParameters.cpp | 2 +- camera/tests/ProCameraTests.cpp | 2 +- services/camera/libcameraservice/api1/Camera2Client.cpp | 2 +- services/camera/libcameraservice/api1/client2/Parameters.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp index e5e4e90..3dbf75e 100644 --- a/camera/CameraParameters.cpp +++ b/camera/CameraParameters.cpp @@ -526,7 +526,7 @@ int CameraParameters::previewFormatToEnum(const char* format) { !strcmp(format, PIXEL_FORMAT_RGBA8888) ? HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888 !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ? - HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data + HAL_PIXEL_FORMAT_RAW16 : // Raw sensor data -1; } diff --git a/camera/tests/ProCameraTests.cpp b/camera/tests/ProCameraTests.cpp index 6212678..24b2327 100644 --- a/camera/tests/ProCameraTests.cpp +++ b/camera/tests/ProCameraTests.cpp @@ -475,7 +475,7 @@ protected: CMP_STR(NV16, YCbCr_422_SP); CMP_STR(NV21, YCrCb_420_SP); CMP_STR(YUY2, YCbCr_422_I); - CMP_STR(RAW, RAW_SENSOR); + CMP_STR(RAW, RAW16); CMP_STR(RGBA, RGBA_8888); std::cerr << "Unknown format string " << str << std::endl; diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index c129f6f..5c631b1 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -1958,7 +1958,7 @@ size_t Camera2Client::calculateBufferSize(int width, int height, return width * height * 2; case HAL_PIXEL_FORMAT_RGBA_8888: return width * height * 4; - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: return width * height * 2; default: ALOGE("%s: Unknown preview format: %x", diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 4f4cfb0..87e0132 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -182,9 +182,9 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) { supportedPreviewFormats += CameraParameters::PIXEL_FORMAT_YUV420SP; break; - // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats + // Not advertizing JPEG, RAW16, etc, for preview formats case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: case HAL_PIXEL_FORMAT_BLOB: addComma = false; break; @@ -2253,7 +2253,7 @@ const char* Parameters::formatEnumToString(int format) { case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888; break; - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: ALOGW("Raw sensor preview format requested."); fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB; break; -- cgit v1.1 From e7b35129d40df50cd8b3d6ba03662996b636dcde Mon Sep 17 00:00:00 2001 From: Chien-Yu Chen Date: Tue, 17 Feb 2015 13:56:46 -0800 Subject: camera: fix flashlight implementation for HAL v2 Update torch availability when the camera device availability changes. For device HAL v2 and v3 implementation, notify torch unavailable for all camera devices with a flash unit when a camera device is opened. Notify torch available for all camera devices with flash unit when all camera devices are closed. Don't invoke torch status callback in camera service. Invoke torch status callback in HAL or FlashControlBase implementations to avoid race condition. Clean up previous CL. Bug: 2682206 Change-Id: I24f5478f467b2c680565fe98f112eef33e2547a1 --- include/camera/ICameraService.h | 11 +- include/camera/ICameraServiceListener.h | 18 +- .../camera/libcameraservice/CameraFlashlight.cpp | 330 ++++++++++++++------- .../camera/libcameraservice/CameraFlashlight.h | 72 +++-- services/camera/libcameraservice/CameraService.cpp | 201 +++++++++---- services/camera/libcameraservice/CameraService.h | 21 +- 6 files changed, 443 insertions(+), 210 deletions(-) diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index cc41efe..194a646 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -145,7 +145,16 @@ public: sp& device) = 0; /** - * Turn on or off a camera's torch mode. + * Turn on or off a camera's torch mode. Torch mode will be turned off by + * camera service if the lastest client binder that turns it on dies. + * + * return values: + * 0: on a successful operation. + * -ENOSYS: the camera device doesn't support this operation. It it returned + * if and only if android.flash.into.available is false. + * -EBUSY: the camera device is opened. + * -EINVAL: camera_id is invalid or clientBinder is NULL when enabling a + * torch mode. */ virtual status_t setTorchMode(const String16& cameraId, bool enabled, const sp& clientBinder) = 0; diff --git a/include/camera/ICameraServiceListener.h b/include/camera/ICameraServiceListener.h index 9e8b912..709ff31 100644 --- a/include/camera/ICameraServiceListener.h +++ b/include/camera/ICameraServiceListener.h @@ -71,18 +71,20 @@ public: * * Initial status will be transmitted with onTorchStatusChanged immediately * after this listener is added to the service listener list. + * + * The enums should be set to values matching + * include/hardware/camera_common.h */ enum TorchStatus { - // The camera's torch mode has become available to use via - // setTorchMode(). - TORCH_STATUS_AVAILABLE = TORCH_MODE_STATUS_AVAILABLE, // The camera's torch mode has become not available to use via // setTorchMode(). - TORCH_STATUS_NOT_AVAILABLE = TORCH_MODE_STATUS_RESOURCE_BUSY, - // The camera's torch mode has been turned off by setTorchMode(). - TORCH_STATUS_OFF = TORCH_MODE_STATUS_OFF, - // The camera's torch mode has been turned on by setTorchMode(). - TORCH_STATUS_ON = 0x80000000, + TORCH_STATUS_NOT_AVAILABLE = TORCH_MODE_STATUS_NOT_AVAILABLE, + // The camera's torch mode is off and available to be turned on via + // setTorchMode(). + TORCH_STATUS_AVAILABLE_OFF = TORCH_MODE_STATUS_AVAILABLE_OFF, + // The camera's torch mode is on and available to be turned off via + // setTorchMode(). + TORCH_STATUS_AVAILABLE_ON = TORCH_MODE_STATUS_AVAILABLE_ON, // Use to initialize variables only TORCH_STATUS_UNKNOWN = 0xFFFFFFFF, diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp index 00a70eb..a00a49f 100644 --- a/services/camera/libcameraservice/CameraFlashlight.cpp +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "CameraFlashlight" #define ATRACE_TAG ATRACE_TAG_CAMERA -#define LOG_NDEBUG 0 +// #define LOG_NDEBUG 0 #include #include @@ -32,16 +32,21 @@ namespace android { +///////////////////////////////////////////////////////////////////// +// CameraFlashlight implementation begins +// used by camera service to control flashflight. +///////////////////////////////////////////////////////////////////// CameraFlashlight::CameraFlashlight(CameraModule& cameraModule, const camera_module_callbacks_t& callbacks) : mCameraModule(&cameraModule), - mCallbacks(&callbacks) { + mCallbacks(&callbacks), + mFlashlightMapInitialized(false) { } CameraFlashlight::~CameraFlashlight() { } -status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { +status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__, cameraId.string()); if (mFlashControl != NULL) { @@ -52,7 +57,7 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { if (mCameraModule->getRawModule()->module_api_version >= CAMERA_MODULE_API_VERSION_2_4) { - mFlashControl = new FlashControl(*mCameraModule, *mCallbacks); + mFlashControl = new ModuleFlashControl(*mCameraModule, *mCallbacks); if (mFlashControl == NULL) { ALOGV("%s: cannot create flash control for module api v2.4+", __FUNCTION__); @@ -67,7 +72,7 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { res = mCameraModule->getCameraInfo( atoi(String8(cameraId).string()), &info); if (res) { - ALOGV("%s: failed to get camera info for camera %s", + ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, cameraId.string()); return res; } @@ -83,8 +88,7 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { } mFlashControl = flashControl; - } - else { + } else { // todo: implement for device api 1 return INVALID_OPERATION; } @@ -93,8 +97,9 @@ status_t CameraFlashlight::createFlashlightControl(const String16& cameraId) { return OK; } -status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) { - if (!mCameraModule) { +status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) { + if (!mFlashlightMapInitialized) { + ALOGE("%s: findFlashUnits() must be called before this method."); return NO_INIT; } @@ -105,6 +110,10 @@ status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) Mutex::Autolock l(mLock); if (mFlashControl == NULL) { + if (enabled == false) { + return OK; + } + res = createFlashlightControl(cameraId); if (res) { return res; @@ -130,88 +139,169 @@ status_t CameraFlashlight::setTorchMode(const String16& cameraId, bool enabled) return res; } -bool CameraFlashlight::hasFlashUnit(const String16& cameraId) { +status_t CameraFlashlight::findFlashUnits() { + Mutex::Autolock l(mLock); status_t res; + int32_t numCameras = mCameraModule->getNumberOfCameras(); - Mutex::Autolock l(mLock); + mHasFlashlightMap.clear(); + mFlashlightMapInitialized = false; - if (mFlashControl == NULL) { - res = createFlashlightControl(cameraId); + for (int32_t i = 0; i < numCameras; i++) { + bool hasFlash = false; + String8 id = String8::format("%d", i); + + res = createFlashlightControl(id); if (res) { - ALOGE("%s: failed to create flash control for %s ", - __FUNCTION__, cameraId.string()); - return false; + ALOGE("%s: failed to create flash control for %s", __FUNCTION__, + id.string()); + } else { + res = mFlashControl->hasFlashUnit(id, &hasFlash); + if (res == -EUSERS || res == -EBUSY) { + ALOGE("%s: failed to check if camera %s has a flash unit. Some " + "camera devices may be opened", __FUNCTION__, + id.string()); + return res; + } else if (res) { + ALOGE("%s: failed to check if camera %s has a flash unit. %s" + " (%d)", __FUNCTION__, id.string(), strerror(-res), + res); + } + + mFlashControl.clear(); } + mHasFlashlightMap.add(id, hasFlash); } - bool flashUnit = false; + mFlashlightMapInitialized = true; + return OK; +} - // if flash control already exists, querying if a camera device has a flash - // unit may fail if it's module v1 - res = mFlashControl->hasFlashUnit(cameraId, &flashUnit); - if (res == BAD_INDEX) { - // need to close the flash control before query. - mFlashControl.clear(); - res = createFlashlightControl(cameraId); - if (res) { - ALOGE("%s: failed to create flash control for %s ", __FUNCTION__, - cameraId.string()); - return false; - } - res = mFlashControl->hasFlashUnit(cameraId, &flashUnit); - if (res) { - flashUnit = false; - } +bool CameraFlashlight::hasFlashUnit(const String8& cameraId) { + status_t res; + + Mutex::Autolock l(mLock); + return hasFlashUnitLocked(cameraId); +} + +bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) { + if (!mFlashlightMapInitialized) { + ALOGE("%s: findFlashUnits() must be called before this method."); + return false; } - return flashUnit; + ssize_t index = mHasFlashlightMap.indexOfKey(cameraId); + if (index == NAME_NOT_FOUND) { + ALOGE("%s: camera %s not present when findFlashUnits() was called", + __FUNCTION__, cameraId.string()); + return false; + } + + return mHasFlashlightMap.valueAt(index); } -status_t CameraFlashlight::prepareDeviceOpen() { +status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) { ALOGV("%s: prepare for device open", __FUNCTION__); Mutex::Autolock l(mLock); + if (!mFlashlightMapInitialized) { + ALOGE("%s: findFlashUnits() must be called before this method."); + return NO_INIT; + } - if (mCameraModule && mCameraModule->getRawModule()->module_api_version < + if (mCameraModule->getRawModule()->module_api_version < CAMERA_MODULE_API_VERSION_2_4) { // framework is going to open a camera device, all flash light control // should be closed for backward compatible support. - if (mFlashControl != NULL) { - mFlashControl.clear(); + mFlashControl.clear(); + + if (mOpenedCameraIds.size() == 0) { + // notify torch unavailable for all cameras with a flash + int numCameras = mCameraModule->getNumberOfCameras(); + for (int i = 0; i < numCameras; i++) { + if (hasFlashUnitLocked(String8::format("%d", i))) { + mCallbacks->torch_mode_status_change(mCallbacks, + String8::format("%d", i).string(), + TORCH_MODE_STATUS_NOT_AVAILABLE); + } + } } + + // close flash control that may be opened by calling hasFlashUnitLocked. + mFlashControl.clear(); + } + + if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) { + mOpenedCameraIds.add(cameraId); } return OK; } +status_t CameraFlashlight::deviceClosed(const String8& cameraId) { + ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string()); -FlashControlBase::~FlashControlBase() { + Mutex::Autolock l(mLock); + if (!mFlashlightMapInitialized) { + ALOGE("%s: findFlashUnits() must be called before this method."); + return NO_INIT; + } + + ssize_t index = mOpenedCameraIds.indexOf(cameraId); + if (index == NAME_NOT_FOUND) { + ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__, + cameraId.string()); + } else { + mOpenedCameraIds.removeAt(index); + } + + // Cannot do anything until all cameras are closed. + if (mOpenedCameraIds.size() != 0) + return OK; + + if (mCameraModule->getRawModule()->module_api_version < + CAMERA_MODULE_API_VERSION_2_4) { + // notify torch available for all cameras with a flash + int numCameras = mCameraModule->getNumberOfCameras(); + for (int i = 0; i < numCameras; i++) { + if (hasFlashUnitLocked(String8::format("%d", i))) { + mCallbacks->torch_mode_status_change(mCallbacks, + String8::format("%d", i).string(), + TORCH_MODE_STATUS_AVAILABLE_OFF); + } + } + } + + return OK; } +// CameraFlashlight implementation ends -FlashControl::FlashControl(CameraModule& cameraModule, +FlashControlBase::~FlashControlBase() { +} + +///////////////////////////////////////////////////////////////////// +// ModuleFlashControl implementation begins +// Flash control for camera module v2.4 and above. +///////////////////////////////////////////////////////////////////// +ModuleFlashControl::ModuleFlashControl(CameraModule& cameraModule, const camera_module_callbacks_t& callbacks) : mCameraModule(&cameraModule) { } -FlashControl::~FlashControl() { +ModuleFlashControl::~ModuleFlashControl() { } -status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) { +status_t ModuleFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) { if (!hasFlash) { return BAD_VALUE; } *hasFlash = false; - Mutex::Autolock l(mLock); - if (!mCameraModule) { - return NO_INIT; - } - camera_info info; - status_t res = mCameraModule->getCameraInfo(atoi(String8(cameraId).string()), + status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); if (res != 0) { return res; @@ -228,33 +318,31 @@ status_t FlashControl::hasFlashUnit(const String16& cameraId, bool *hasFlash) { return OK; } -status_t FlashControl::setTorchMode(const String16& cameraId, bool enabled) { +status_t ModuleFlashControl::setTorchMode(const String8& cameraId, bool enabled) { ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__, cameraId.string(), enabled); Mutex::Autolock l(mLock); - if (!mCameraModule) { - return NO_INIT; - } - - return mCameraModule->setTorchMode(String8(cameraId).string(), enabled); + return mCameraModule->setTorchMode(cameraId.string(), enabled); } +// ModuleFlashControl implementation ends +///////////////////////////////////////////////////////////////////// +// CameraDeviceClientFlashControl implementation begins +// Flash control for camera module <= v2.3 and camera HAL v2-v3 +///////////////////////////////////////////////////////////////////// CameraDeviceClientFlashControl::CameraDeviceClientFlashControl( CameraModule& cameraModule, const camera_module_callbacks_t& callbacks) : mCameraModule(&cameraModule), mCallbacks(&callbacks), mTorchEnabled(false), - mMetadata(NULL) { + mMetadata(NULL), + mStreaming(false) { } CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { - if (mDevice != NULL) { - mDevice->flush(); - mDevice->deleteStream(mStreamId); - mDevice.clear(); - } + disconnectCameraDevice(); if (mMetadata) { delete mMetadata; } @@ -269,13 +357,13 @@ CameraDeviceClientFlashControl::~CameraDeviceClientFlashControl() { ALOGV("%s: notify the framework that torch was turned off", __FUNCTION__); mCallbacks->torch_mode_status_change(mCallbacks, - String8(mCameraId).string(), TORCH_MODE_STATUS_OFF); + mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF); } } } -status_t CameraDeviceClientFlashControl::initializeSurface(int32_t width, - int32_t height) { +status_t CameraDeviceClientFlashControl::initializeSurface( + sp &device, int32_t width, int32_t height) { status_t res; BufferQueue::createBufferQueue(&mProducer, &mConsumer); @@ -295,27 +383,16 @@ status_t CameraDeviceClientFlashControl::initializeSurface(int32_t width, return res; } - bool useAsync = false; - int32_t consumerUsage; - res = mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage); - if (res) { - return res; - } - - if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) { - useAsync = true; - } - - mAnw = new Surface(mProducer, useAsync); + mAnw = new Surface(mProducer, /*useAsync*/ true); if (mAnw == NULL) { return NO_MEMORY; } - res = mDevice->createStream(mAnw, width, height, format, &mStreamId); + res = device->createStream(mAnw, width, height, format, &mStreamId); if (res) { return res; } - res = mDevice->configureStreams(); + res = device->configureStreams(); if (res) { return res; } @@ -342,7 +419,21 @@ status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( int32_t ww = streamConfigs.data.i32[i + 1]; int32_t hh = streamConfigs.data.i32[i + 2]; - if (w* h > ww * hh) { + if (w * h > ww * hh) { + w = ww; + h = hh; + } + } + } + + // if stream configuration is not found, try available processed sizes. + if (streamConfigs.count == 0) { + camera_metadata_entry availableProcessedSizes = + metadata.find(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES); + for (size_t i = 0; i < availableProcessedSizes.count; i += 2) { + int32_t ww = availableProcessedSizes.data.i32[i]; + int32_t hh = availableProcessedSizes.data.i32[i + 1]; + if (w * h > ww * hh) { w = ww; h = hh; } @@ -360,24 +451,24 @@ status_t CameraDeviceClientFlashControl::getSmallestSurfaceSize( } status_t CameraDeviceClientFlashControl::connectCameraDevice( - const String16& cameraId) { - String8 id = String8(cameraId); + const String8& cameraId) { camera_info info; - status_t res = mCameraModule->getCameraInfo(atoi(id.string()), &info); + status_t res = mCameraModule->getCameraInfo(atoi(cameraId.string()), &info); if (res != 0) { ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, - mCameraId.string()); + cameraId.string()); return res; } - mDevice = CameraDeviceFactory::createDevice(atoi(id.string())); - if (mDevice == NULL) { + sp device = + CameraDeviceFactory::createDevice(atoi(cameraId.string())); + if (device == NULL) { return NO_MEMORY; } - res = mDevice->initialize(mCameraModule); + res = device->initialize(mCameraModule); if (res) { - goto fail; + return res; } int32_t width, height; @@ -385,22 +476,30 @@ status_t CameraDeviceClientFlashControl::connectCameraDevice( if (res) { return res; } - res = initializeSurface(width, height); + res = initializeSurface(device, width, height); if (res) { - goto fail; + return res; } mCameraId = cameraId; + mStreaming = (info.device_version <= CAMERA_DEVICE_API_VERSION_3_1); + mDevice = device; return OK; +} -fail: - mDevice.clear(); - return res; +status_t CameraDeviceClientFlashControl::disconnectCameraDevice() { + if (mDevice != NULL) { + mDevice->disconnect(); + mDevice.clear(); + } + + return OK; } -status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId, + +status_t CameraDeviceClientFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) { ALOGV("%s: checking if camera %s has a flash unit", __FUNCTION__, cameraId.string()); @@ -411,19 +510,14 @@ status_t CameraDeviceClientFlashControl::hasFlashUnit(const String16& cameraId, } status_t CameraDeviceClientFlashControl::hasFlashUnitLocked( - const String16& cameraId, bool *hasFlash) { - if (!mCameraModule) { - ALOGE("%s: camera module is NULL", __FUNCTION__); - return NO_INIT; - } - + const String8& cameraId, bool *hasFlash) { if (!hasFlash) { return BAD_VALUE; } camera_info info; status_t res = mCameraModule->getCameraInfo( - atoi(String8(cameraId).string()), &info); + atoi(cameraId.string()), &info); if (res != 0) { ALOGE("%s: failed to get camera info for camera %s", __FUNCTION__, cameraId.string()); @@ -441,7 +535,7 @@ status_t CameraDeviceClientFlashControl::hasFlashUnitLocked( return OK; } -status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) { +status_t CameraDeviceClientFlashControl::submitTorchEnabledRequest() { status_t res; if (mMetadata == NULL) { @@ -456,27 +550,29 @@ status_t CameraDeviceClientFlashControl::submitTorchRequest(bool enabled) { } } - uint8_t torchOn = enabled ? ANDROID_FLASH_MODE_TORCH : - ANDROID_FLASH_MODE_OFF; - + uint8_t torchOn = ANDROID_FLASH_MODE_TORCH; mMetadata->update(ANDROID_FLASH_MODE, &torchOn, 1); mMetadata->update(ANDROID_REQUEST_OUTPUT_STREAMS, &mStreamId, 1); + uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; + mMetadata->update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); + int32_t requestId = 0; mMetadata->update(ANDROID_REQUEST_ID, &requestId, 1); - List metadataRequestList; - metadataRequestList.push_back(*mMetadata); - - int64_t lastFrameNumber = 0; - res = mDevice->captureList(metadataRequestList, &lastFrameNumber); - + if (mStreaming) { + res = mDevice->setStreamingRequest(*mMetadata); + } else { + res = mDevice->capture(*mMetadata); + } return res; } + + status_t CameraDeviceClientFlashControl::setTorchMode( - const String16& cameraId, bool enabled) { + const String8& cameraId, bool enabled) { bool hasFlash = false; Mutex::Autolock l(mLock); @@ -499,6 +595,13 @@ status_t CameraDeviceClientFlashControl::setTorchMode( } 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; } if (mDevice == NULL) { @@ -508,13 +611,16 @@ status_t CameraDeviceClientFlashControl::setTorchMode( } } - res = submitTorchRequest(enabled); + res = submitTorchEnabledRequest(); if (res) { return res; } - mTorchEnabled = enabled; + mTorchEnabled = true; + mCallbacks->torch_mode_status_change(mCallbacks, + cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON); return OK; } +// CameraDeviceClientFlashControl implementation ends } diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h index a0de0b0..ae502b9 100644 --- a/services/camera/libcameraservice/CameraFlashlight.h +++ b/services/camera/libcameraservice/CameraFlashlight.h @@ -19,6 +19,7 @@ #include "hardware/camera_common.h" #include "utils/KeyedVector.h" +#include "utils/SortedVector.h" #include "gui/GLConsumer.h" #include "gui/Surface.h" #include "common/CameraDeviceBase.h" @@ -37,11 +38,11 @@ class FlashControlBase : public virtual VirtualLightRefBase { // cause the torch mode to be turned off in HAL v1 devices. If // previously-on torch mode is turned off, // callbacks.torch_mode_status_change() should be invoked. - virtual status_t hasFlashUnit(const String16& cameraId, + virtual status_t hasFlashUnit(const String8& cameraId, bool *hasFlash) = 0; // set the torch mode to on or off. - virtual status_t setTorchMode(const String16& cameraId, + virtual status_t setTorchMode(const String8& cameraId, bool enabled) = 0; }; @@ -54,43 +55,61 @@ class CameraFlashlight : public virtual VirtualLightRefBase { const camera_module_callbacks_t& callbacks); virtual ~CameraFlashlight(); - // set the torch mode to on or off. - status_t setTorchMode(const String16& cameraId, bool enabled); + // Find all flash units. This must be called before other methods. All + // camera devices must be closed when it's called because HAL v1 devices + // need to be opened to query available flash modes. + status_t findFlashUnits(); - // Whether a camera device has a flash unit. Calling this function may - // cause the torch mode to be turned off in HAL v1 devices. - bool hasFlashUnit(const String16& cameraId); + // Whether a camera device has a flash unit. Before findFlashUnits() is + // called, this function always returns false. + bool hasFlashUnit(const String8& cameraId); + + // set the torch mode to on or off. + status_t setTorchMode(const String8& cameraId, bool enabled); // Notify CameraFlashlight that camera service is going to open a camera // device. CameraFlashlight will free the resources that may cause the // camera open to fail. Camera service must call this function before // opening a camera device. - status_t prepareDeviceOpen(); + status_t prepareDeviceOpen(const String8& cameraId); + + // Notify CameraFlashlight that camera service has closed a camera + // device. CameraFlashlight may invoke callbacks for torch mode + // available depending on the implementation. + status_t deviceClosed(const String8& cameraId); private: // create flashlight control based on camera module API and camera // device API versions. - status_t createFlashlightControl(const String16& cameraId); + status_t createFlashlightControl(const String8& cameraId); + + // mLock should be locked. + bool hasFlashUnitLocked(const String8& cameraId); sp mFlashControl; CameraModule *mCameraModule; const camera_module_callbacks_t *mCallbacks; + SortedVector mOpenedCameraIds; - Mutex mLock; + // camera id -> if it has a flash unit + KeyedVector mHasFlashlightMap; + bool mFlashlightMapInitialized; + + Mutex mLock; // protect CameraFlashlight API }; /** * Flash control for camera module v2.4 and above. */ -class FlashControl : public FlashControlBase { +class ModuleFlashControl : public FlashControlBase { public: - FlashControl(CameraModule& cameraModule, + ModuleFlashControl(CameraModule& cameraModule, const camera_module_callbacks_t& callbacks); - virtual ~FlashControl(); + virtual ~ModuleFlashControl(); // FlashControlBase - status_t hasFlashUnit(const String16& cameraId, bool *hasFlash); - status_t setTorchMode(const String16& cameraId, bool enabled); + status_t hasFlashUnit(const String8& cameraId, bool *hasFlash); + status_t setTorchMode(const String8& cameraId, bool enabled); private: CameraModule *mCameraModule; @@ -108,30 +127,37 @@ class CameraDeviceClientFlashControl : public FlashControlBase { virtual ~CameraDeviceClientFlashControl(); // FlashControlBase - status_t setTorchMode(const String16& cameraId, bool enabled); - status_t hasFlashUnit(const String16& cameraId, bool *hasFlash); + 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 String16& cameraId); + status_t connectCameraDevice(const String8& cameraId); + // disconnect and free mDevice + status_t disconnectCameraDevice(); // initialize a surface - status_t initializeSurface(int32_t width, int32_t height); + status_t initializeSurface(sp& device, int32_t width, + int32_t height); - // submit a request with the given torch mode - status_t submitTorchRequest(bool enabled); + // submit a request to enable the torch mode + status_t submitTorchEnabledRequest(); // get the smallest surface size of IMPLEMENTATION_DEFINED status_t getSmallestSurfaceSize(const camera_info& info, int32_t *width, int32_t *height); - status_t hasFlashUnitLocked(const String16& cameraId, bool *hasFlash); + status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash); CameraModule *mCameraModule; const camera_module_callbacks_t *mCallbacks; - String16 mCameraId; + String8 mCameraId; bool mTorchEnabled; CameraMetadata *mMetadata; + // WORKAROUND: will be set to true for HAL v2 devices where + // setStreamingRequest() needs to be call for torch mode settings to + // take effect. + bool mStreaming; sp mDevice; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index e2747ad..7b8314c 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -101,14 +101,14 @@ static void torch_mode_status_change( ICameraServiceListener::TorchStatus status; switch (new_status) { - case TORCH_MODE_STATUS_AVAILABLE: - status = ICameraServiceListener::TORCH_STATUS_AVAILABLE; - break; - case TORCH_MODE_STATUS_RESOURCE_BUSY: + case TORCH_MODE_STATUS_NOT_AVAILABLE: status = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; break; - case TORCH_MODE_STATUS_OFF: - status = ICameraServiceListener::TORCH_STATUS_OFF; + case TORCH_MODE_STATUS_AVAILABLE_OFF: + status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF; + break; + case TORCH_MODE_STATUS_AVAILABLE_ON: + status = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON; break; default: ALOGE("Unknown torch status %d", new_status); @@ -116,7 +116,7 @@ static void torch_mode_status_change( } cs->onTorchStatusChanged( - String16(camera_id), + String8(camera_id), status); } } // extern "C" @@ -156,23 +156,29 @@ void CameraService::onFirstRef() } else { mModule = new CameraModule(rawModule); - mFlashlight = new CameraFlashlight(*mModule, *this); - const hw_module_t *common = mModule->getRawModule(); - ALOGI("Loaded \"%s\" camera module", common->name); + ALOGI("Loaded \"%s\" cameraCa module", common->name); mNumberOfCameras = mModule->getNumberOfCameras(); if (mNumberOfCameras > MAX_CAMERAS) { ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", mNumberOfCameras, MAX_CAMERAS); mNumberOfCameras = MAX_CAMERAS; } + + mFlashlight = new CameraFlashlight(*mModule, *this); + status_t res = mFlashlight->findFlashUnits(); + if (res) { + // impossible because we haven't open any camera devices. + ALOGE("failed to find flash units."); + } + for (int i = 0; i < mNumberOfCameras; i++) { setCameraFree(i); - String16 cameraName = String16(String8::format("%d", i)); + String8 cameraName = String8::format("%d", i); if (mFlashlight->hasFlashUnit(cameraName)) { mTorchStatusMap.add(cameraName, - ICameraServiceListener::TORCH_STATUS_AVAILABLE); + ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF); } } @@ -207,7 +213,7 @@ CameraService::~CameraService() { void CameraService::onDeviceStatusChanged(int cameraId, int newStatus) { - ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__, + ALOGV("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__, cameraId, newStatus); if (cameraId < 0 || cameraId >= MAX_CAMERAS) { @@ -268,24 +274,30 @@ void CameraService::onDeviceStatusChanged(int cameraId, } -void CameraService::onTorchStatusChanged(const String16& cameraId, +void CameraService::onTorchStatusChanged(const String8& cameraId, ICameraServiceListener::TorchStatus newStatus) { Mutex::Autolock al(mTorchStatusMutex); onTorchStatusChangedLocked(cameraId, newStatus); } -void CameraService::onTorchStatusChangedLocked(const String16& cameraId, +void CameraService::onTorchStatusChangedLocked(const String8& cameraId, ICameraServiceListener::TorchStatus newStatus) { ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d", __FUNCTION__, cameraId.string(), newStatus); - if (getTorchStatusLocked(cameraId) == newStatus) { + ICameraServiceListener::TorchStatus status; + status_t res = getTorchStatusLocked(cameraId, &status); + if (res) { + ALOGE("%s: cannot get torch status of camera %s", cameraId.string()); + return; + } + if (status == newStatus) { ALOGE("%s: Torch state transition to the same status 0x%x not allowed", __FUNCTION__, (uint32_t)newStatus); return; } - status_t res = setTorchStatusLocked(cameraId, newStatus); + res = setTorchStatusLocked(cameraId, newStatus); if (res) { ALOGE("%s: Failed to set the torch status", __FUNCTION__, (uint32_t)newStatus); @@ -294,7 +306,7 @@ void CameraService::onTorchStatusChangedLocked(const String16& cameraId, Vector >::const_iterator it; for (it = mListenerList.begin(); it != mListenerList.end(); ++it) { - (*it)->onTorchStatusChanged(newStatus, cameraId); + (*it)->onTorchStatusChanged(newStatus, String16(cameraId.string())); } } @@ -754,7 +766,7 @@ status_t CameraService::connectHelperLocked( bool legacyMode) { // give flashlight a chance to close devices if necessary. - mFlashlight->prepareDeviceOpen(); + mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId)); int facing = -1; int deviceVersion = getDeviceVersion(cameraId, &facing); @@ -932,44 +944,94 @@ status_t CameraService::connectLegacy( return OK; } +bool CameraService::validCameraIdForSetTorchMode(const String8& cameraId) { + // invalid string for int + if (cameraId.string() == NULL) { + return false; + } + errno = 0; + char *endptr; + long id = strtol(cameraId.string(), &endptr, 10); // base 10 + if (errno || id > INT_MAX || id < INT_MIN || *endptr != 0) { + return false; + } + + // id matches one of the plugged-in devices? + ICameraServiceListener::Status deviceStatus = getStatus(id); + if (deviceStatus != ICameraServiceListener::STATUS_PRESENT && + deviceStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) { + return false; + } + + return true; +} + status_t CameraService::setTorchMode(const String16& cameraId, bool enabled, const sp& clientBinder) { if (enabled && clientBinder == NULL) { ALOGE("%s: torch client binder is NULL", __FUNCTION__); - return -ENOSYS; + return -EINVAL; } - Mutex::Autolock al(mTorchStatusMutex); - status_t res = mFlashlight->setTorchMode(cameraId, enabled); + String8 id = String8(cameraId.string()); + + // verify id is valid. + if (validCameraIdForSetTorchMode(id) == false) { + ALOGE("%s: camera id is invalid %s", id.string()); + return -EINVAL; + } + + { + Mutex::Autolock al(mTorchStatusMutex); + ICameraServiceListener::TorchStatus status; + status_t res = getTorchStatusLocked(id, &status); + if (res) { + ALOGE("%s: getting current torch status failed for camera %s", + __FUNCTION__, id.string()); + return -EINVAL; + } + + if (status == ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE) { + if (getStatus(atoi(id.string())) == + ICameraServiceListener::STATUS_NOT_AVAILABLE) { + ALOGE("%s: torch mode of camera %s is not available because " + "camera is in use", __FUNCTION__, id.string()); + return -EBUSY; + } else { + ALOGE("%s: torch mode of camera %s is not available due to " + "insufficient resources", __FUNCTION__, id.string()); + return -EUSERS; + } + } + } + + status_t res = mFlashlight->setTorchMode(id, enabled); if (res) { - ALOGE("%s: setting torch mode of camera %s to %d failed", __FUNCTION__, - cameraId.string(), enabled); + ALOGE("%s: setting torch mode of camera %s to %d failed. %s (%d)", + __FUNCTION__, id.string(), enabled, strerror(-res), res); return res; } - // update the link to client's death - ssize_t index = mTorchClientMap.indexOfKey(cameraId); - if (enabled) { - if (index == NAME_NOT_FOUND) { - mTorchClientMap.add(cameraId, clientBinder); - } else { - const sp oldBinder = mTorchClientMap.valueAt(index); - oldBinder->unlinkToDeath(this); + { + // update the link to client's death + Mutex::Autolock al(mTorchClientMapMutex); + ssize_t index = mTorchClientMap.indexOfKey(id); + if (enabled) { + if (index == NAME_NOT_FOUND) { + mTorchClientMap.add(id, clientBinder); + } else { + const sp oldBinder = mTorchClientMap.valueAt(index); + oldBinder->unlinkToDeath(this); - mTorchClientMap.replaceValueAt(index, clientBinder); + mTorchClientMap.replaceValueAt(index, clientBinder); + } + clientBinder->linkToDeath(this); + } else if (index != NAME_NOT_FOUND) { + sp oldBinder = mTorchClientMap.valueAt(index); + oldBinder->unlinkToDeath(this); } - clientBinder->linkToDeath(this); - } else if (index != NAME_NOT_FOUND) { - sp oldBinder = mTorchClientMap.valueAt(index); - oldBinder->unlinkToDeath(this); } - // notify the listeners the change. - ICameraServiceListener::TorchStatus status = enabled ? - ICameraServiceListener::TORCH_STATUS_ON : - ICameraServiceListener::TORCH_STATUS_OFF; - onTorchStatusChangedLocked(cameraId, status); - return OK; } @@ -1099,7 +1161,7 @@ status_t CameraService::connectDevice( int deviceVersion = getDeviceVersion(cameraId, &facing); // give flashlight a chance to close devices if necessary. - mFlashlight->prepareDeviceOpen(); + mFlashlight->prepareDeviceOpen(String8::format("%d", cameraId)); switch(deviceVersion) { case CAMERA_DEVICE_API_VERSION_1_0: @@ -1176,8 +1238,8 @@ status_t CameraService::addListener( { Mutex::Autolock al(mTorchStatusMutex); for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) { - listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), - mTorchStatusMap.keyAt(i)); + String16 id = String16(mTorchStatusMap.keyAt(i).string()); + listener->onTorchStatusChanged(mTorchStatusMap.valueAt(i), id); } } @@ -1615,6 +1677,9 @@ status_t CameraService::BasicClient::finishCameraOps() { mCameraId, &rejectSourceStates); + // Notify flashlight that a camera device is closed. + mCameraService->mFlashlight->deviceClosed( + String8::format("%d", mCameraId)); } // Always stop watching, even if no camera op is active mAppOpsManager.stopWatchingMode(mOpsCallback); @@ -1859,17 +1924,18 @@ status_t CameraService::dump(int fd, const Vector& args) { } void CameraService::handleTorchClientBinderDied(const wp &who) { - Mutex::Autolock al(mTorchStatusMutex); + Mutex::Autolock al(mTorchClientMapMutex); for (size_t i = 0; i < mTorchClientMap.size(); i++) { if (mTorchClientMap[i] == who) { // turn off the torch mode that was turned on by dead client - String16 cameraId = mTorchClientMap.keyAt(i); - mFlashlight->setTorchMode(cameraId, false); + String8 cameraId = mTorchClientMap.keyAt(i); + status_t res = mFlashlight->setTorchMode(cameraId, false); + if (res) { + ALOGE("%s: torch client died but couldn't turn off torch: " + "%s (%d)", __FUNCTION__, strerror(-res), res); + return; + } mTorchClientMap.removeItemsAt(i); - - // notify torch mode was turned off - onTorchStatusChangedLocked(cameraId, - ICameraServiceListener::TORCH_STATUS_OFF); break; } } @@ -1965,6 +2031,19 @@ void CameraService::updateStatus(ICameraServiceListener::Status status, } } + if (status == ICameraServiceListener::STATUS_NOT_PRESENT || + status == ICameraServiceListener::STATUS_NOT_AVAILABLE) { + // update torch status to not available when the camera device + // becomes not present or not available. + onTorchStatusChanged(String8::format("%d", cameraId), + ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE); + } else if (status == ICameraServiceListener::STATUS_PRESENT) { + // update torch status to available when the camera device becomes + // present or available + onTorchStatusChanged(String8::format("%d", cameraId), + ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF); + } + Vector >::const_iterator it; for (it = mListenerList.begin(); it != mListenerList.end(); ++it) { (*it)->onStatusChanged(status, cameraId); @@ -1982,17 +2061,23 @@ ICameraServiceListener::Status CameraService::getStatus(int cameraId) const { return mStatusList[cameraId]; } -ICameraServiceListener::TorchStatus CameraService::getTorchStatusLocked( - const String16& cameraId) const { +status_t CameraService::getTorchStatusLocked( + const String8& cameraId, + ICameraServiceListener::TorchStatus *status) const { + if (!status) { + return BAD_VALUE; + } ssize_t index = mTorchStatusMap.indexOfKey(cameraId); if (index == NAME_NOT_FOUND) { - return ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; + // invalid camera ID or the camera doesn't have a flash unit + return NAME_NOT_FOUND; } - return mTorchStatusMap.valueAt(index); + *status = mTorchStatusMap.valueAt(index); + return OK; } -status_t CameraService::setTorchStatusLocked(const String16& cameraId, +status_t CameraService::setTorchStatusLocked(const String8& cameraId, ICameraServiceListener::TorchStatus status) { ssize_t index = mTorchStatusMap.indexOfKey(cameraId); if (index == NAME_NOT_FOUND) { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 158825e..803c795 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -72,7 +72,7 @@ public: // HAL Callbacks virtual void onDeviceStatusChanged(int cameraId, int newStatus); - virtual void onTorchStatusChanged(const String16& cameraId, + virtual void onTorchStatusChanged(const String8& cameraId, ICameraServiceListener::TorchStatus newStatus); @@ -418,28 +418,33 @@ private: // flashlight control sp mFlashlight; - // guard mTorchStatusMap and mTorchClientMap + // guard mTorchStatusMap Mutex mTorchStatusMutex; + // guard mTorchClientMap + Mutex mTorchClientMapMutex; // camera id -> torch status - KeyedVector mTorchStatusMap; + KeyedVector mTorchStatusMap; // camera id -> torch client binder // only store the last client that turns on each camera's torch mode - KeyedVector > mTorchClientMap; + KeyedVector > mTorchClientMap; // check and handle if torch client's process has died void handleTorchClientBinderDied(const wp &who); // handle torch mode status change and invoke callbacks. mTorchStatusMutex // should be locked. - void onTorchStatusChangedLocked(const String16& cameraId, + void onTorchStatusChangedLocked(const String8& cameraId, ICameraServiceListener::TorchStatus newStatus); + // validate the camera id for use of setting a torch mode. + bool validCameraIdForSetTorchMode(const String8& cameraId); + // get a camera's torch status. mTorchStatusMutex should be locked. - ICameraServiceListener::TorchStatus getTorchStatusLocked( - const String16 &cameraId) const; + status_t getTorchStatusLocked(const String8 &cameraId, + ICameraServiceListener::TorchStatus *status) const; // set a camera's torch status. mTorchStatusMutex should be locked. - status_t setTorchStatusLocked(const String16 &cameraId, + status_t setTorchStatusLocked(const String8 &cameraId, ICameraServiceListener::TorchStatus status); // IBinder::DeathRecipient implementation -- cgit v1.1 From 3f22f6d4fa126b49a39a05f8354019ce4e33ac28 Mon Sep 17 00:00:00 2001 From: Chien-Yu Chen Date: Wed, 25 Feb 2015 16:04:22 -0800 Subject: 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 --- .../camera/libcameraservice/CameraFlashlight.cpp | 252 ++++++++++++++++++++- .../camera/libcameraservice/CameraFlashlight.h | 50 ++++ services/camera/libcameraservice/CameraService.cpp | 13 -- services/camera/libcameraservice/CameraService.h | 1 - .../libcameraservice/common/CameraModule.cpp | 17 +- .../camera/libcameraservice/common/CameraModule.h | 2 + .../device1/CameraHardwareInterface.h | 3 +- .../libcameraservice/device2/Camera2Device.cpp | 3 +- .../libcameraservice/device3/Camera3Device.cpp | 4 +- 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 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 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 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 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 mDevice; + String8 mCameraId; + CameraParameters mParameters; + bool mTorchEnabled; + + sp mProducer; + sp mConsumer; + sp mSurfaceTexture; + sp mAnw; + + Mutex mLock; +}; + } // namespace android #endif diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 7b8314c..5ba3a5c 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 803c795..5e2817d 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 16e3a19..c79fa59 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(&device))); + res = module->open(name, reinterpret_cast(&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(&device))); + res = module->open(deviceName.string(), + reinterpret_cast(&device)); ATRACE_END(); if (res != OK) { -- cgit v1.1 From 815a321f30434f8ce7c0b34a00ccc999e0c5c5a7 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 23 Feb 2015 15:19:19 -0800 Subject: Camera: Wire up dataSpace, clean up ICameraDeviceUser - Remove unused arguments from ICameraDeviceUser::createStream - Add dataSpace as a stream parameter, plumb it through everything Change-Id: I608cafe694785d1c512276e71b2016f8ac3b0ccb --- camera/camera2/ICameraDeviceUser.cpp | 15 ++------------ include/camera/camera2/ICameraDeviceUser.h | 1 - .../camera/libcameraservice/CameraFlashlight.cpp | 3 ++- .../api1/client2/CallbackProcessor.cpp | 2 +- .../api1/client2/JpegProcessor.cpp | 3 ++- .../api1/client2/StreamingProcessor.cpp | 8 ++++++-- .../libcameraservice/api1/client2/ZslProcessor.cpp | 2 +- .../libcameraservice/api2/CameraDeviceClient.cpp | 21 ++++++++++++++------ .../libcameraservice/api2/CameraDeviceClient.h | 6 ++---- .../libcameraservice/api_pro/ProCamera2Client.cpp | 2 +- .../libcameraservice/common/CameraDeviceBase.h | 13 +++++------- .../libcameraservice/device2/Camera2Device.cpp | 3 ++- .../libcameraservice/device2/Camera2Device.h | 3 ++- .../libcameraservice/device3/Camera3Device.cpp | 11 ++++++----- .../libcameraservice/device3/Camera3Device.h | 3 ++- .../device3/Camera3DummyStream.cpp | 2 +- .../libcameraservice/device3/Camera3DummyStream.h | 1 + .../device3/Camera3IOStreamBase.cpp | 5 +++-- .../libcameraservice/device3/Camera3IOStreamBase.h | 3 ++- .../device3/Camera3InputStream.cpp | 2 +- .../device3/Camera3OutputStream.cpp | 23 ++++++++++++++++------ .../libcameraservice/device3/Camera3OutputStream.h | 9 ++++++--- .../libcameraservice/device3/Camera3Stream.cpp | 8 +++++++- .../libcameraservice/device3/Camera3Stream.h | 10 ++++++---- .../libcameraservice/device3/Camera3ZslStream.cpp | 3 ++- 25 files changed, 95 insertions(+), 67 deletions(-) diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp index 7d3807a..90eaa28 100644 --- a/camera/camera2/ICameraDeviceUser.cpp +++ b/camera/camera2/ICameraDeviceUser.cpp @@ -208,14 +208,11 @@ public: return reply.readInt32(); } - virtual status_t createStream(int width, int height, int format, + virtual status_t createStream( const sp& bufferProducer) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); - data.writeInt32(width); - data.writeInt32(height); - data.writeInt32(format); data.writeInt32(1); // marker that bufferProducer is not null data.writeString16(String16("unknown_name")); // name of surface @@ -396,14 +393,6 @@ status_t BnCameraDeviceUser::onTransact( } break; case CREATE_STREAM: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); - int width, height, format; - - width = data.readInt32(); - ALOGV("%s: CREATE_STREAM: width = %d", __FUNCTION__, width); - height = data.readInt32(); - ALOGV("%s: CREATE_STREAM: height = %d", __FUNCTION__, height); - format = data.readInt32(); - ALOGV("%s: CREATE_STREAM: format = %d", __FUNCTION__, format); sp bp; if (data.readInt32() != 0) { @@ -419,7 +408,7 @@ status_t BnCameraDeviceUser::onTransact( } status_t ret; - ret = createStream(width, height, format, bp); + ret = createStream(bp); reply->writeNoException(); ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__); diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h index 35488bb..bfc2aa0 100644 --- a/include/camera/camera2/ICameraDeviceUser.h +++ b/include/camera/camera2/ICameraDeviceUser.h @@ -101,7 +101,6 @@ public: virtual status_t deleteStream(int streamId) = 0; virtual status_t createStream( - int width, int height, int format, const sp& bufferProducer) = 0; // Create a request object from a template. diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp index 8e894cd..7a79750 100644 --- a/services/camera/libcameraservice/CameraFlashlight.cpp +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -388,7 +388,8 @@ status_t CameraDeviceClientFlashControl::initializeSurface( if (mAnw == NULL) { return NO_MEMORY; } - res = device->createStream(mAnw, width, height, format, &mStreamId); + res = device->createStream(mAnw, width, height, format, + HAL_DATASPACE_UNKNOWN, &mStreamId); if (res) { return res; } diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp index eadaa00..fd4e714 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp @@ -155,7 +155,7 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { callbackFormat, params.previewFormat); res = device->createStream(mCallbackWindow, params.previewWidth, params.previewHeight, - callbackFormat, &mCallbackStreamId); + callbackFormat, HAL_DATASPACE_JFIF, &mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for callbacks: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp index 2772267..5b387f9 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp @@ -145,7 +145,8 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { // Create stream for HAL production res = device->createStream(mCaptureWindow, params.pictureWidth, params.pictureHeight, - HAL_PIXEL_FORMAT_BLOB, &mCaptureStreamId); + HAL_PIXEL_FORMAT_BLOB, HAL_DATASPACE_JFIF, + &mCaptureStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for capture: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index 470624b..ea5dcdd 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -181,7 +181,8 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { if (mPreviewStreamId == NO_STREAM) { res = device->createStream(mPreviewWindow, params.previewWidth, params.previewHeight, - CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, &mPreviewStreamId); + CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN, + &mPreviewStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)", __FUNCTION__, mId, strerror(-res), res); @@ -420,9 +421,12 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { if (mRecordingStreamId == NO_STREAM) { mRecordingFrameCount = 0; + // Selecting BT.709 colorspace by default + // TODO: Wire this in from encoder side res = device->createStream(mRecordingWindow, params.videoWidth, params.videoHeight, - CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, &mRecordingStreamId); + CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, + HAL_DATASPACE_BT709, &mRecordingStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for recording: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 8b7e4b4..db7e10d 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -186,7 +186,7 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; res = device->createStream(mZslWindow, params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, - streamType, &mZslStreamId); + streamType, HAL_DATASPACE_UNKNOWN, &mZslStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for ZSL: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 884b198..7043547 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -308,11 +308,10 @@ status_t CameraDeviceClient::deleteStream(int streamId) { return res; } -status_t CameraDeviceClient::createStream(int width, int height, int format, +status_t CameraDeviceClient::createStream( const sp& bufferProducer) { ATRACE_CALL(); - ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format); status_t res; if ( (res = checkPid(__FUNCTION__) ) != OK) return res; @@ -368,7 +367,8 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, anw = new Surface(bufferProducer, useAsync); } - // TODO: remove w,h,f since we are ignoring them + int width, height, format; + android_dataspace dataSpace; if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) { ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__, @@ -385,6 +385,12 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, mCameraId); return res; } + if ((res = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, + reinterpret_cast(&dataSpace))) != OK) { + ALOGE("%s: Camera %d: Failed to query Surface dataSpace", __FUNCTION__, + mCameraId); + return res; + } // FIXME: remove this override since the default format should be // IMPLEMENTATION_DEFINED. b/9487482 @@ -397,14 +403,15 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, // Round dimensions to the nearest dimensions available for this format if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height, - format, mDevice->info(), /*out*/&width, /*out*/&height)) { + format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) { ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.", __FUNCTION__, format); return BAD_VALUE; } int streamId = -1; - res = mDevice->createStream(anw, width, height, format, &streamId); + res = mDevice->createStream(anw, width, height, format, dataSpace, + &streamId); if (res == OK) { mStreamMap.add(bufferProducer->asBinder(), streamId); @@ -439,10 +446,12 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height, - int32_t format, const CameraMetadata& info, + int32_t format, android_dataspace dataSpace, const CameraMetadata& info, /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) { camera_metadata_ro_entry streamConfigs = + (dataSpace == HAL_DATASPACE_DEPTH) ? + info.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS) : info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); int32_t bestWidth = -1; diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index e687175..c89c269 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -84,9 +84,6 @@ public: virtual status_t deleteStream(int streamId); virtual status_t createStream( - int width, - int height, - int format, const sp& bufferProducer); // Create a request object from a template. @@ -161,7 +158,8 @@ private: // a width <= ROUNDING_WIDTH_CAP static const int32_t ROUNDING_WIDTH_CAP = 1080; static bool roundBufferDimensionNearest(int32_t width, int32_t height, int32_t format, - const CameraMetadata& info, /*out*/int32_t* outWidth, /*out*/int32_t* outHeight); + android_dataspace dataSpace, const CameraMetadata& info, + /*out*/int32_t* outWidth, /*out*/int32_t* outHeight); // IGraphicsBufferProducer binder -> Stream ID KeyedVector, int> mStreamMap; diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp index d335d0b..b73f494 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp @@ -281,7 +281,7 @@ status_t ProCamera2Client::createStream(int width, int height, int format, } return mDevice->createStream(window, width, height, format, - streamId); + HAL_DATASPACE_UNKNOWN, streamId); } // Create a request object from a template. diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index 06615f6..8764504 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -100,17 +100,14 @@ class CameraDeviceBase : public virtual RefBase { nsecs_t timeout) = 0; /** - * Create an output stream of the requested size and format. + * Create an output stream of the requested size, format, and dataspace * - * If format is CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, then the HAL device selects - * an appropriate format; it can be queried with getStreamInfo. - * - * If format is HAL_PIXEL_FORMAT_COMPRESSED, the size parameter must be - * equal to the size in bytes of the buffers to allocate for the stream. For - * other formats, the size parameter is ignored. + * For HAL_PIXEL_FORMAT_BLOB formats, the width and height should be the + * logical dimensions of the buffer, not the number of bytes. */ virtual status_t createStream(sp consumer, - uint32_t width, uint32_t height, int format, int *id) = 0; + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace, int *id) = 0; /** * Create an input reprocess stream that uses buffers from an existing diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 43c8307..ee862a2 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -241,7 +241,8 @@ status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t time } status_t Camera2Device::createStream(sp consumer, - uint32_t width, uint32_t height, int format, int *id) { + uint32_t width, uint32_t height, int format, + android_dataspace /*dataSpace*/, int *id) { ATRACE_CALL(); status_t res; ALOGV("%s: E", __FUNCTION__); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 1cc5482..e4c2856 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -57,7 +57,8 @@ class Camera2Device: public CameraDeviceBase { virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); virtual status_t createStream(sp consumer, - uint32_t width, uint32_t height, int format, int *id); + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace, int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t getStreamInfo(int id, uint32_t *width, uint32_t *height, uint32_t *format); diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index bca9bfd..529d249 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -801,12 +801,13 @@ status_t Camera3Device::createZslStream( } status_t Camera3Device::createStream(sp consumer, - uint32_t width, uint32_t height, int format, int *id) { + uint32_t width, uint32_t height, int format, android_dataspace dataSpace, + int *id) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); - ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d", - mId, mNextStreamId, width, height, format); + ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d", + mId, mNextStreamId, width, height, format, dataSpace); status_t res; bool wasActive = false; @@ -846,10 +847,10 @@ status_t Camera3Device::createStream(sp consumer, } newStream = new Camera3OutputStream(mNextStreamId, consumer, - width, height, jpegBufferSize, format); + width, height, jpegBufferSize, format, dataSpace); } else { newStream = new Camera3OutputStream(mNextStreamId, consumer, - width, height, format); + width, height, format, dataSpace); } newStream->setStatusTracker(mStatusTracker); diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index de10cfe..e2ad1fa 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -95,7 +95,8 @@ class Camera3Device : // If adding streams while actively capturing, will pause device before adding // stream, reconfiguring device, and unpausing. virtual status_t createStream(sp consumer, - uint32_t width, uint32_t height, int format, int *id); + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace, int *id); virtual status_t createInputStream( uint32_t width, uint32_t height, int format, int *id); diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp index 6656b09..6201484 100644 --- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp @@ -28,7 +28,7 @@ namespace camera3 { Camera3DummyStream::Camera3DummyStream(int id) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, DUMMY_WIDTH, DUMMY_HEIGHT, - /*maxSize*/0, DUMMY_FORMAT) { + /*maxSize*/0, DUMMY_FORMAT, DUMMY_DATASPACE) { } diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h index 3e42623..7f52d84 100644 --- a/services/camera/libcameraservice/device3/Camera3DummyStream.h +++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h @@ -75,6 +75,7 @@ class Camera3DummyStream : static const int DUMMY_WIDTH = 320; static const int DUMMY_HEIGHT = 240; static const int DUMMY_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; + static const android_dataspace DUMMY_DATASPACE = HAL_DATASPACE_UNKNOWN; static const uint32_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER; /** diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp index cc66459..ff0acbb 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp @@ -30,9 +30,10 @@ namespace android { namespace camera3 { Camera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type, - uint32_t width, uint32_t height, size_t maxSize, int format) : + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace) : Camera3Stream(id, type, - width, height, maxSize, format), + width, height, maxSize, format, dataSpace), mTotalBufferCount(0), mHandoutTotalBufferCount(0), mHandoutOutputBufferCount(0), diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h index a35c290..83d4350 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h @@ -33,7 +33,8 @@ class Camera3IOStreamBase : public Camera3Stream { protected: Camera3IOStreamBase(int id, camera3_stream_type_t type, - uint32_t width, uint32_t height, size_t maxSize, int format); + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace); public: diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp index 319be1d..85ed88d 100644 --- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp @@ -29,7 +29,7 @@ namespace camera3 { Camera3InputStream::Camera3InputStream(int id, uint32_t width, uint32_t height, int format) : Camera3IOStreamBase(id, CAMERA3_STREAM_INPUT, width, height, - /*maxSize*/0, format) { + /*maxSize*/0, format, HAL_DATASPACE_UNKNOWN) { if (format == HAL_PIXEL_FORMAT_BLOB) { ALOGE("%s: Bad format, BLOB not supported", __FUNCTION__); diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp index 77ad503..103d90b 100644 --- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp @@ -33,9 +33,10 @@ namespace camera3 { Camera3OutputStream::Camera3OutputStream(int id, sp consumer, - uint32_t width, uint32_t height, int format) : + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, - /*maxSize*/0, format), + /*maxSize*/0, format, dataSpace), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true) { @@ -48,9 +49,10 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, sp consumer, - uint32_t width, uint32_t height, size_t maxSize, int format) : + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, - format), + format, dataSpace), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true) { @@ -69,10 +71,11 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, uint32_t width, uint32_t height, - int format) : + int format, + android_dataspace dataSpace) : Camera3IOStreamBase(id, type, width, height, /*maxSize*/0, - format), + format, dataSpace), mTransform(0) { // Subclasses expected to initialize mConsumer themselves @@ -323,6 +326,14 @@ status_t Camera3OutputStream::configureQueueLocked() { return res; } + res = native_window_set_buffers_data_space(mConsumer.get(), + camera3_stream::data_space); + if (res != OK) { + ALOGE("%s: Unable to configure stream dataspace %#x for stream %d", + __FUNCTION__, camera3_stream::data_space, mId); + return res; + } + int maxConsumerBuffers; res = mConsumer->query(mConsumer.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h index be278c5..f016d60 100644 --- a/services/camera/libcameraservice/device3/Camera3OutputStream.h +++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h @@ -39,14 +39,16 @@ class Camera3OutputStream : * Set up a stream for formats that have 2 dimensions, such as RAW and YUV. */ Camera3OutputStream(int id, sp consumer, - uint32_t width, uint32_t height, int format); + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace); /** * Set up a stream for formats that have a variable buffer size for the same * dimensions, such as compressed JPEG. */ Camera3OutputStream(int id, sp consumer, - uint32_t width, uint32_t height, size_t maxSize, int format); + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace); virtual ~Camera3OutputStream(); @@ -64,7 +66,8 @@ class Camera3OutputStream : protected: Camera3OutputStream(int id, camera3_stream_type_t type, - uint32_t width, uint32_t height, int format); + uint32_t width, uint32_t height, int format, + android_dataspace dataSpace); /** * Note that we release the lock briefly in this function diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 3c0e908..f829741 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -46,7 +46,8 @@ const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { Camera3Stream::Camera3Stream(int id, camera3_stream_type type, - uint32_t width, uint32_t height, size_t maxSize, int format) : + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace) : camera3_stream(), mId(id), mName(String8::format("Camera3Stream[%d]", id)), @@ -58,6 +59,7 @@ Camera3Stream::Camera3Stream(int id, camera3_stream::width = width; camera3_stream::height = height; camera3_stream::format = format; + camera3_stream::data_space = dataSpace; camera3_stream::usage = 0; camera3_stream::max_buffers = 0; camera3_stream::priv = NULL; @@ -84,6 +86,10 @@ int Camera3Stream::getFormat() const { return camera3_stream::format; } +android_dataspace Camera3Stream::getDataSpace() const { + return camera3_stream::data_space; +} + camera3_stream* Camera3Stream::startConfiguration() { ATRACE_CALL(); Mutex::Autolock l(mLock); diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h index d0e1337..72f3ee9 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.h +++ b/services/camera/libcameraservice/device3/Camera3Stream.h @@ -119,9 +119,10 @@ class Camera3Stream : /** * Get the stream's dimensions and format */ - uint32_t getWidth() const; - uint32_t getHeight() const; - int getFormat() const; + uint32_t getWidth() const; + uint32_t getHeight() const; + int getFormat() const; + android_dataspace getDataSpace() const; /** * Start the stream configuration process. Returns a handle to the stream's @@ -264,7 +265,8 @@ class Camera3Stream : mutable Mutex mLock; Camera3Stream(int id, camera3_stream_type type, - uint32_t width, uint32_t height, size_t maxSize, int format); + uint32_t width, uint32_t height, size_t maxSize, int format, + android_dataspace dataSpace); /** * Interface to be implemented by derived classes diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp index 81330ea..5bf7a4c 100644 --- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp @@ -114,7 +114,8 @@ Camera3ZslStream::Camera3ZslStream(int id, uint32_t width, uint32_t height, int bufferCount) : Camera3OutputStream(id, CAMERA3_STREAM_BIDIRECTIONAL, width, height, - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED), + HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, + HAL_DATASPACE_UNKNOWN), mDepth(bufferCount) { sp producer; -- cgit v1.1 From 5b1a2b075f42b2282cb1d0f0bdd08df74aafb89b Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Thu, 12 Mar 2015 13:42:44 -0700 Subject: Camera: plumbing rotation field through Change-Id: I0f4343a0bfa7bf09ba887c78a1da1c08daa35333 --- camera/Android.mk | 1 + camera/camera2/ICameraDeviceUser.cpp | 31 ++++----- camera/camera2/OutputConfiguration.cpp | 79 ++++++++++++++++++++++ include/camera/camera2/ICameraDeviceUser.h | 6 +- include/camera/camera2/OutputConfiguration.h | 51 ++++++++++++++ .../camera/libcameraservice/CameraFlashlight.cpp | 2 +- .../api1/client2/CallbackProcessor.cpp | 4 +- .../api1/client2/JpegProcessor.cpp | 2 +- .../api1/client2/StreamingProcessor.cpp | 6 +- .../libcameraservice/api1/client2/ZslProcessor.cpp | 4 +- .../libcameraservice/api2/CameraDeviceClient.cpp | 9 ++- .../libcameraservice/api2/CameraDeviceClient.h | 4 +- .../libcameraservice/api_pro/ProCamera2Client.cpp | 3 +- .../libcameraservice/common/CameraDeviceBase.h | 4 +- .../libcameraservice/device2/Camera2Device.cpp | 2 +- .../libcameraservice/device2/Camera2Device.h | 2 +- .../libcameraservice/device3/Camera3Device.cpp | 10 +-- .../libcameraservice/device3/Camera3Device.h | 2 +- .../device3/Camera3DummyStream.cpp | 2 +- .../libcameraservice/device3/Camera3DummyStream.h | 1 + .../device3/Camera3IOStreamBase.cpp | 4 +- .../libcameraservice/device3/Camera3IOStreamBase.h | 2 +- .../device3/Camera3InputStream.cpp | 4 +- .../device3/Camera3OutputStream.cpp | 13 ++-- .../libcameraservice/device3/Camera3OutputStream.h | 6 +- .../libcameraservice/device3/Camera3Stream.cpp | 3 +- .../libcameraservice/device3/Camera3Stream.h | 2 +- .../libcameraservice/device3/Camera3ZslStream.cpp | 2 +- 28 files changed, 196 insertions(+), 65 deletions(-) create mode 100644 camera/camera2/OutputConfiguration.cpp create mode 100644 include/camera/camera2/OutputConfiguration.h diff --git a/camera/Android.mk b/camera/Android.mk index da5ac59..df7279f 100644 --- a/camera/Android.mk +++ b/camera/Android.mk @@ -35,6 +35,7 @@ LOCAL_SRC_FILES:= \ camera2/ICameraDeviceUser.cpp \ camera2/ICameraDeviceCallbacks.cpp \ camera2/CaptureRequest.cpp \ + camera2/OutputConfiguration.cpp \ ProCamera.cpp \ CameraBase.cpp \ CameraUtils.cpp \ diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp index 90eaa28..16018dc 100644 --- a/camera/camera2/ICameraDeviceUser.cpp +++ b/camera/camera2/ICameraDeviceUser.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace android { @@ -208,17 +209,17 @@ public: return reply.readInt32(); } - virtual status_t createStream( - const sp& bufferProducer) + virtual status_t createStream(const OutputConfiguration& outputConfiguration) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); - data.writeInt32(1); // marker that bufferProducer is not null - data.writeString16(String16("unknown_name")); // name of surface - sp b(bufferProducer->asBinder()); - data.writeStrongBinder(b); - + if (outputConfiguration.getGraphicBufferProducer() != NULL) { + data.writeInt32(1); // marker that OutputConfiguration is not null. Mimic aidl behavior + outputConfiguration.writeToParcel(data); + } else { + data.writeInt32(0); + } remote()->transact(CREATE_STREAM, data, &reply); reply.readExceptionCode(); @@ -394,22 +395,14 @@ status_t BnCameraDeviceUser::onTransact( case CREATE_STREAM: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); - sp bp; + status_t ret = BAD_VALUE; if (data.readInt32() != 0) { - String16 name = readMaybeEmptyString16(data); - bp = interface_cast( - data.readStrongBinder()); - - ALOGV("%s: CREATE_STREAM: bp = %p, name = %s", __FUNCTION__, - bp.get(), String8(name).string()); + OutputConfiguration outputConfiguration(data); + ret = createStream(outputConfiguration); } else { - ALOGV("%s: CREATE_STREAM: bp = unset, name = unset", - __FUNCTION__); + ALOGE("%s: cannot take an empty OutputConfiguration", __FUNCTION__); } - status_t ret; - ret = createStream(bp); - reply->writeNoException(); ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__); reply->writeInt32(ret); diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp new file mode 100644 index 0000000..dab6a00 --- /dev/null +++ b/camera/camera2/OutputConfiguration.cpp @@ -0,0 +1,79 @@ +/* +** +** Copyright 2015, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#define LOG_TAG "OutputConfiguration" +#include + +#include +#include + +namespace android { + + +const int OutputConfiguration::INVALID_ROTATION = -1; + +// Read empty strings without printing a false error message. +String16 OutputConfiguration::readMaybeEmptyString16(const Parcel& parcel) { + size_t len; + const char16_t* str = parcel.readString16Inplace(&len); + if (str != NULL) { + return String16(str, len); + } else { + return String16(); + } +} + +sp OutputConfiguration::getGraphicBufferProducer() const { + return mGbp; +} + +int OutputConfiguration::getRotation() const { + return mRotation; +} + +OutputConfiguration::OutputConfiguration(const Parcel& parcel) { + status_t err; + int rotation = 0; + if ((err = parcel.readInt32(&rotation)) != OK) { + ALOGE("%s: Failed to read rotation from parcel", __FUNCTION__); + mGbp = NULL; + mRotation = INVALID_ROTATION; + return; + } + + String16 name = readMaybeEmptyString16(parcel); + const sp& gbp = + interface_cast(parcel.readStrongBinder()); + mGbp = gbp; + mRotation = rotation; + + ALOGV("%s: OutputConfiguration: bp = %p, name = %s", __FUNCTION__, + gbp.get(), String8(name).string()); +} + +status_t OutputConfiguration::writeToParcel(Parcel& parcel) const { + + parcel.writeInt32(mRotation); + parcel.writeString16(String16("unknown_name")); // name of surface + sp b(mGbp->asBinder()); + parcel.writeStrongBinder(b); + + return OK; +} + +}; // namespace android + diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h index bfc2aa0..e9f1f5a 100644 --- a/include/camera/camera2/ICameraDeviceUser.h +++ b/include/camera/camera2/ICameraDeviceUser.h @@ -27,9 +27,9 @@ namespace android { class ICameraDeviceUserClient; class IGraphicBufferProducer; -class Surface; class CaptureRequest; class CameraMetadata; +class OutputConfiguration; enum { NO_IN_FLIGHT_REPEATING_FRAMES = -1, @@ -100,8 +100,8 @@ public: virtual status_t endConfigure() = 0; virtual status_t deleteStream(int streamId) = 0; - virtual status_t createStream( - const sp& bufferProducer) = 0; + + virtual status_t createStream(const OutputConfiguration& outputConfiguration) = 0; // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, diff --git a/include/camera/camera2/OutputConfiguration.h b/include/camera/camera2/OutputConfiguration.h new file mode 100644 index 0000000..e6b679f --- /dev/null +++ b/include/camera/camera2/OutputConfiguration.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H +#define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H + +#include +#include + +namespace android { + +class Surface; + +class OutputConfiguration : public virtual RefBase { +public: + + static const int INVALID_ROTATION; + sp getGraphicBufferProducer() const; + int getRotation() const; + + /** + * Keep impl up-to-date with OutputConfiguration.java in frameworks/base + */ + status_t writeToParcel(Parcel& parcel) const; + // getGraphicBufferProducer will be NULL if error occurred + // getRotation will be INVALID_ROTATION if error occurred + OutputConfiguration(const Parcel& parcel); + +private: + sp mGbp; + int mRotation; + + // helper function + static String16 readMaybeEmptyString16(const Parcel& parcel); +}; +}; // namespace android + +#endif diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp index 7a79750..b3449e2 100644 --- a/services/camera/libcameraservice/CameraFlashlight.cpp +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -389,7 +389,7 @@ status_t CameraDeviceClientFlashControl::initializeSurface( return NO_MEMORY; } res = device->createStream(mAnw, width, height, format, - HAL_DATASPACE_UNKNOWN, &mStreamId); + HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mStreamId); if (res) { return res; } diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp index fd4e714..5c8f750 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp @@ -154,8 +154,8 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { params.previewWidth, params.previewHeight, callbackFormat, params.previewFormat); res = device->createStream(mCallbackWindow, - params.previewWidth, params.previewHeight, - callbackFormat, HAL_DATASPACE_JFIF, &mCallbackStreamId); + params.previewWidth, params.previewHeight, callbackFormat, + HAL_DATASPACE_JFIF, CAMERA3_STREAM_ROTATION_0, &mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for callbacks: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp index 5b387f9..34798bf 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp @@ -146,7 +146,7 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { res = device->createStream(mCaptureWindow, params.pictureWidth, params.pictureHeight, HAL_PIXEL_FORMAT_BLOB, HAL_DATASPACE_JFIF, - &mCaptureStreamId); + CAMERA3_STREAM_ROTATION_0, &mCaptureStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for capture: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index ea5dcdd..423659c 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -182,7 +182,7 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { res = device->createStream(mPreviewWindow, params.previewWidth, params.previewHeight, CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN, - &mPreviewStreamId); + CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)", __FUNCTION__, mId, strerror(-res), res); @@ -425,8 +425,8 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { // TODO: Wire this in from encoder side res = device->createStream(mRecordingWindow, params.videoWidth, params.videoHeight, - CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, - HAL_DATASPACE_BT709, &mRecordingStreamId); + CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_BT709, + CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for recording: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index db7e10d..2e41db5 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -185,8 +185,8 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL : (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; res = device->createStream(mZslWindow, - params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, - streamType, HAL_DATASPACE_UNKNOWN, &mZslStreamId); + params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, streamType, + HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mZslStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for ZSL: " "%s (%d)", __FUNCTION__, mId, diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 7043547..d25344e 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -308,8 +308,7 @@ status_t CameraDeviceClient::deleteStream(int streamId) { return res; } -status_t CameraDeviceClient::createStream( - const sp& bufferProducer) +status_t CameraDeviceClient::createStream(const OutputConfiguration &outputConfiguration) { ATRACE_CALL(); @@ -318,6 +317,8 @@ status_t CameraDeviceClient::createStream( Mutex::Autolock icl(mBinderSerializationLock); + + sp bufferProducer = outputConfiguration.getGraphicBufferProducer(); if (bufferProducer == NULL) { ALOGE("%s: bufferProducer must not be null", __FUNCTION__); return BAD_VALUE; @@ -411,7 +412,9 @@ status_t CameraDeviceClient::createStream( int streamId = -1; res = mDevice->createStream(anw, width, height, format, dataSpace, - &streamId); + static_cast + (outputConfiguration.getRotation()), + &streamId); if (res == OK) { mStreamMap.add(bufferProducer->asBinder(), streamId); diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index c89c269..a3dbb90 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -19,6 +19,7 @@ #include #include +#include #include "CameraService.h" #include "common/FrameProcessorBase.h" @@ -83,8 +84,7 @@ public: // Returns -EBUSY if device is not idle virtual status_t deleteStream(int streamId); - virtual status_t createStream( - const sp& bufferProducer); + virtual status_t createStream(const OutputConfiguration &outputConfiguration); // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp index b73f494..8999ee4 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp @@ -281,7 +281,8 @@ status_t ProCamera2Client::createStream(int width, int height, int format, } return mDevice->createStream(window, width, height, format, - HAL_DATASPACE_UNKNOWN, streamId); + HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, + streamId); } // Create a request object from a template. diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index 8764504..fe55b9e 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -100,14 +100,14 @@ class CameraDeviceBase : public virtual RefBase { nsecs_t timeout) = 0; /** - * Create an output stream of the requested size, format, and dataspace + * Create an output stream of the requested size, format, rotation and dataspace * * For HAL_PIXEL_FORMAT_BLOB formats, the width and height should be the * logical dimensions of the buffer, not the number of bytes. */ virtual status_t createStream(sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace, int *id) = 0; + android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id) = 0; /** * Create an input reprocess stream that uses buffers from an existing diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index ee862a2..878986b 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -242,7 +242,7 @@ status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t time status_t Camera2Device::createStream(sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace /*dataSpace*/, int *id) { + android_dataspace /*dataSpace*/, camera3_stream_rotation_t rotation, int *id) { ATRACE_CALL(); status_t res; ALOGV("%s: E", __FUNCTION__); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index e4c2856..9b32fa6 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -58,7 +58,7 @@ class Camera2Device: public CameraDeviceBase { virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); virtual status_t createStream(sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace, int *id); + android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t getStreamInfo(int id, uint32_t *width, uint32_t *height, uint32_t *format); diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 529d249..8236788 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -802,12 +802,12 @@ status_t Camera3Device::createZslStream( status_t Camera3Device::createStream(sp consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, - int *id) { + camera3_stream_rotation_t rotation, int *id) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); - ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d", - mId, mNextStreamId, width, height, format, dataSpace); + ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d", + mId, mNextStreamId, width, height, format, dataSpace, rotation); status_t res; bool wasActive = false; @@ -847,10 +847,10 @@ status_t Camera3Device::createStream(sp consumer, } newStream = new Camera3OutputStream(mNextStreamId, consumer, - width, height, jpegBufferSize, format, dataSpace); + width, height, jpegBufferSize, format, dataSpace, rotation); } else { newStream = new Camera3OutputStream(mNextStreamId, consumer, - width, height, format, dataSpace); + width, height, format, dataSpace, rotation); } newStream->setStatusTracker(mStatusTracker); diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index e2ad1fa..a77548d 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -96,7 +96,7 @@ class Camera3Device : // stream, reconfiguring device, and unpausing. virtual status_t createStream(sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace, int *id); + android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id); virtual status_t createInputStream( uint32_t width, uint32_t height, int format, int *id); diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp index 6201484..01edfff 100644 --- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp @@ -28,7 +28,7 @@ namespace camera3 { Camera3DummyStream::Camera3DummyStream(int id) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, DUMMY_WIDTH, DUMMY_HEIGHT, - /*maxSize*/0, DUMMY_FORMAT, DUMMY_DATASPACE) { + /*maxSize*/0, DUMMY_FORMAT, DUMMY_DATASPACE, DUMMY_ROTATION) { } diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h index 7f52d84..d023c57 100644 --- a/services/camera/libcameraservice/device3/Camera3DummyStream.h +++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h @@ -76,6 +76,7 @@ class Camera3DummyStream : static const int DUMMY_HEIGHT = 240; static const int DUMMY_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; static const android_dataspace DUMMY_DATASPACE = HAL_DATASPACE_UNKNOWN; + static const camera3_stream_rotation_t DUMMY_ROTATION = CAMERA3_STREAM_ROTATION_0; static const uint32_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER; /** diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp index ff0acbb..8696413 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp @@ -31,9 +31,9 @@ namespace camera3 { Camera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace) : + android_dataspace dataSpace, camera3_stream_rotation_t rotation) : Camera3Stream(id, type, - width, height, maxSize, format, dataSpace), + width, height, maxSize, format, dataSpace, rotation), mTotalBufferCount(0), mHandoutTotalBufferCount(0), mHandoutOutputBufferCount(0), diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h index 83d4350..abcf2b1 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h @@ -34,7 +34,7 @@ class Camera3IOStreamBase : protected: Camera3IOStreamBase(int id, camera3_stream_type_t type, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace); + android_dataspace dataSpace, camera3_stream_rotation_t rotation); public: diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp index 85ed88d..2f0c8be 100644 --- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp @@ -28,8 +28,8 @@ namespace camera3 { Camera3InputStream::Camera3InputStream(int id, uint32_t width, uint32_t height, int format) : - Camera3IOStreamBase(id, CAMERA3_STREAM_INPUT, width, height, - /*maxSize*/0, format, HAL_DATASPACE_UNKNOWN) { + Camera3IOStreamBase(id, CAMERA3_STREAM_INPUT, width, height, /*maxSize*/0, + format, HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0) { if (format == HAL_PIXEL_FORMAT_BLOB) { ALOGE("%s: Bad format, BLOB not supported", __FUNCTION__); diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp index 103d90b..96bed0d 100644 --- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp @@ -34,9 +34,9 @@ namespace camera3 { Camera3OutputStream::Camera3OutputStream(int id, sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace) : + android_dataspace dataSpace, camera3_stream_rotation_t rotation) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, - /*maxSize*/0, format, dataSpace), + /*maxSize*/0, format, dataSpace, rotation), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true) { @@ -50,9 +50,9 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, sp consumer, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace) : + android_dataspace dataSpace, camera3_stream_rotation_t rotation) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, - format, dataSpace), + format, dataSpace, rotation), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true) { @@ -72,10 +72,11 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace) : + android_dataspace dataSpace, + camera3_stream_rotation_t rotation) : Camera3IOStreamBase(id, type, width, height, /*maxSize*/0, - format, dataSpace), + format, dataSpace, rotation), mTransform(0) { // Subclasses expected to initialize mConsumer themselves diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h index f016d60..12b2ebb 100644 --- a/services/camera/libcameraservice/device3/Camera3OutputStream.h +++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h @@ -40,7 +40,7 @@ class Camera3OutputStream : */ Camera3OutputStream(int id, sp consumer, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace); + android_dataspace dataSpace, camera3_stream_rotation_t rotation); /** * Set up a stream for formats that have a variable buffer size for the same @@ -48,7 +48,7 @@ class Camera3OutputStream : */ Camera3OutputStream(int id, sp consumer, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace); + android_dataspace dataSpace, camera3_stream_rotation_t rotation); virtual ~Camera3OutputStream(); @@ -67,7 +67,7 @@ class Camera3OutputStream : protected: Camera3OutputStream(int id, camera3_stream_type_t type, uint32_t width, uint32_t height, int format, - android_dataspace dataSpace); + android_dataspace dataSpace, camera3_stream_rotation_t rotation); /** * Note that we release the lock briefly in this function diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index f829741..4acbce3 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -47,7 +47,7 @@ const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { Camera3Stream::Camera3Stream(int id, camera3_stream_type type, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace) : + android_dataspace dataSpace, camera3_stream_rotation_t rotation) : camera3_stream(), mId(id), mName(String8::format("Camera3Stream[%d]", id)), @@ -60,6 +60,7 @@ Camera3Stream::Camera3Stream(int id, camera3_stream::height = height; camera3_stream::format = format; camera3_stream::data_space = dataSpace; + camera3_stream::rotation = rotation; camera3_stream::usage = 0; camera3_stream::max_buffers = 0; camera3_stream::priv = NULL; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h index 72f3ee9..aba27fe 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.h +++ b/services/camera/libcameraservice/device3/Camera3Stream.h @@ -266,7 +266,7 @@ class Camera3Stream : Camera3Stream(int id, camera3_stream_type type, uint32_t width, uint32_t height, size_t maxSize, int format, - android_dataspace dataSpace); + android_dataspace dataSpace, camera3_stream_rotation_t rotation); /** * Interface to be implemented by derived classes diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp index 5bf7a4c..10d7f2e 100644 --- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp @@ -115,7 +115,7 @@ Camera3ZslStream::Camera3ZslStream(int id, uint32_t width, uint32_t height, Camera3OutputStream(id, CAMERA3_STREAM_BIDIRECTIONAL, width, height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - HAL_DATASPACE_UNKNOWN), + HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0), mDepth(bufferCount) { sp producer; -- cgit v1.1