Merge "media : ServiceUtilities: suppress useless error log"
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 78a77d4..3687b15 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -173,6 +173,13 @@
void setTorchMode(String cameraId, boolean enabled, IBinder clientBinder);
+ // Change the brightness level of the flash unit associated with cameraId to strengthLevel.
+ // If the torch is in OFF state and strengthLevel > 0 then the torch will also be turned ON.
+ void turnOnTorchWithStrengthLevel(String cameraId, int strengthLevel, IBinder clientBinder);
+
+ // Get the brightness level of the flash unit associated with cameraId.
+ int getTorchStrengthLevel(String cameraId);
+
/**
* Notify the camera service of a system event. Should only be called from system_server.
*
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index c54813c..5f17f5b 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -83,6 +83,8 @@
oneway void onTorchStatusChanged(int status, String cameraId);
+ oneway void onTorchStrengthLevelChanged(String cameraId, int newTorchStrength);
+
/**
* Notify registered clients about camera access priority changes.
* Clients which were previously unable to open a certain camera device
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index da887a2..d53d809 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -95,6 +95,9 @@
virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
return binder::Status::ok();
}
+ virtual binder::Status onTorchStrengthLevelChanged(const String16&, int32_t) {
+ return binder::Status::ok();
+ }
virtual binder::Status onCameraAccessPrioritiesChanged();
virtual binder::Status onCameraOpened(const String16&, const String16&) {
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 9f2f430..17ea512 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -96,6 +96,12 @@
return binder::Status::ok();
};
+ virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+ int32_t /*torchStrength*/) {
+ // No op
+ return binder::Status::ok();
+ }
+
virtual binder::Status onCameraAccessPrioritiesChanged() {
// No op
return binder::Status::ok();
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index ccdd9e5..015ae2f 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -119,6 +119,59 @@
return res;
}
+status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const String8& cameraId,
+ int32_t torchStrength) {
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
+ return NO_INIT;
+ }
+
+ ALOGV("%s: set torch strength of camera %s to %d", __FUNCTION__,
+ cameraId.string(), torchStrength);
+ status_t res = OK;
+ Mutex::Autolock l(mLock);
+
+ if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
+ ALOGE("%s: Camera device %s is in use, cannot be turned ON.",
+ __FUNCTION__, cameraId.string());
+ return -EBUSY;
+ }
+
+ if (mFlashControl == NULL) {
+ res = createFlashlightControl(cameraId);
+ if (res) {
+ return res;
+ }
+ }
+
+ res = mFlashControl->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
+ return res;
+}
+
+
+status_t CameraFlashlight::getTorchStrengthLevel(const String8& cameraId,
+ int32_t* torchStrength) {
+ status_t res = OK;
+ if (!mFlashlightMapInitialized) {
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
+ return false;
+ }
+
+ Mutex::Autolock l(mLock);
+
+ if (mFlashControl == NULL) {
+ res = createFlashlightControl(cameraId);
+ if (res) {
+ return res;
+ }
+ }
+
+ res = mFlashControl->getTorchStrengthLevel(cameraId, torchStrength);
+ return res;
+}
+
status_t CameraFlashlight::findFlashUnits() {
Mutex::Autolock l(mLock);
status_t res;
@@ -306,6 +359,22 @@
return mProviderManager->setTorchMode(cameraId.string(), enabled);
}
+
+status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const String8& cameraId,
+ int32_t torchStrength) {
+ ALOGV("%s: change torch strength level of camera %s to %d", __FUNCTION__,
+ cameraId.string(), torchStrength);
+
+ return mProviderManager->turnOnTorchWithStrengthLevel(cameraId.string(), torchStrength);
+}
+
+status_t ProviderFlashControl::getTorchStrengthLevel(const String8& cameraId,
+ int32_t* torchStrength) {
+ ALOGV("%s: get torch strength level of camera %s", __FUNCTION__,
+ cameraId.string());
+
+ return mProviderManager->getTorchStrengthLevel(cameraId.string(), torchStrength);
+}
// ProviderFlashControl implementation ends
}
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index b97fa5f..1703ddc 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -44,6 +44,14 @@
// set the torch mode to on or off.
virtual status_t setTorchMode(const String8& cameraId,
bool enabled) = 0;
+
+ // Change the brightness level of the torch. If the torch is OFF and
+ // torchStrength >= 1, then the torch will also be turned ON.
+ virtual status_t turnOnTorchWithStrengthLevel(const String8& cameraId,
+ int32_t torchStrength) = 0;
+
+ // Returns the torch strength level.
+ virtual status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength) = 0;
};
/**
@@ -67,6 +75,12 @@
// set the torch mode to on or off.
status_t setTorchMode(const String8& cameraId, bool enabled);
+ // Change the torch strength level of the flash unit in torch mode.
+ status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
+
+ // Get the torch strength level
+ status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
+
// 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
@@ -115,6 +129,8 @@
// FlashControlBase
status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
status_t setTorchMode(const String8& cameraId, bool enabled);
+ status_t turnOnTorchWithStrengthLevel(const String8& cameraId, int32_t torchStrength);
+ status_t getTorchStrengthLevel(const String8& cameraId, int32_t* torchStrength);
private:
sp<CameraProviderManager> mProviderManager;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 40e49bf..5a18582 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -569,6 +569,15 @@
onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
}
+void CameraService::broadcastTorchStrengthLevel(const String8& cameraId,
+ int32_t newStrengthLevel) {
+ Mutex::Autolock lock(mStatusListenerLock);
+ for (auto& i : mListenerList) {
+ i->getListener()->onTorchStrengthLevelChanged(String16{cameraId},
+ newStrengthLevel);
+ }
+}
+
void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
@@ -804,6 +813,31 @@
return ret;
}
+Status CameraService::getTorchStrengthLevel(const String16& cameraId,
+ int32_t* torchStrength) {
+ ATRACE_CALL();
+ Mutex::Autolock l(mServiceLock);
+ if (!mInitialized) {
+ ALOGE("%s: Camera HAL couldn't be initialized.", __FUNCTION__);
+ return STATUS_ERROR(ERROR_DISCONNECTED, "Camera HAL couldn't be initialized.");
+ }
+
+ if(torchStrength == NULL) {
+ ALOGE("%s: strength level must not be null.", __FUNCTION__);
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Strength level should not be null.");
+ }
+
+ status_t res = mCameraProviderManager->getTorchStrengthLevel(String8(cameraId).string(),
+ torchStrength);
+ if (res != OK) {
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve torch "
+ "strength level for device %s: %s (%d)", String8(cameraId).string(),
+ strerror(-res), res);
+ }
+ ALOGI("%s: Torch strength level is: %d", __FUNCTION__, *torchStrength);
+ return Status::ok();
+}
+
String8 CameraService::getFormattedCurrentTime() {
time_t now = time(nullptr);
char formattedTime[64];
@@ -2006,6 +2040,132 @@
return OK;
}
+Status CameraService::turnOnTorchWithStrengthLevel(const String16& cameraId, int32_t torchStrength,
+ const sp<IBinder>& clientBinder) {
+ Mutex::Autolock lock(mServiceLock);
+
+ ATRACE_CALL();
+ if (clientBinder == nullptr) {
+ ALOGE("%s: torch client binder is NULL", __FUNCTION__);
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
+ "Torch client binder in null.");
+ }
+
+ String8 id = String8(cameraId.string());
+ int uid = CameraThreadState::getCallingUid();
+
+ if (shouldRejectSystemCameraConnection(id)) {
+ return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to change the strength level"
+ "for system only device %s: ", id.string());
+ }
+
+ // verify id is valid
+ auto state = getCameraState(id);
+ if (state == nullptr) {
+ ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string());
+ return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
+ "Camera ID \"%s\" is a not valid camera ID", id.string());
+ }
+
+ StatusInternal cameraStatus = state->getStatus();
+ if (cameraStatus != StatusInternal::NOT_AVAILABLE &&
+ cameraStatus != StatusInternal::PRESENT) {
+ ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, id.string(),
+ (int)cameraStatus);
+ return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
+ "Camera ID \"%s\" is a not valid camera ID", id.string());
+ }
+
+ {
+ Mutex::Autolock al(mTorchStatusMutex);
+ TorchModeStatus status;
+ status_t err = getTorchStatusLocked(id, &status);
+ if (err != OK) {
+ if (err == NAME_NOT_FOUND) {
+ return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
+ "Camera \"%s\" does not have a flash unit", id.string());
+ }
+ ALOGE("%s: getting current torch status failed for camera %s",
+ __FUNCTION__, id.string());
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
+ "Error changing torch strength level for camera \"%s\": %s (%d)",
+ id.string(), strerror(-err), err);
+ }
+
+ if (status == TorchModeStatus::NOT_AVAILABLE) {
+ if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
+ ALOGE("%s: torch mode of camera %s is not available because "
+ "camera is in use.", __FUNCTION__, id.string());
+ return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
+ "Torch for camera \"%s\" is not available due to an existing camera user",
+ id.string());
+ } else {
+ ALOGE("%s: torch mode of camera %s is not available due to "
+ "insufficient resources", __FUNCTION__, id.string());
+ return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
+ "Torch for camera \"%s\" is not available due to insufficient resources",
+ id.string());
+ }
+ }
+ }
+
+ {
+ Mutex::Autolock al(mTorchUidMapMutex);
+ updateTorchUidMapLocked(cameraId, uid);
+ }
+ // Check if the current torch strength level is same as the new one.
+ bool shouldSkipTorchStrengthUpdates = mCameraProviderManager->shouldSkipTorchStrengthUpdate(
+ id.string(), torchStrength);
+
+ status_t err = mFlashlight->turnOnTorchWithStrengthLevel(id, torchStrength);
+
+ if (err != OK) {
+ int32_t errorCode;
+ String8 msg;
+ switch (err) {
+ case -ENOSYS:
+ msg = String8::format("Camera \"%s\" has no flashlight.",
+ id.string());
+ errorCode = ERROR_ILLEGAL_ARGUMENT;
+ break;
+ case -EBUSY:
+ msg = String8::format("Camera \"%s\" is in use",
+ id.string());
+ errorCode = ERROR_CAMERA_IN_USE;
+ break;
+ default:
+ msg = String8::format("Changing torch strength level failed.");
+ errorCode = ERROR_INVALID_OPERATION;
+
+ }
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(errorCode, msg.string());
+ }
+
+ {
+ // update the link to client's death
+ // Store the last client that turns on each camera's torch mode.
+ Mutex::Autolock al(mTorchClientMapMutex);
+ ssize_t index = mTorchClientMap.indexOfKey(id);
+ if (index == NAME_NOT_FOUND) {
+ mTorchClientMap.add(id, clientBinder);
+ } else {
+ mTorchClientMap.valueAt(index)->unlinkToDeath(this);
+ mTorchClientMap.replaceValueAt(index, clientBinder);
+ }
+ clientBinder->linkToDeath(this);
+ }
+
+ int clientPid = CameraThreadState::getCallingPid();
+ const char *id_cstr = id.c_str();
+ ALOGI("%s: Torch strength for camera id %s changed to %d for client PID %d",
+ __FUNCTION__, id_cstr, torchStrength, clientPid);
+ if (!shouldSkipTorchStrengthUpdates) {
+ broadcastTorchStrengthLevel(id, torchStrength);
+ }
+ return Status::ok();
+}
+
Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
const sp<IBinder>& clientBinder) {
Mutex::Autolock lock(mServiceLock);
@@ -2077,13 +2237,7 @@
// Update UID map - this is used in the torch status changed callbacks, so must be done
// before setTorchMode
Mutex::Autolock al(mTorchUidMapMutex);
- if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
- mTorchUidMap[id].first = uid;
- mTorchUidMap[id].second = uid;
- } else {
- // Set the pending UID
- mTorchUidMap[id].first = uid;
- }
+ updateTorchUidMapLocked(cameraId, uid);
}
status_t err = mFlashlight->setTorchMode(id, enabled);
@@ -2138,6 +2292,17 @@
return Status::ok();
}
+void CameraService::updateTorchUidMapLocked(const String16& cameraId, int uid) {
+ String8 id = String8(cameraId.string());
+ if (mTorchUidMap.find(id) == mTorchUidMap.end()) {
+ mTorchUidMap[id].first = uid;
+ mTorchUidMap[id].second = uid;
+ } else {
+ // Set the pending UID
+ mTorchUidMap[id].first = uid;
+ }
+}
+
Status CameraService::notifySystemEvent(int32_t eventId,
const std::vector<int32_t>& args) {
const int pid = CameraThreadState::getCallingPid();
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 51c734f..060f075 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -172,6 +172,12 @@
virtual binder::Status setTorchMode(const String16& cameraId, bool enabled,
const sp<IBinder>& clientBinder);
+ virtual binder::Status turnOnTorchWithStrengthLevel(const String16& cameraId,
+ int32_t torchStrength, const sp<IBinder>& clientBinder);
+
+ virtual binder::Status getTorchStrengthLevel(const String16& cameraId,
+ int32_t* torchStrength);
+
virtual binder::Status notifySystemEvent(int32_t eventId,
const std::vector<int32_t>& args);
@@ -1232,6 +1238,8 @@
hardware::camera::common::V1_0::TorchModeStatus status,
SystemCameraKind systemCameraKind);
+ void broadcastTorchStrengthLevel(const String8& cameraId, int32_t newTorchStrengthLevel);
+
void disconnectClient(const String8& id, sp<BasicClient> clientToDisconnect);
// Regular online and offline devices must not be in conflict at camera service layer.
@@ -1310,6 +1318,8 @@
bool mInjectionInitPending = false;
// Guard mInjectionInternalCamId and mInjectionInitPending.
Mutex mInjectionParametersLock;
+
+ void updateTorchUidMapLocked(const String16& cameraId, int uid);
};
} // namespace android
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 0cce2ca..d37d717 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,7 +20,7 @@
#include "CameraProviderManager.h"
-#include <android/hardware/camera/device/3.7/ICameraDevice.h>
+#include <android/hardware/camera/device/3.8/ICameraDevice.h>
#include <algorithm>
#include <chrono>
@@ -307,6 +307,50 @@
return OK;
}
+status_t CameraProviderManager::getTorchStrengthLevel(const std::string &id,
+ int32_t* torchStrength /*out*/) {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ return deviceInfo->getTorchStrengthLevel(torchStrength);
+}
+
+status_t CameraProviderManager::turnOnTorchWithStrengthLevel(const std::string &id,
+ int32_t torchStrength) {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ return deviceInfo->turnOnTorchWithStrengthLevel(torchStrength);
+}
+
+bool CameraProviderManager::shouldSkipTorchStrengthUpdate(const std::string &id,
+ int32_t torchStrength) const {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ if (deviceInfo->mTorchStrengthLevel == torchStrength) {
+ ALOGV("%s: Skipping torch strength level updates prev_level: %d, new_level: %d",
+ __FUNCTION__, deviceInfo->mTorchStrengthLevel, torchStrength);
+ return true;
+ }
+ return false;
+}
+
+int32_t CameraProviderManager::getTorchDefaultStrengthLevel(const std::string &id) const {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ return deviceInfo->mTorchDefaultStrengthLevel;
+}
+
bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
for (auto& provider : mProviders) {
@@ -2385,6 +2429,22 @@
mHasFlashUnit = false;
}
+ camera_metadata_entry entry =
+ mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
+ if (entry.count == 1) {
+ mTorchDefaultStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchDefaultStrengthLevel = 0;
+ }
+
+ entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
+ if (entry.count == 1) {
+ mTorchMaximumStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchMaximumStrengthLevel = 0;
+ }
+
+ mTorchStrengthLevel = 0;
queryPhysicalCameraIds();
// Get physical camera characteristics if applicable
@@ -2468,6 +2528,80 @@
return setTorchModeForDevice<InterfaceT>(enabled);
}
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::turnOnTorchWithStrengthLevel(
+ int32_t torchStrength) {
+ const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
+ startDeviceInterface<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = nullptr;
+ auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
+ if (castResult_3_8.isOk()) {
+ interface_3_8 = castResult_3_8;
+ }
+
+ if (interface_3_8 == nullptr) {
+ return INVALID_OPERATION;
+ }
+
+ Status s = interface_3_8->turnOnTorchWithStrengthLevel(torchStrength);
+ if (s == Status::OK) {
+ mTorchStrengthLevel = torchStrength;
+ }
+ return mapToStatusT(s);
+}
+
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getTorchStrengthLevel(
+ int32_t *torchStrength) {
+ if (torchStrength == nullptr) {
+ return BAD_VALUE;
+ }
+ const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
+ startDeviceInterface<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
+ sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = nullptr;
+ if (castResult_3_8.isOk()) {
+ interface_3_8 = castResult_3_8;
+ }
+
+ if (interface_3_8 == nullptr) {
+ return INVALID_OPERATION;
+ }
+
+ Status callStatus;
+ status_t res;
+ hardware::Return<void> ret = interface_3_8->getTorchStrengthLevel([&callStatus, &torchStrength]
+ (Status status, const int32_t& torchStrengthLevel) {
+ callStatus = status;
+ if (status == Status::OK) {
+ *torchStrength = torchStrengthLevel;
+ } });
+
+ if (ret.isOk()) {
+ switch (callStatus) {
+ case Status::OK:
+ // Expected case, do nothing.
+ res = OK;
+ break;
+ case Status::METHOD_NOT_SUPPORTED:
+ res = INVALID_OPERATION;
+ break;
+ default:
+ ALOGE("%s: Get torch strength level failed: %d", __FUNCTION__, callStatus);
+ res = UNKNOWN_ERROR;
+ }
+ } else {
+ ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.description().c_str());
+ res = UNKNOWN_ERROR;
+ }
+
+ return res;
+}
+
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
hardware::CameraInfo *info) const {
if (info == nullptr) return BAD_VALUE;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index f28d128..7d13941 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -258,6 +258,17 @@
bool supportSetTorchMode(const std::string &id) const;
/**
+ * Check if torch strength update should be skipped or not.
+ */
+ bool shouldSkipTorchStrengthUpdate(const std::string &id, int32_t torchStrength) const;
+
+ /**
+ * Return the default torch strength level if the torch strength control
+ * feature is supported.
+ */
+ int32_t getTorchDefaultStrengthLevel(const std::string &id) const;
+
+ /**
* Turn on or off the flashlight on a given camera device.
* May fail if the device does not support this API, is in active use, or if the device
* doesn't exist, etc.
@@ -265,6 +276,24 @@
status_t setTorchMode(const std::string &id, bool enabled);
/**
+ * Change the brightness level of the flash unit associated with the cameraId and
+ * set it to the value in torchStrength.
+ * If the torch is OFF and torchStrength > 0, the torch will be turned ON with the
+ * specified strength level. If the torch is ON, only the brightness level will be
+ * changed.
+ *
+ * This operation will fail if the device does not have flash unit, has flash unit
+ * but does not support this API, torchStrength is invalid or if the device doesn't
+ * exist etc.
+ */
+ status_t turnOnTorchWithStrengthLevel(const std::string &id, int32_t torchStrength);
+
+ /**
+ * Return the torch strength level of this camera device.
+ */
+ status_t getTorchStrengthLevel(const std::string &id, int32_t* torchStrength);
+
+ /**
* Setup vendor tags for all registered providers
*/
status_t setUpVendorTags();
@@ -475,10 +504,17 @@
hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
wp<ProviderInfo> mParentProvider;
+ // Torch strength default, maximum levels if the torch strength control
+ // feature is supported.
+ int32_t mTorchStrengthLevel;
+ int32_t mTorchMaximumStrengthLevel;
+ int32_t mTorchDefaultStrengthLevel;
bool hasFlashUnit() const { return mHasFlashUnit; }
bool supportNativeZoomRatio() const { return mSupportNativeZoomRatio; }
virtual status_t setTorchMode(bool enabled) = 0;
+ virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) = 0;
+ virtual status_t getTorchStrengthLevel(int32_t *torchStrength) = 0;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
virtual bool isAPI1Compatible() const = 0;
virtual status_t dumpState(int fd) = 0;
@@ -551,6 +587,9 @@
typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
virtual status_t setTorchMode(bool enabled) override;
+ virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) override;
+ virtual status_t getTorchStrengthLevel(int32_t *torchStrength) override;
+
virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
virtual bool isAPI1Compatible() const override;
virtual status_t dumpState(int fd) override;
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
index 8e619e1..cca3f2e 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -70,6 +70,11 @@
return binder::Status::ok();
}
+::android::binder::Status H2BCameraServiceListener::onTorchStrengthLevelChanged(
+ const ::android::String16&, int32_t) {
+ return binder::Status::ok();
+}
+
} // implementation
} // V2_0
} // common
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 7148035..7ef413f 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -54,6 +54,8 @@
virtual ::android::binder::Status onTorchStatusChanged(
int32_t status, const ::android::String16& cameraId) override;
+ virtual ::android::binder::Status onTorchStrengthLevelChanged(
+ const ::android::String16& cameraId, int32_t newStrengthLevel) override;
virtual binder::Status onCameraAccessPrioritiesChanged() {
// TODO: no implementation yet.
return binder::Status::ok();
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index e46bf74..97d7bf4 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -466,6 +466,12 @@
// No op
return binder::Status::ok();
}
+
+ virtual binder::Status onTorchStrengthLevelChanged(const String16& /*cameraId*/,
+ int32_t /*torchStrength*/) {
+ // No op
+ return binder::Status::ok();
+ }
};
class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {