Camera: Add 3.8 version of ICameraDevice.
The new version of ICameraDevice supports interfaces for torch strength control feature. New VTS test has been added to test the emulator HAL-side implementation of the newly added interfaces. bug: 200174275 Test: Camera VTS test pass. Change-Id: Ia5652a96e09bd716b5079fe9ed071dffc53b5b12
This commit is contained in:
parent
7d4d3dace1
commit
5ad93755c8
2 changed files with 227 additions and 0 deletions
|
@ -16,6 +16,7 @@
|
|||
|
||||
package android.hardware.camera.device@3.8;
|
||||
|
||||
import android.hardware.camera.common@1.0::Status;
|
||||
import @3.7::ICameraDevice;
|
||||
|
||||
/**
|
||||
|
@ -29,4 +30,81 @@ import @3.7::ICameraDevice;
|
|||
* @3.7::ICameraDeviceSession.
|
||||
*/
|
||||
interface ICameraDevice extends @3.7::ICameraDevice {
|
||||
/**
|
||||
* turnOnTorchWithStrengthLevel:
|
||||
*
|
||||
* Change the brightness level of the flash unit associated with this camera device
|
||||
* and set it to value in torchStrength. This function also turns ON the torch
|
||||
* with specified torchStrength if the torch is OFF.
|
||||
*
|
||||
* The torchStrength value must be within the valid range i.e. >=1 and
|
||||
* <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. Whenever the torch is turned OFF,
|
||||
* the brightness level will reset to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
|
||||
* When the client calls setTorchMode(ON) after turnOnTorchWithStrengthLevel(N),
|
||||
* the flash unit will have brightness level equal to N. This level does not
|
||||
* represent the real brightness units. It is linear in nature i.e. flashlight
|
||||
* at level 10 is twice as bright as at level 5.
|
||||
*
|
||||
* @param torchStrength Brightness level to be set for the flashlight.
|
||||
*
|
||||
* @return status Status code for the operation, one of:
|
||||
* OK:
|
||||
* On a successful change to the torch strength level.
|
||||
* INTERNAL_ERROR:
|
||||
* The flash unit cannot be operated due to an unexpected internal
|
||||
* error.
|
||||
* CAMERA_IN_USE:
|
||||
* This status code is returned when:
|
||||
* - This camera device has been opened, so the torch cannot be
|
||||
* controlled until it is closed.
|
||||
* - Due to other camera devices being open, or due to other
|
||||
* resource constraints, the torch cannot be controlled currently.
|
||||
* ILLEGAL_ARGUMENT:
|
||||
* If the torchStrength value is not within the range i.e. < 1 or
|
||||
* > FLASH_INFO_STRENGTH_MAXIMUM_LEVEL.
|
||||
* METHOD_NOT_SUPPORTED:
|
||||
* This status code is returned when:
|
||||
* - This camera device does not support direct operation of flashlight
|
||||
* torch mode. The framework must open the camera device and turn
|
||||
* the torch on through the device interface.
|
||||
* - This camera device does not have a flash unit.
|
||||
* - This camera device has flash unit but does not support torch
|
||||
* strength control.
|
||||
* CAMERA_DISCONNECTED:
|
||||
* An external camera device has been disconnected, and is no longer
|
||||
* available. This camera device interface is now stale, and a new
|
||||
* instance must be acquired if the device is reconnected. All
|
||||
* subsequent calls on this interface must return
|
||||
* CAMERA_DISCONNECTED.
|
||||
*
|
||||
*/
|
||||
turnOnTorchWithStrengthLevel(int32_t torchStrength) generates (Status status);
|
||||
|
||||
/**
|
||||
* getTorchStrengthLevel:
|
||||
*
|
||||
* Get current torch strength level.
|
||||
* If the device supports torch strength control, when the torch is OFF the
|
||||
* strength level will reset to default level, so the return
|
||||
* value in this case will be equal to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
|
||||
*
|
||||
* @return status Status code for the operation, one of:
|
||||
* OK:
|
||||
* On success.
|
||||
* INTERNAL_ERROR:
|
||||
* An unexpected error occurred and the information is not
|
||||
* available.
|
||||
* METHOD_NOT_SUPPORTED:
|
||||
* This status code is returned when:
|
||||
* - This camera device does not support direct operation of flashlight
|
||||
* torch mode. The framework must open the camera device and turn
|
||||
* the torch on through the device interface.
|
||||
* - This camera device does not have a flash unit.
|
||||
* - This camera device has flash unit but does not support torch
|
||||
* strength control.
|
||||
*
|
||||
* @return torchStrength Current torch strength level.
|
||||
*
|
||||
*/
|
||||
getTorchStrengthLevel() generates (Status status, int32_t torchStrength);
|
||||
};
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <android/hardware/camera/device/3.6/ICameraDevice.h>
|
||||
#include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
|
||||
#include <android/hardware/camera/device/3.7/ICameraDevice.h>
|
||||
#include <android/hardware/camera/device/3.8/ICameraDevice.h>
|
||||
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
|
||||
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
|
||||
#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
|
||||
|
@ -911,6 +912,7 @@ public:
|
|||
uint32_t* outBufSize);
|
||||
static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
|
||||
static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
|
||||
static bool isTorchStrengthControlSupported(const camera_metadata_t *staticMeta);
|
||||
static Status isOfflineSessionSupported(const camera_metadata_t *staticMeta);
|
||||
static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
|
||||
std::unordered_set<std::string> *physicalIds/*out*/);
|
||||
|
@ -2933,6 +2935,137 @@ TEST_P(CameraHidlTest, getCameraCharacteristics) {
|
|||
}
|
||||
}
|
||||
|
||||
// Verify that the torch strength level can be set and retrieved successfully.
|
||||
TEST_P(CameraHidlTest, turnOnTorchWithStrengthLevel) {
|
||||
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
|
||||
bool torchControlSupported = false;
|
||||
bool torchStrengthControlSupported = false;
|
||||
Return<void> ret;
|
||||
|
||||
ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
|
||||
ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
torchControlSupported = support;
|
||||
});
|
||||
|
||||
sp<TorchProviderCb> cb = new TorchProviderCb(this);
|
||||
Return<Status> returnStatus = mProvider->setCallback(cb);
|
||||
ASSERT_TRUE(returnStatus.isOk());
|
||||
ASSERT_EQ(Status::OK, returnStatus);
|
||||
|
||||
for (const auto& name : cameraDeviceNames) {
|
||||
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
|
||||
int32_t defaultLevel;
|
||||
switch (deviceVersion) {
|
||||
case CAMERA_DEVICE_API_VERSION_3_8: {
|
||||
::android::sp<::android::hardware::camera::device::V3_8::ICameraDevice> device3_8;
|
||||
ALOGI("%s: Testing camera device %s", __FUNCTION__, name.c_str());
|
||||
ret = mProvider->getCameraDeviceInterface_V3_x(
|
||||
name, [&](auto status, const auto& device) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
ASSERT_NE(device, nullptr);
|
||||
auto castResult = device::V3_8::ICameraDevice::castFrom(device);
|
||||
ASSERT_TRUE(castResult.isOk());
|
||||
device3_8 = castResult;
|
||||
});
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
ret = device3_8->getCameraCharacteristics([&] (auto s, const auto& chars) {
|
||||
ASSERT_EQ(Status::OK, s);
|
||||
const camera_metadata_t* staticMeta =
|
||||
reinterpret_cast<const camera_metadata_t*>(chars.data());
|
||||
ASSERT_NE(nullptr, staticMeta);
|
||||
torchStrengthControlSupported = isTorchStrengthControlSupported(staticMeta);
|
||||
camera_metadata_ro_entry entry;
|
||||
int rc = find_camera_metadata_ro_entry(staticMeta,
|
||||
ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
|
||||
if (torchStrengthControlSupported) {
|
||||
ASSERT_EQ(rc, 0);
|
||||
ASSERT_GT(entry.count, 0);
|
||||
defaultLevel = *entry.data.i32;
|
||||
ALOGI("Default level is:%d", defaultLevel);
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
// If torchStrengthControl is supported, torchControlSupported should be true.
|
||||
if (torchStrengthControlSupported) {
|
||||
ASSERT_TRUE(torchControlSupported);
|
||||
}
|
||||
mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
|
||||
returnStatus = device3_8->turnOnTorchWithStrengthLevel(2);
|
||||
ASSERT_TRUE(returnStatus.isOk());
|
||||
// Method_not_supported check
|
||||
if (!torchStrengthControlSupported) {
|
||||
ALOGI("Torch strength control not supported.");
|
||||
ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
|
||||
} else {
|
||||
ASSERT_EQ(Status::OK, returnStatus);
|
||||
if (returnStatus == Status::OK) {
|
||||
{
|
||||
std::unique_lock<std::mutex> l(mTorchLock);
|
||||
while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
|
||||
auto timeout = std::chrono::system_clock::now() +
|
||||
std::chrono::seconds(kTorchTimeoutSec);
|
||||
ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
|
||||
timeout));
|
||||
}
|
||||
ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
|
||||
mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
|
||||
}
|
||||
ALOGI("getTorchStrengthLevel: Testing");
|
||||
ret = device3_8->getTorchStrengthLevel([&]
|
||||
(auto status, const auto& strengthLevel) {
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
ALOGI("Torch strength level is : %d", strengthLevel);
|
||||
ASSERT_EQ(strengthLevel, 2);
|
||||
});
|
||||
// Turn OFF the torch and verify torch strength level is reset to default level.
|
||||
ALOGI("Testing torch strength level reset after turning the torch OFF.");
|
||||
returnStatus = device3_8->setTorchMode(TorchMode::OFF);
|
||||
ASSERT_TRUE(returnStatus.isOk());
|
||||
ASSERT_EQ(Status::OK, returnStatus);
|
||||
{
|
||||
std::unique_lock<std::mutex> l(mTorchLock);
|
||||
while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
|
||||
auto timeout = std::chrono::system_clock::now() +
|
||||
std::chrono::seconds(kTorchTimeoutSec);
|
||||
ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
|
||||
timeout));
|
||||
}
|
||||
ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
|
||||
}
|
||||
ret = device3_8->getTorchStrengthLevel([&]
|
||||
(auto status, const auto& strengthLevel) {
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
ALOGI("Torch strength level after turning OFF torch is : %d",
|
||||
strengthLevel);
|
||||
ASSERT_EQ(strengthLevel, defaultLevel);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAMERA_DEVICE_API_VERSION_3_7:
|
||||
case CAMERA_DEVICE_API_VERSION_3_6:
|
||||
case CAMERA_DEVICE_API_VERSION_3_5:
|
||||
case CAMERA_DEVICE_API_VERSION_3_4:
|
||||
case CAMERA_DEVICE_API_VERSION_3_3:
|
||||
case CAMERA_DEVICE_API_VERSION_3_2:
|
||||
case CAMERA_DEVICE_API_VERSION_1_0: {
|
||||
ALOGI("Torch strength control feature not supported.");
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
ALOGI("Invalid device version.");
|
||||
ADD_FAILURE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//In case it is supported verify that torch can be enabled.
|
||||
//Check for corresponding toch callbacks as well.
|
||||
TEST_P(CameraHidlTest, setTorchMode) {
|
||||
|
@ -6600,6 +6733,22 @@ Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool CameraHidlTest::isTorchStrengthControlSupported(const camera_metadata_t *staticMetadata) {
|
||||
int32_t maxLevel = 0;
|
||||
camera_metadata_ro_entry maxEntry;
|
||||
int rc = find_camera_metadata_ro_entry(staticMetadata,
|
||||
ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &maxEntry);
|
||||
if (rc != 0) {
|
||||
return false;
|
||||
}
|
||||
maxLevel = *maxEntry.data.i32;
|
||||
if (maxLevel > 1) {
|
||||
ALOGI("Torch strength control supported.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the camera device has logical multi-camera capability.
|
||||
Status CameraHidlTest::isOfflineSessionSupported(const camera_metadata_t *staticMeta) {
|
||||
Status ret = Status::METHOD_NOT_SUPPORTED;
|
||||
|
|
Loading…
Reference in a new issue