Merge "wifi(implementation): Increase stop timeout" into oc-mr1-dev
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 84d76f1..81d3de1 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -34,6 +34,7 @@
"android.hardware.camera.common@1.0-helper",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.mapper@2.0",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 1392896..e4cf9af 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -26,6 +26,7 @@
#include <android/hardware/camera/device/1.0/ICameraDevice.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
@@ -101,6 +102,8 @@
using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using ::android::hidl::manager::V1_0::IServiceManager;
+using namespace ::android::hardware::camera;
+
const uint32_t kMaxPreviewWidth = 1920;
const uint32_t kMaxPreviewHeight = 1080;
const uint32_t kMaxVideoWidth = 4096;
@@ -125,8 +128,10 @@
namespace {
// "device@<version>/legacy/<id>"
const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+ const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+ const char *kHAL3_3 = "3.3";
const char *kHAL3_2 = "3.2";
const char *kHAL1_0 = "1.0";
@@ -159,8 +164,9 @@
return -1;
}
- if (version.compare(kHAL3_2) == 0) {
- // maybe switched to 3.4 or define the hidl version enumlater
+ if (version.compare(kHAL3_3) == 0) {
+ return CAMERA_DEVICE_API_VERSION_3_3;
+ } else if (version.compare(kHAL3_2) == 0) {
return CAMERA_DEVICE_API_VERSION_3_2;
} else if (version.compare(kHAL1_0) == 0) {
return CAMERA_DEVICE_API_VERSION_1_0;
@@ -605,6 +611,7 @@
void openEmptyDeviceSession(const std::string &name,
sp<ICameraProvider> provider,
sp<ICameraDeviceSession> *session /*out*/,
+ sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
camera_metadata_t **staticMeta /*out*/);
void configurePreviewStream(const std::string &name,
sp<ICameraProvider> provider,
@@ -1091,24 +1098,36 @@
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Return<void> ret;
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device3_2) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device3_2, nullptr);
- });
- ASSERT_TRUE(ret.isOk());
- } else if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
- Return<void> ret;
- ret = mProvider->getCameraDeviceInterface_V1_x(
- name, [&](auto status, const auto& device1) {
- ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device1, nullptr);
- });
- ASSERT_TRUE(ret.isOk());
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device3_x) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device3_x, nullptr);
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V1_x(
+ name, [&](auto status, const auto& device1) {
+ ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device1, nullptr);
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -1119,52 +1138,64 @@
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
- ALOGI("getResourceCost: Testing camera device %s", name.c_str());
- Return<void> ret;
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
+ ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- ret = device3_2->getResourceCost([&](auto status, const auto& resourceCost) {
- ALOGI("getResourceCost returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ALOGI(" Resource cost is %d", resourceCost.resourceCost);
- ASSERT_LE(resourceCost.resourceCost, 100u);
- for (const auto& name : resourceCost.conflictingDevices) {
- ALOGI(" Conflicting device: %s", name.c_str());
- }
- });
- ASSERT_TRUE(ret.isOk());
- } else {
- ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
- ALOGI("getResourceCost: Testing camera device %s", name.c_str());
- Return<void> ret;
- ret = mProvider->getCameraDeviceInterface_V1_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+ ret = device3_x->getResourceCost([&](auto status, const auto& resourceCost) {
+ ALOGI("getResourceCost returns status:%d", (int)status);
ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device1 = device;
+ ALOGI(" Resource cost is %d", resourceCost.resourceCost);
+ ASSERT_LE(resourceCost.resourceCost, 100u);
+ for (const auto& name : resourceCost.conflictingDevices) {
+ ALOGI(" Conflicting device: %s", name.c_str());
+ }
});
- ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+ ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V1_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device1 = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- ret = device1->getResourceCost([&](auto status, const auto& resourceCost) {
- ALOGI("getResourceCost returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ALOGI(" Resource cost is %d", resourceCost.resourceCost);
- ASSERT_LE(resourceCost.resourceCost, 100u);
- for (const auto& name : resourceCost.conflictingDevices) {
- ALOGI(" Conflicting device: %s", name.c_str());
- }
- });
- ASSERT_TRUE(ret.isOk());
+ ret = device1->getResourceCost([&](auto status, const auto& resourceCost) {
+ ALOGI("getResourceCost returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ALOGI(" Resource cost is %d", resourceCost.resourceCost);
+ ASSERT_LE(resourceCost.resourceCost, 100u);
+ for (const auto& name : resourceCost.conflictingDevices) {
+ ALOGI(" Conflicting device: %s", name.c_str());
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -1846,33 +1877,47 @@
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
- ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
- Return<void> ret;
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
+ ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
+ Return<void> ret;
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- ret = device3_2->getCameraCharacteristics([&](auto status, const auto& chars) {
- ALOGI("getCameraCharacteristics returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
- size_t expectedSize = chars.size();
- int result = validate_camera_metadata_structure(metadata, &expectedSize);
- ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
- size_t entryCount = get_camera_metadata_entry_count(metadata);
- // TODO: we can do better than 0 here. Need to check how many required
- // characteristics keys we've defined.
- ASSERT_GT(entryCount, 0u);
- ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
- });
- ASSERT_TRUE(ret.isOk());
+ ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
+ ALOGI("getCameraCharacteristics returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
+ size_t expectedSize = chars.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ size_t entryCount = get_camera_metadata_entry_count(metadata);
+ // TODO: we can do better than 0 here. Need to check how many required
+ // characteristics keys we've defined.
+ ASSERT_GT(entryCount, 0u);
+ ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -1896,102 +1941,116 @@
ASSERT_EQ(Status::OK, returnStatus);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
- ALOGI("setTorchMode: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
+ ALOGI("setTorchMode: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
- returnStatus = device3_2->setTorchMode(TorchMode::ON);
- ASSERT_TRUE(returnStatus.isOk());
- if (!torchControlSupported) {
- ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
- } else {
- ASSERT_TRUE(returnStatus == Status::OK ||
- returnStatus == Status::OPERATION_NOT_SUPPORTED);
- 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));
+ mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+ returnStatus = device3_x->setTorchMode(TorchMode::ON);
+ ASSERT_TRUE(returnStatus.isOk());
+ if (!torchControlSupported) {
+ ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+ } else {
+ ASSERT_TRUE(returnStatus == Status::OK ||
+ returnStatus == Status::OPERATION_NOT_SUPPORTED);
+ 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;
}
- ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
- mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
- }
- returnStatus = device3_2->setTorchMode(TorchMode::OFF);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ returnStatus = device3_x->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));
+ {
+ 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);
}
- ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
}
}
}
- } else if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
- ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
- ALOGI("dumpState: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V1_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device1 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+ ALOGI("dumpState: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V1_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device1 = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
- returnStatus = device1->setTorchMode(TorchMode::ON);
- ASSERT_TRUE(returnStatus.isOk());
- if (!torchControlSupported) {
- ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
- } else {
- ASSERT_TRUE(returnStatus == Status::OK ||
- returnStatus == Status::OPERATION_NOT_SUPPORTED);
- 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));
+ mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+ returnStatus = device1->setTorchMode(TorchMode::ON);
+ ASSERT_TRUE(returnStatus.isOk());
+ if (!torchControlSupported) {
+ ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+ } else {
+ ASSERT_TRUE(returnStatus == Status::OK ||
+ returnStatus == Status::OPERATION_NOT_SUPPORTED);
+ 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;
}
- ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
- mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
- }
- returnStatus = device1->setTorchMode(TorchMode::OFF);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ returnStatus = device1->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));
+ {
+ 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);
}
- ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
}
}
+ ret = device1->close();
+ ASSERT_TRUE(ret.isOk());
}
- ret = device1->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
@@ -2006,47 +2065,59 @@
Return<void> ret;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<ICameraDevice> device3_2;
- ALOGI("dumpState: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<ICameraDevice> device3_x;
+ ALOGI("dumpState: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- native_handle_t* raw_handle = native_handle_create(1, 0);
- raw_handle->data[0] = open(kDumpOutput, O_RDWR);
- ASSERT_GE(raw_handle->data[0], 0);
- hidl_handle handle = raw_handle;
- ret = device3_2->dumpState(handle);
- ASSERT_TRUE(ret.isOk());
- close(raw_handle->data[0]);
- native_handle_delete(raw_handle);
- } else if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
- ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
- ALOGI("dumpState: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V1_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device1 = device;
- });
- ASSERT_TRUE(ret.isOk());
+ native_handle_t* raw_handle = native_handle_create(1, 0);
+ raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+ ASSERT_GE(raw_handle->data[0], 0);
+ hidl_handle handle = raw_handle;
+ ret = device3_x->dumpState(handle);
+ ASSERT_TRUE(ret.isOk());
+ close(raw_handle->data[0]);
+ native_handle_delete(raw_handle);
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+ ALOGI("dumpState: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V1_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device1 = device;
+ });
+ ASSERT_TRUE(ret.isOk());
- native_handle_t* raw_handle = native_handle_create(1, 0);
- raw_handle->data[0] = open(kDumpOutput, O_RDWR);
- ASSERT_GE(raw_handle->data[0], 0);
- hidl_handle handle = raw_handle;
- Return<Status> returnStatus = device1->dumpState(handle);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
- close(raw_handle->data[0]);
- native_handle_delete(raw_handle);
+ native_handle_t* raw_handle = native_handle_create(1, 0);
+ raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+ ASSERT_GE(raw_handle->data[0], 0);
+ hidl_handle handle = raw_handle;
+ Return<Status> returnStatus = device1->dumpState(handle);
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, returnStatus);
+ close(raw_handle->data[0]);
+ native_handle_delete(raw_handle);
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2057,58 +2128,79 @@
Return<void> ret;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
- ALOGI("openClose: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
+ ALOGI("openClose: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+ sp<ICameraDeviceSession> session;
+ ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
+ ALOGI("device::open returns status:%d", (int)status);
ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
+ ASSERT_NE(newSession, nullptr);
+ session = newSession;
});
- ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(ret.isOk());
+ // Ensure that a device labeling itself as 3.3 can have its session interface cast
+ // to the 3.3 interface, and that lower versions can't be cast to it.
+ auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session);
+ ASSERT_TRUE(castResult.isOk());
+ sp<device::V3_3::ICameraDeviceSession> sessionV3_3 = castResult;
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
+ ASSERT_TRUE(sessionV3_3.get() != nullptr);
+ } else {
+ ASSERT_TRUE(sessionV3_3.get() == nullptr);
+ }
+ native_handle_t* raw_handle = native_handle_create(1, 0);
+ raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+ ASSERT_GE(raw_handle->data[0], 0);
+ hidl_handle handle = raw_handle;
+ ret = device3_x->dumpState(handle);
+ ASSERT_TRUE(ret.isOk());
+ close(raw_handle->data[0]);
+ native_handle_delete(raw_handle);
- sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
- sp<ICameraDeviceSession> session;
- ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
- ALOGI("device::open returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(newSession, nullptr);
- session = newSession;
- });
- ASSERT_TRUE(ret.isOk());
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ // TODO: test all session API calls return INTERNAL_ERROR after close
+ // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+ openCameraDevice(name, mProvider, &device1 /*out*/);
+ ASSERT_NE(nullptr, device1.get());
- native_handle_t* raw_handle = native_handle_create(1, 0);
- raw_handle->data[0] = open(kDumpOutput, O_RDWR);
- ASSERT_GE(raw_handle->data[0], 0);
- hidl_handle handle = raw_handle;
- ret = device3_2->dumpState(handle);
- ASSERT_TRUE(ret.isOk());
- close(raw_handle->data[0]);
- native_handle_delete(raw_handle);
+ native_handle_t* raw_handle = native_handle_create(1, 0);
+ raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+ ASSERT_GE(raw_handle->data[0], 0);
+ hidl_handle handle = raw_handle;
+ Return<Status> returnStatus = device1->dumpState(handle);
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, returnStatus);
+ close(raw_handle->data[0]);
+ native_handle_delete(raw_handle);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
- // TODO: test all session API calls return INTERNAL_ERROR after close
- // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
- } else if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
- sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
- openCameraDevice(name, mProvider, &device1 /*out*/);
- ASSERT_NE(nullptr, device1.get());
-
- native_handle_t* raw_handle = native_handle_create(1, 0);
- raw_handle->data[0] = open(kDumpOutput, O_RDWR);
- ASSERT_GE(raw_handle->data[0], 0);
- hidl_handle handle = raw_handle;
- Return<Status> returnStatus = device1->dumpState(handle);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
- close(raw_handle->data[0]);
- native_handle_delete(raw_handle);
-
- ret = device1->close();
- ASSERT_TRUE(ret.isOk());
+ ret = device1->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2119,73 +2211,88 @@
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
- Return<void> ret;
- ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
- ret = mProvider->getCameraDeviceInterface_V3_x(
- name, [&](auto status, const auto& device) {
- ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
+ Return<void> ret;
+ ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
+ ret = mProvider->getCameraDeviceInterface_V3_x(
+ name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+ sp<ICameraDeviceSession> session;
+ ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
+ ALOGI("device::open returns status:%d", (int)status);
ASSERT_EQ(Status::OK, status);
- ASSERT_NE(device, nullptr);
- device3_2 = device;
+ ASSERT_NE(newSession, nullptr);
+ session = newSession;
});
- ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(ret.isOk());
- sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
- sp<ICameraDeviceSession> session;
- ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
- ALOGI("device::open returns status:%d", (int)status);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(newSession, nullptr);
- session = newSession;
- });
- ASSERT_TRUE(ret.isOk());
+ for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
+ t <= (uint32_t)RequestTemplate::MANUAL; t++) {
+ RequestTemplate reqTemplate = (RequestTemplate)t;
+ ret =
+ session->constructDefaultRequestSettings(
+ reqTemplate, [&](auto status, const auto& req) {
+ ALOGI("constructDefaultRequestSettings returns status:%d",
+ (int)status);
+ if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
+ reqTemplate == RequestTemplate::MANUAL) {
+ // optional templates
+ ASSERT_TRUE((status == Status::OK) ||
+ (status == Status::ILLEGAL_ARGUMENT));
+ } else {
+ ASSERT_EQ(Status::OK, status);
+ }
- for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
- t <= (uint32_t)RequestTemplate::MANUAL; t++) {
- RequestTemplate reqTemplate = (RequestTemplate)t;
- ret =
- session->constructDefaultRequestSettings(
- reqTemplate, [&](auto status, const auto& req) {
- ALOGI("constructDefaultRequestSettings returns status:%d",
- (int)status);
- if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
- reqTemplate == RequestTemplate::MANUAL) {
- // optional templates
- ASSERT_TRUE((status == Status::OK) ||
- (status == Status::ILLEGAL_ARGUMENT));
- } else {
- ASSERT_EQ(Status::OK, status);
- }
-
- if (status == Status::OK) {
- const camera_metadata_t* metadata =
- (camera_metadata_t*) req.data();
- size_t expectedSize = req.size();
- int result = validate_camera_metadata_structure(
- metadata, &expectedSize);
- ASSERT_TRUE((result == 0) ||
- (result == CAMERA_METADATA_VALIDATION_SHIFTED));
- size_t entryCount =
- get_camera_metadata_entry_count(metadata);
- // TODO: we can do better than 0 here. Need to check how many required
- // request keys we've defined for each template
- ASSERT_GT(entryCount, 0u);
- ALOGI("template %u metadata entry count is %zu",
- t, entryCount);
- } else {
- ASSERT_EQ(0u, req.size());
- }
- });
+ if (status == Status::OK) {
+ const camera_metadata_t* metadata =
+ (camera_metadata_t*) req.data();
+ size_t expectedSize = req.size();
+ int result = validate_camera_metadata_structure(
+ metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) ||
+ (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ size_t entryCount =
+ get_camera_metadata_entry_count(metadata);
+ // TODO: we can do better than 0 here. Need to check how many required
+ // request keys we've defined for each template
+ ASSERT_GT(entryCount, 0u);
+ ALOGI("template %u metadata entry count is %zu",
+ t, entryCount);
+ } else {
+ ASSERT_EQ(0u, req.size());
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ }
+ ret = session->close();
ASSERT_TRUE(ret.isOk());
}
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
+
// Verify that all supported stream formats and sizes can be configured
// successfully.
TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
@@ -2193,41 +2300,66 @@
std::vector<AvailableStream> outputStreams;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- outputStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
- ASSERT_NE(0u, outputStreams.size());
+ outputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+ ASSERT_NE(0u, outputStreams.size());
- int32_t streamId = 0;
- for (auto& it : outputStreams) {
- Stream stream = {streamId,
- StreamType::OUTPUT,
- static_cast<uint32_t>(it.width),
- static_cast<uint32_t>(it.height),
- static_cast<PixelFormat>(it.format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- StreamRotation::ROTATION_0};
- ::android::hardware::hidl_vec<Stream> streams = {stream};
- StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(
- config, [streamId](Status s, HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(1u, halConfig.streams.size());
- ASSERT_EQ(halConfig.streams[0].id, streamId);
- });
+ int32_t streamId = 0;
+ for (auto& it : outputStreams) {
+ Stream stream = {streamId,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(it.width),
+ static_cast<uint32_t>(it.height),
+ static_cast<PixelFormat>(it.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ StreamRotation::ROTATION_0};
+ ::android::hardware::hidl_vec<Stream> streams = {stream};
+ StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [streamId](Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ ASSERT_EQ(halConfig.streams[0].id, streamId);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+ streamId++;
+ }
+
+ free_camera_metadata(staticMeta);
+ ret = session->close();
ASSERT_TRUE(ret.isOk());
- streamId++;
}
-
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2238,82 +2370,132 @@
std::vector<AvailableStream> outputStreams;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- outputStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
- ASSERT_NE(0u, outputStreams.size());
+ outputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+ ASSERT_NE(0u, outputStreams.size());
- int32_t streamId = 0;
- Stream stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(0),
- static_cast<uint32_t>(0),
- static_cast<PixelFormat>(outputStreams[0].format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- StreamRotation::ROTATION_0};
- ::android::hardware::hidl_vec<Stream> streams = {stream};
- StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || (Status::INTERNAL_ERROR == s));
- });
- ASSERT_TRUE(ret.isOk());
+ int32_t streamId = 0;
+ Stream stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(0),
+ static_cast<uint32_t>(0),
+ static_cast<PixelFormat>(outputStreams[0].format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ StreamRotation::ROTATION_0};
+ ::android::hardware::hidl_vec<Stream> streams = {stream};
+ StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
+ if(session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+ (Status::INTERNAL_ERROR == s));
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+ (Status::INTERNAL_ERROR == s));
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
- stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(UINT32_MAX),
- static_cast<uint32_t>(UINT32_MAX),
- static_cast<PixelFormat>(outputStreams[0].format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- StreamRotation::ROTATION_0};
- streams[0] = stream;
- config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
- });
- ASSERT_TRUE(ret.isOk());
-
- for (auto& it : outputStreams) {
stream = {streamId++,
StreamType::OUTPUT,
- static_cast<uint32_t>(it.width),
- static_cast<uint32_t>(it.height),
- static_cast<PixelFormat>(UINT32_MAX),
+ static_cast<uint32_t>(UINT32_MAX),
+ static_cast<uint32_t>(UINT32_MAX),
+ static_cast<PixelFormat>(outputStreams[0].format),
GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
0,
StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
- });
+ if(session3_3 == nullptr) {
+ ret = session->configureStreams(config, [](Status s,
+ HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config, [](Status s,
+ device::V3_3::HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ }
ASSERT_TRUE(ret.isOk());
- stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(it.width),
- static_cast<uint32_t>(it.height),
- static_cast<PixelFormat>(it.format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- static_cast<StreamRotation>(UINT32_MAX)};
- streams[0] = stream;
- config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
- });
+ for (auto& it : outputStreams) {
+ stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(it.width),
+ static_cast<uint32_t>(it.height),
+ static_cast<PixelFormat>(UINT32_MAX),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ StreamRotation::ROTATION_0};
+ streams[0] = stream;
+ config = {streams, StreamConfigurationMode::NORMAL_MODE};
+ if(session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+
+ stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(it.width),
+ static_cast<uint32_t>(it.height),
+ static_cast<PixelFormat>(it.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ static_cast<StreamRotation>(UINT32_MAX)};
+ streams[0] = stream;
+ config = {streams, StreamConfigurationMode::NORMAL_MODE};
+ if(session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ free_camera_metadata(staticMeta);
+ ret = session->close();
ASSERT_TRUE(ret.isOk());
}
-
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2326,79 +2508,107 @@
std::vector<AvailableZSLInputOutput> inputOutputMap;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- Status rc = isZSLModeAvailable(staticMeta);
- if (Status::METHOD_NOT_SUPPORTED == rc) {
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
- continue;
- }
- ASSERT_EQ(Status::OK, rc);
+ Status rc = isZSLModeAvailable(staticMeta);
+ if (Status::METHOD_NOT_SUPPORTED == rc) {
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+ ASSERT_EQ(Status::OK, rc);
- inputStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
- ASSERT_NE(0u, inputStreams.size());
-
- inputOutputMap.clear();
- ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
- ASSERT_NE(0u, inputOutputMap.size());
-
- int32_t streamId = 0;
- for (auto& inputIter : inputOutputMap) {
- AvailableStream input;
- ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, input));
+ inputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
ASSERT_NE(0u, inputStreams.size());
- AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, inputIter.outputFormat};
- std::vector<AvailableStream> outputStreams;
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputStreams, &outputThreshold));
- for (auto& outputIter : outputStreams) {
- Stream zslStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(input.width),
- static_cast<uint32_t>(input.height),
- static_cast<PixelFormat>(input.format),
- GRALLOC_USAGE_HW_CAMERA_ZSL,
- 0,
- StreamRotation::ROTATION_0};
- Stream inputStream = {streamId++,
- StreamType::INPUT,
- static_cast<uint32_t>(input.width),
- static_cast<uint32_t>(input.height),
- static_cast<PixelFormat>(input.format),
- 0,
- 0,
- StreamRotation::ROTATION_0};
- Stream outputStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(outputIter.width),
- static_cast<uint32_t>(outputIter.height),
- static_cast<PixelFormat>(outputIter.format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- StreamRotation::ROTATION_0};
+ inputOutputMap.clear();
+ ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
+ ASSERT_NE(0u, inputOutputMap.size());
- ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream,
- outputStream};
- StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config,
- [](Status s, HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(3u, halConfig.streams.size());
- });
- ASSERT_TRUE(ret.isOk());
+ int32_t streamId = 0;
+ for (auto& inputIter : inputOutputMap) {
+ AvailableStream input;
+ ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat,
+ input));
+ ASSERT_NE(0u, inputStreams.size());
+
+ AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
+ inputIter.outputFormat};
+ std::vector<AvailableStream> outputStreams;
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputStreams,
+ &outputThreshold));
+ for (auto& outputIter : outputStreams) {
+ Stream zslStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(input.width),
+ static_cast<uint32_t>(input.height),
+ static_cast<PixelFormat>(input.format),
+ GRALLOC_USAGE_HW_CAMERA_ZSL,
+ 0,
+ StreamRotation::ROTATION_0};
+ Stream inputStream = {streamId++,
+ StreamType::INPUT,
+ static_cast<uint32_t>(input.width),
+ static_cast<uint32_t>(input.height),
+ static_cast<PixelFormat>(input.format),
+ 0,
+ 0,
+ StreamRotation::ROTATION_0};
+ Stream outputStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(outputIter.width),
+ static_cast<uint32_t>(outputIter.height),
+ static_cast<PixelFormat>(outputIter.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ StreamRotation::ROTATION_0};
+
+ ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream,
+ outputStream};
+ StreamConfiguration config = {streams,
+ StreamConfigurationMode::NORMAL_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(3u, halConfig.streams.size());
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(3u, halConfig.streams.size());
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+ }
}
- }
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ free_camera_metadata(staticMeta);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2411,58 +2621,86 @@
std::vector<AvailableStream> outputPreviewStreams;
AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
- AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, static_cast<int32_t>(PixelFormat::BLOB)};
+ AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
+ static_cast<int32_t>(PixelFormat::BLOB)};
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- outputBlobStreams.clear();
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputBlobStreams, &blobThreshold));
- ASSERT_NE(0u, outputBlobStreams.size());
+ outputBlobStreams.clear();
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputBlobStreams,
+ &blobThreshold));
+ ASSERT_NE(0u, outputBlobStreams.size());
- outputPreviewStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
- &previewThreshold));
- ASSERT_NE(0u, outputPreviewStreams.size());
+ outputPreviewStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
+ &previewThreshold));
+ ASSERT_NE(0u, outputPreviewStreams.size());
- int32_t streamId = 0;
- for (auto& blobIter : outputBlobStreams) {
- for (auto& previewIter : outputPreviewStreams) {
- Stream previewStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(previewIter.width),
- static_cast<uint32_t>(previewIter.height),
- static_cast<PixelFormat>(previewIter.format),
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
- 0,
- StreamRotation::ROTATION_0};
- Stream blobStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(blobIter.width),
- static_cast<uint32_t>(blobIter.height),
- static_cast<PixelFormat>(blobIter.format),
- GRALLOC1_CONSUMER_USAGE_CPU_READ,
- 0,
- StreamRotation::ROTATION_0};
- ::android::hardware::hidl_vec<Stream> streams = {previewStream, blobStream};
- StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config,
- [](Status s, HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(2u, halConfig.streams.size());
- });
- ASSERT_TRUE(ret.isOk());
+ int32_t streamId = 0;
+ for (auto& blobIter : outputBlobStreams) {
+ for (auto& previewIter : outputPreviewStreams) {
+ Stream previewStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(previewIter.width),
+ static_cast<uint32_t>(previewIter.height),
+ static_cast<PixelFormat>(previewIter.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
+ 0,
+ StreamRotation::ROTATION_0};
+ Stream blobStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(blobIter.width),
+ static_cast<uint32_t>(blobIter.height),
+ static_cast<PixelFormat>(blobIter.format),
+ GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ 0,
+ StreamRotation::ROTATION_0};
+ ::android::hardware::hidl_vec<Stream> streams = {previewStream,
+ blobStream};
+ StreamConfiguration config = {streams,
+ StreamConfigurationMode::NORMAL_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(2u, halConfig.streams.size());
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(2u, halConfig.streams.size());
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+ }
}
- }
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ free_camera_metadata(staticMeta);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2474,92 +2712,143 @@
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- Status rc = isConstrainedModeAvailable(staticMeta);
- if (Status::METHOD_NOT_SUPPORTED == rc) {
+ Status rc = isConstrainedModeAvailable(staticMeta);
+ if (Status::METHOD_NOT_SUPPORTED == rc) {
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+ ASSERT_EQ(Status::OK, rc);
+
+ AvailableStream hfrStream;
+ rc = pickConstrainedModeSize(staticMeta, hfrStream);
+ ASSERT_EQ(Status::OK, rc);
+
+ int32_t streamId = 0;
+ Stream stream = {streamId,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(hfrStream.width),
+ static_cast<uint32_t>(hfrStream.height),
+ static_cast<PixelFormat>(hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ 0,
+ StreamRotation::ROTATION_0};
+ ::android::hardware::hidl_vec<Stream> streams = {stream};
+ StreamConfiguration config = {streams,
+ StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [streamId](Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ ASSERT_EQ(halConfig.streams[0].id, streamId);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+
+ stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(0),
+ static_cast<uint32_t>(0),
+ static_cast<PixelFormat>(hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ 0,
+ StreamRotation::ROTATION_0};
+ streams[0] = stream;
+ config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+ (Status::INTERNAL_ERROR == s));
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+ (Status::INTERNAL_ERROR == s));
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+
+ stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(UINT32_MAX),
+ static_cast<uint32_t>(UINT32_MAX),
+ static_cast<PixelFormat>(hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ 0,
+ StreamRotation::ROTATION_0};
+ streams[0] = stream;
+ config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+
+ stream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(hfrStream.width),
+ static_cast<uint32_t>(hfrStream.height),
+ static_cast<PixelFormat>(UINT32_MAX),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ 0,
+ StreamRotation::ROTATION_0};
+ streams[0] = stream;
+ config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration) {
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+
+ free_camera_metadata(staticMeta);
ret = session->close();
ASSERT_TRUE(ret.isOk());
- continue;
}
- ASSERT_EQ(Status::OK, rc);
-
- AvailableStream hfrStream;
- rc = pickConstrainedModeSize(staticMeta, hfrStream);
- ASSERT_EQ(Status::OK, rc);
-
- int32_t streamId = 0;
- Stream stream = {streamId,
- StreamType::OUTPUT,
- static_cast<uint32_t>(hfrStream.width),
- static_cast<uint32_t>(hfrStream.height),
- static_cast<PixelFormat>(hfrStream.format),
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
- 0,
- StreamRotation::ROTATION_0};
- ::android::hardware::hidl_vec<Stream> streams = {stream};
- StreamConfiguration config = {streams,
- StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
- ret = session->configureStreams(config,
- [streamId](Status s, HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(1u, halConfig.streams.size());
- ASSERT_EQ(halConfig.streams[0].id, streamId);
- });
- ASSERT_TRUE(ret.isOk());
-
- stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(0),
- static_cast<uint32_t>(0),
- static_cast<PixelFormat>(hfrStream.format),
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
- 0,
- StreamRotation::ROTATION_0};
- streams[0] = stream;
- config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || (Status::INTERNAL_ERROR == s));
- });
- ASSERT_TRUE(ret.isOk());
-
- stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(UINT32_MAX),
- static_cast<uint32_t>(UINT32_MAX),
- static_cast<PixelFormat>(hfrStream.format),
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
- 0,
- StreamRotation::ROTATION_0};
- streams[0] = stream;
- config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
- });
- ASSERT_TRUE(ret.isOk());
-
- stream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(hfrStream.width),
- static_cast<uint32_t>(hfrStream.height),
- static_cast<PixelFormat>(UINT32_MAX),
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
- 0,
- StreamRotation::ROTATION_0};
- streams[0] = stream;
- config = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
- ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
- });
- ASSERT_TRUE(ret.isOk());
-
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2576,55 +2865,82 @@
static_cast<int32_t>(PixelFormat::BLOB)};
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- camera_metadata_t* staticMeta;
- Return<void> ret;
- sp<ICameraDeviceSession> session;
- openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ openEmptyDeviceSession(name, mProvider,
+ &session /*out*/, &session3_3 /*out*/, &staticMeta /*out*/);
- outputBlobStreams.clear();
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputBlobStreams, &blobThreshold));
- ASSERT_NE(0u, outputBlobStreams.size());
+ outputBlobStreams.clear();
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputBlobStreams,
+ &blobThreshold));
+ ASSERT_NE(0u, outputBlobStreams.size());
- outputVideoStreams.clear();
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputVideoStreams, &videoThreshold));
- ASSERT_NE(0u, outputVideoStreams.size());
+ outputVideoStreams.clear();
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputVideoStreams,
+ &videoThreshold));
+ ASSERT_NE(0u, outputVideoStreams.size());
- int32_t streamId = 0;
- for (auto& blobIter : outputBlobStreams) {
- for (auto& videoIter : outputVideoStreams) {
- Stream videoStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(videoIter.width),
- static_cast<uint32_t>(videoIter.height),
- static_cast<PixelFormat>(videoIter.format),
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
- 0,
- StreamRotation::ROTATION_0};
- Stream blobStream = {streamId++,
- StreamType::OUTPUT,
- static_cast<uint32_t>(blobIter.width),
- static_cast<uint32_t>(blobIter.height),
- static_cast<PixelFormat>(blobIter.format),
- GRALLOC1_CONSUMER_USAGE_CPU_READ,
- 0,
- StreamRotation::ROTATION_0};
- ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream};
- StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE};
- ret = session->configureStreams(config,
- [](Status s, HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(2u, halConfig.streams.size());
- });
- ASSERT_TRUE(ret.isOk());
+ int32_t streamId = 0;
+ for (auto& blobIter : outputBlobStreams) {
+ for (auto& videoIter : outputVideoStreams) {
+ Stream videoStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(videoIter.width),
+ static_cast<uint32_t>(videoIter.height),
+ static_cast<PixelFormat>(videoIter.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ 0,
+ StreamRotation::ROTATION_0};
+ Stream blobStream = {streamId++,
+ StreamType::OUTPUT,
+ static_cast<uint32_t>(blobIter.width),
+ static_cast<uint32_t>(blobIter.height),
+ static_cast<PixelFormat>(blobIter.format),
+ GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ 0,
+ StreamRotation::ROTATION_0};
+ ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream};
+ StreamConfiguration config = {streams,
+ StreamConfigurationMode::NORMAL_MODE};
+ if (session3_3 == nullptr) {
+ ret = session->configureStreams(config,
+ [](Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(2u, halConfig.streams.size());
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(2u, halConfig.streams.size());
+ });
+ }
+ ASSERT_TRUE(ret.isOk());
+ }
}
- }
- free_camera_metadata(staticMeta);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ free_camera_metadata(staticMeta);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2639,129 +2955,152 @@
::android::hardware::hidl_vec<uint8_t> settings;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Stream previewStream;
- HalStreamConfiguration halStreamConfig;
- sp<ICameraDeviceSession> session;
- bool supportsPartialResults = false;
- uint32_t partialResultCount = 0;
- configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
- &previewStream /*out*/, &halStreamConfig /*out*/,
- &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Stream previewStream;
+ HalStreamConfiguration halStreamConfig;
+ sp<ICameraDeviceSession> session;
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
+ &previewStream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/,
+ &partialResultCount /*out*/);
- std::shared_ptr<ResultMetadataQueue> resultQueue;
- auto resultQueueRet =
- session->getCaptureResultMetadataQueue(
- [&resultQueue](const auto& descriptor) {
- resultQueue = std::make_shared<ResultMetadataQueue>(
- descriptor);
- if (!resultQueue->isValid() ||
- resultQueue->availableToWrite() <= 0) {
- ALOGE("%s: HAL returns empty result metadata fmq,"
- " not use it", __func__);
- resultQueue = nullptr;
- // Don't use the queue onwards.
- }
+ std::shared_ptr<ResultMetadataQueue> resultQueue;
+ auto resultQueueRet =
+ session->getCaptureResultMetadataQueue(
+ [&resultQueue](const auto& descriptor) {
+ resultQueue = std::make_shared<ResultMetadataQueue>(
+ descriptor);
+ if (!resultQueue->isValid() ||
+ resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq,"
+ " not use it", __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+ });
+ ASSERT_TRUE(resultQueueRet.isOk());
+
+ InFlightRequest inflightReq = {1, false, supportsPartialResults,
+ partialResultCount, resultQueue};
+
+ RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+ Return<void> ret;
+ ret = session->constructDefaultRequestSettings(reqTemplate,
+ [&](auto status, const auto& req) {
+ ASSERT_EQ(Status::OK, status);
+ settings = req;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ sp<GraphicBuffer> gb = new GraphicBuffer(
+ previewStream.width, previewStream.height,
+ static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
+ android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
+ halStreamConfig.streams[0].consumerUsage));
+ ASSERT_NE(nullptr, gb.get());
+ StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+ bufferId,
+ hidl_handle(gb->getNativeBuffer()->handle),
+ BufferStatus::OK,
+ nullptr,
+ nullptr};
+ ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
+ StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
+ nullptr};
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+ emptyInputBuffer, outputBuffers};
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ mInflightMap.clear();
+ mInflightMap.add(frameNumber, &inflightReq);
+ }
+
+ Status status = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ Return<void> returnStatus = session->processCaptureRequest(
+ {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
+ uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
});
- ASSERT_TRUE(resultQueueRet.isOk());
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
- InFlightRequest inflightReq = {1, false, supportsPartialResults, partialResultCount,
- resultQueue};
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReq.errorCodeValid &&
+ ((0 < inflightReq.numBuffersLeft) ||
+ (!inflightReq.haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout,
+ mResultCondition.wait_until(l, timeout));
+ }
- RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
- Return<void> ret;
- ret = session->constructDefaultRequestSettings(reqTemplate,
- [&](auto status, const auto& req) {
- ASSERT_EQ(Status::OK, status);
- settings = req;
- });
- ASSERT_TRUE(ret.isOk());
+ ASSERT_FALSE(inflightReq.errorCodeValid);
+ ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+ ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
- sp<GraphicBuffer> gb = new GraphicBuffer(
- previewStream.width, previewStream.height,
- static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
- android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
- halStreamConfig.streams[0].consumerUsage));
- ASSERT_NE(nullptr, gb.get());
- StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
- bufferId,
- hidl_handle(gb->getNativeBuffer()->handle),
- BufferStatus::OK,
- nullptr,
- nullptr};
- ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
- StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
- emptyInputBuffer, outputBuffers};
-
- {
- std::unique_lock<std::mutex> l(mLock);
- mInflightMap.clear();
- mInflightMap.add(frameNumber, &inflightReq);
- }
-
- Status status = Status::INTERNAL_ERROR;
- uint32_t numRequestProcessed = 0;
- hidl_vec<BufferCache> cachesToRemove;
- Return<void> returnStatus = session->processCaptureRequest(
- {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
- status = s;
- numRequestProcessed = n;
- });
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, status);
- ASSERT_EQ(numRequestProcessed, 1u);
-
- {
- std::unique_lock<std::mutex> l(mLock);
- while (!inflightReq.errorCodeValid &&
- ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
- auto timeout = std::chrono::system_clock::now() +
- std::chrono::seconds(kStreamBufferTimeoutSec);
- ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ request.frameNumber++;
+ // Empty settings should be supported after the first call
+ // for repeating requests.
+ request.settings.setToExternal(nullptr, 0, true);
+ // The buffer has been registered to HAL by bufferId, so per
+ // API contract we should send a null handle for this buffer
+ request.outputBuffers[0].buffer = nullptr;
+ mInflightMap.clear();
+ inflightReq = {1, false, supportsPartialResults, partialResultCount,
+ resultQueue};
+ mInflightMap.add(request.frameNumber, &inflightReq);
}
- ASSERT_FALSE(inflightReq.errorCodeValid);
- ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
- ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
+ returnStatus = session->processCaptureRequest(
+ {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
+ uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
- request.frameNumber++;
- // Empty settings should be supported after the first call
- // for repeating requests.
- request.settings.setToExternal(nullptr, 0, true);
- // The buffer has been registered to HAL by bufferId, so per
- // API contract we should send a null handle for this buffer
- request.outputBuffers[0].buffer = nullptr;
- mInflightMap.clear();
- inflightReq = {1, false, supportsPartialResults, partialResultCount, resultQueue};
- mInflightMap.add(request.frameNumber, &inflightReq);
- }
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReq.errorCodeValid &&
+ ((0 < inflightReq.numBuffersLeft) ||
+ (!inflightReq.haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout,
+ mResultCondition.wait_until(l, timeout));
+ }
- returnStatus = session->processCaptureRequest(
- {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
- status = s;
- numRequestProcessed = n;
- });
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, status);
- ASSERT_EQ(numRequestProcessed, 1u);
-
- {
- std::unique_lock<std::mutex> l(mLock);
- while (!inflightReq.errorCodeValid &&
- ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
- auto timeout = std::chrono::system_clock::now() +
- std::chrono::seconds(kStreamBufferTimeoutSec);
- ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ ASSERT_FALSE(inflightReq.errorCodeValid);
+ ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+ ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
}
- ASSERT_FALSE(inflightReq.errorCodeValid);
- ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
- ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
}
-
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2778,48 +3117,65 @@
::android::hardware::hidl_vec<uint8_t> settings;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Stream previewStream;
- HalStreamConfiguration halStreamConfig;
- sp<ICameraDeviceSession> session;
- bool supportsPartialResults = false;
- uint32_t partialResultCount = 0;
- configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
- &previewStream /*out*/, &halStreamConfig /*out*/,
- &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Stream previewStream;
+ HalStreamConfiguration halStreamConfig;
+ sp<ICameraDeviceSession> session;
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
+ &previewStream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/,
+ &partialResultCount /*out*/);
- sp<GraphicBuffer> gb = new GraphicBuffer(
- previewStream.width, previewStream.height,
- static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
- android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
- halStreamConfig.streams[0].consumerUsage));
+ sp<GraphicBuffer> gb = new GraphicBuffer(
+ previewStream.width, previewStream.height,
+ static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
+ android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
+ halStreamConfig.streams[0].consumerUsage));
- StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
- bufferId,
- hidl_handle(gb->getNativeBuffer()->handle),
- BufferStatus::OK,
- nullptr,
- nullptr};
- ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
- StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
- emptyInputBuffer, outputBuffers};
+ StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+ bufferId,
+ hidl_handle(gb->getNativeBuffer()->handle),
+ BufferStatus::OK,
+ nullptr,
+ nullptr};
+ ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
+ StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
+ nullptr};
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+ emptyInputBuffer, outputBuffers};
- // Settings were not correctly initialized, we should fail here
- Status status = Status::OK;
- uint32_t numRequestProcessed = 0;
- hidl_vec<BufferCache> cachesToRemove;
- Return<void> ret = session->processCaptureRequest(
- {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
- status = s;
- numRequestProcessed = n;
- });
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
- ASSERT_EQ(numRequestProcessed, 0u);
+ // Settings were not correctly initialized, we should fail here
+ Status status = Status::OK;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ Return<void> ret = session->processCaptureRequest(
+ {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
+ uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+ ASSERT_EQ(numRequestProcessed, 0u);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2835,45 +3191,62 @@
::android::hardware::hidl_vec<uint8_t> settings;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Stream previewStream;
- HalStreamConfiguration halStreamConfig;
- sp<ICameraDeviceSession> session;
- bool supportsPartialResults = false;
- uint32_t partialResultCount = 0;
- configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
- &previewStream /*out*/, &halStreamConfig /*out*/,
- &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Stream previewStream;
+ HalStreamConfiguration halStreamConfig;
+ sp<ICameraDeviceSession> session;
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
+ &previewStream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/,
+ &partialResultCount /*out*/);
- RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
- Return<void> ret;
- ret = session->constructDefaultRequestSettings(reqTemplate,
- [&](auto status, const auto& req) {
- ASSERT_EQ(Status::OK, status);
- settings = req;
- });
- ASSERT_TRUE(ret.isOk());
+ RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+ Return<void> ret;
+ ret = session->constructDefaultRequestSettings(reqTemplate,
+ [&](auto status, const auto& req) {
+ ASSERT_EQ(Status::OK, status);
+ settings = req;
+ });
+ ASSERT_TRUE(ret.isOk());
- ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
- StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
- CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
- emptyInputBuffer, emptyOutputBuffers};
+ ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
+ StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
+ nullptr};
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+ emptyInputBuffer, emptyOutputBuffers};
- // Output buffers are missing, we should fail here
- Status status = Status::OK;
- uint32_t numRequestProcessed = 0;
- hidl_vec<BufferCache> cachesToRemove;
- ret = session->processCaptureRequest(
- {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
- status = s;
- numRequestProcessed = n;
- });
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
- ASSERT_EQ(numRequestProcessed, 0u);
+ // Output buffers are missing, we should fail here
+ Status status = Status::OK;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ ret = session->processCaptureRequest(
+ {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
+ uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
+ ASSERT_EQ(numRequestProcessed, 0u);
- ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -2889,113 +3262,131 @@
::android::hardware::hidl_vec<uint8_t> settings;
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Stream previewStream;
- HalStreamConfiguration halStreamConfig;
- sp<ICameraDeviceSession> session;
- bool supportsPartialResults = false;
- uint32_t partialResultCount = 0;
- configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
- &previewStream /*out*/, &halStreamConfig /*out*/,
- &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Stream previewStream;
+ HalStreamConfiguration halStreamConfig;
+ sp<ICameraDeviceSession> session;
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
+ &previewStream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/,
+ &partialResultCount /*out*/);
- std::shared_ptr<ResultMetadataQueue> resultQueue;
- auto resultQueueRet =
- session->getCaptureResultMetadataQueue(
- [&resultQueue](const auto& descriptor) {
- resultQueue = std::make_shared<ResultMetadataQueue>(
- descriptor);
- if (!resultQueue->isValid() ||
- resultQueue->availableToWrite() <= 0) {
- ALOGE("%s: HAL returns empty result metadata fmq,"
- " not use it", __func__);
- resultQueue = nullptr;
- // Don't use the queue onwards.
- }
- });
- ASSERT_TRUE(resultQueueRet.isOk());
+ std::shared_ptr<ResultMetadataQueue> resultQueue;
+ auto resultQueueRet =
+ session->getCaptureResultMetadataQueue(
+ [&resultQueue](const auto& descriptor) {
+ resultQueue = std::make_shared<ResultMetadataQueue>(
+ descriptor);
+ if (!resultQueue->isValid() ||
+ resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq,"
+ " not use it", __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+ });
+ ASSERT_TRUE(resultQueueRet.isOk());
- InFlightRequest inflightReq = {1, false, supportsPartialResults, partialResultCount,
- resultQueue};
- RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
- Return<void> ret;
- ret = session->constructDefaultRequestSettings(reqTemplate,
- [&](auto status, const auto& req) {
- ASSERT_EQ(Status::OK, status);
- settings = req;
- });
- ASSERT_TRUE(ret.isOk());
-
- sp<GraphicBuffer> gb = new GraphicBuffer(
- previewStream.width, previewStream.height,
- static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
- android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
- halStreamConfig.streams[0].consumerUsage));
- ASSERT_NE(nullptr, gb.get());
- StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
- bufferId,
- hidl_handle(gb->getNativeBuffer()->handle),
- BufferStatus::OK,
- nullptr,
- nullptr};
- ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
- const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR,
- nullptr, nullptr};
- CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
- emptyInputBuffer, outputBuffers};
-
- {
- std::unique_lock<std::mutex> l(mLock);
- mInflightMap.clear();
- mInflightMap.add(frameNumber, &inflightReq);
- }
-
- Status status = Status::INTERNAL_ERROR;
- uint32_t numRequestProcessed = 0;
- hidl_vec<BufferCache> cachesToRemove;
- ret = session->processCaptureRequest(
- {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
- status = s;
- numRequestProcessed = n;
- });
-
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(Status::OK, status);
- ASSERT_EQ(numRequestProcessed, 1u);
- // Flush before waiting for request to complete.
- Return<Status> returnStatus = session->flush();
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
-
- {
- std::unique_lock<std::mutex> l(mLock);
- while (!inflightReq.errorCodeValid &&
- ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
- auto timeout = std::chrono::system_clock::now() +
- std::chrono::seconds(kStreamBufferTimeoutSec);
- ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
- }
-
- if (!inflightReq.errorCodeValid) {
- ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
- ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
- } else {
- switch (inflightReq.errorCode) {
- case ErrorCode::ERROR_REQUEST:
- case ErrorCode::ERROR_RESULT:
- case ErrorCode::ERROR_BUFFER:
- // Expected
- break;
- case ErrorCode::ERROR_DEVICE:
- default:
- FAIL() << "Unexpected error:"
- << static_cast<uint32_t>(inflightReq.errorCode);
- }
- }
-
- ret = session->close();
+ InFlightRequest inflightReq = {1, false, supportsPartialResults,
+ partialResultCount, resultQueue};
+ RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+ Return<void> ret;
+ ret = session->constructDefaultRequestSettings(reqTemplate,
+ [&](auto status, const auto& req) {
+ ASSERT_EQ(Status::OK, status);
+ settings = req;
+ });
ASSERT_TRUE(ret.isOk());
+
+ sp<GraphicBuffer> gb = new GraphicBuffer(
+ previewStream.width, previewStream.height,
+ static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
+ android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
+ halStreamConfig.streams[0].consumerUsage));
+ ASSERT_NE(nullptr, gb.get());
+ StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+ bufferId,
+ hidl_handle(gb->getNativeBuffer()->handle),
+ BufferStatus::OK,
+ nullptr,
+ nullptr};
+ ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
+ const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+ BufferStatus::ERROR, nullptr, nullptr};
+ CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+ emptyInputBuffer, outputBuffers};
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ mInflightMap.clear();
+ mInflightMap.add(frameNumber, &inflightReq);
+ }
+
+ Status status = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ ret = session->processCaptureRequest(
+ {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
+ uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
+ // Flush before waiting for request to complete.
+ Return<Status> returnStatus = session->flush();
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, returnStatus);
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReq.errorCodeValid &&
+ ((0 < inflightReq.numBuffersLeft) ||
+ (!inflightReq.haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l,
+ timeout));
+ }
+
+ if (!inflightReq.errorCodeValid) {
+ ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+ ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
+ } else {
+ switch (inflightReq.errorCode) {
+ case ErrorCode::ERROR_REQUEST:
+ case ErrorCode::ERROR_RESULT:
+ case ErrorCode::ERROR_BUFFER:
+ // Expected
+ break;
+ case ErrorCode::ERROR_DEVICE:
+ default:
+ FAIL() << "Unexpected error:"
+ << static_cast<uint32_t>(inflightReq.errorCode);
+ }
+ }
+
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
}
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -3008,29 +3399,44 @@
static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
for (const auto& name : cameraDeviceNames) {
- if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_3_2) {
- Stream previewStream;
- HalStreamConfiguration halStreamConfig;
- sp<ICameraDeviceSession> session;
- bool supportsPartialResults = false;
- uint32_t partialResultCount = 0;
- configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
- &previewStream /*out*/, &halStreamConfig /*out*/,
- &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_2: {
+ Stream previewStream;
+ HalStreamConfiguration halStreamConfig;
+ sp<ICameraDeviceSession> session;
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ configurePreviewStream(name, mProvider, &previewThreshold, &session /*out*/,
+ &previewStream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/,
+ &partialResultCount /*out*/);
- Return<Status> returnStatus = session->flush();
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ Return<Status> returnStatus = session->flush();
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, returnStatus);
- {
- std::unique_lock<std::mutex> l(mLock);
- auto timeout = std::chrono::system_clock::now() +
- std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
- ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
+ ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ }
+
+ Return<void> ret = session->close();
+ ASSERT_TRUE(ret.isOk());
}
-
- Return<void> ret = session->close();
- ASSERT_TRUE(ret.isOk());
+ break;
+ case CAMERA_DEVICE_API_VERSION_1_0: {
+ //Not applicable
+ }
+ break;
+ default: {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ }
+ break;
}
}
}
@@ -3234,7 +3640,7 @@
ASSERT_NE(nullptr, partialResultCount);
std::vector<AvailableStream> outputPreviewStreams;
- ::android::sp<ICameraDevice> device3_2;
+ ::android::sp<ICameraDevice> device3_x;
ALOGI("configureStreams: Testing camera device %s", name.c_str());
Return<void> ret;
ret = provider->getCameraDeviceInterface_V3_x(
@@ -3244,12 +3650,12 @@
(int)status);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(device, nullptr);
- device3_2 = device;
+ device3_x = device;
});
ASSERT_TRUE(ret.isOk());
sp<DeviceCb> cb = new DeviceCb(this);
- ret = device3_2->open(
+ ret = device3_x->open(
cb,
[&](auto status, const auto& newSession) {
ALOGI("device::open returns status:%d", (int)status);
@@ -3259,8 +3665,12 @@
});
ASSERT_TRUE(ret.isOk());
+ auto castResult = device::V3_3::ICameraDeviceSession::castFrom(*session);
+ ASSERT_TRUE(castResult.isOk());
+ sp<device::V3_3::ICameraDeviceSession> session3_3 = castResult;
+
camera_metadata_t *staticMeta;
- ret = device3_2->getCameraCharacteristics([&] (Status s,
+ ret = device3_x->getCameraCharacteristics([&] (Status s,
CameraMetadata metadata) {
ASSERT_EQ(Status::OK, s);
staticMeta = clone_camera_metadata(
@@ -3292,12 +3702,24 @@
::android::hardware::hidl_vec<Stream> streams = {*previewStream};
StreamConfiguration config = {streams,
StreamConfigurationMode::NORMAL_MODE};
- ret = (*session)->configureStreams(config, [&] (Status s,
- HalStreamConfiguration halConfig) {
- ASSERT_EQ(Status::OK, s);
- ASSERT_EQ(1u, halConfig.streams.size());
- *halStreamConfig = halConfig;
- });
+ if (session3_3 == nullptr) {
+ ret = (*session)->configureStreams(config,
+ [&] (Status s, HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ *halStreamConfig = halConfig;
+ });
+ } else {
+ ret = session3_3->configureStreams_3_3(config,
+ [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ ASSERT_EQ(1u, halConfig.streams.size());
+ halStreamConfig->streams.resize(halConfig.streams.size());
+ for (size_t i = 0; i < halConfig.streams.size(); i++) {
+ halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
+ }
+ });
+ }
ASSERT_TRUE(ret.isOk());
}
@@ -3305,11 +3727,12 @@
void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
sp<ICameraProvider> provider,
sp<ICameraDeviceSession> *session /*out*/,
+ sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
camera_metadata_t **staticMeta /*out*/) {
ASSERT_NE(nullptr, session);
ASSERT_NE(nullptr, staticMeta);
- ::android::sp<ICameraDevice> device3_2;
+ ::android::sp<ICameraDevice> device3_x;
ALOGI("configureStreams: Testing camera device %s", name.c_str());
Return<void> ret;
ret = provider->getCameraDeviceInterface_V3_x(
@@ -3319,12 +3742,12 @@
(int)status);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(device, nullptr);
- device3_2 = device;
+ device3_x = device;
});
ASSERT_TRUE(ret.isOk());
sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
- ret = device3_2->open(cb, [&](auto status, const auto& newSession) {
+ ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
ALOGI("device::open returns status:%d", (int)status);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(newSession, nullptr);
@@ -3332,7 +3755,7 @@
});
ASSERT_TRUE(ret.isOk());
- ret = device3_2->getCameraCharacteristics([&] (Status s,
+ ret = device3_x->getCameraCharacteristics([&] (Status s,
CameraMetadata metadata) {
ASSERT_EQ(Status::OK, s);
*staticMeta = clone_camera_metadata(
@@ -3340,6 +3763,12 @@
ASSERT_NE(nullptr, *staticMeta);
});
ASSERT_TRUE(ret.isOk());
+
+ if(session3_3 != nullptr) {
+ auto castResult = device::V3_3::ICameraDeviceSession::castFrom(*session);
+ ASSERT_TRUE(castResult.isOk());
+ *session3_3 = castResult;
+ }
}
// Open a particular camera device.
diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..d601235
--- /dev/null
+++ b/cas/1.0/vts/functional/Android.bp
@@ -0,0 +1,23 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_test {
+ name: "VtsHalCasV1_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalCasV1_0TargetTest.cpp"],
+ static_libs: ["android.hardware.cas@1.0"],
+}
+
diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
new file mode 100644
index 0000000..f346bae
--- /dev/null
+++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 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 "mediacas_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/cas/1.0/ICas.h>
+#include <android/hardware/cas/1.0/ICasListener.h>
+#include <android/hardware/cas/1.0/IDescramblerBase.h>
+#include <android/hardware/cas/1.0/IMediaCasService.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include <cinttypes>
+#include <utility>
+
+// CA System Ids used for testing
+#define CLEAR_KEY_SYSTEM_ID 0xF6D8
+#define INVALID_SYSTEM_ID 0
+
+using android::Condition;
+using android::hardware::cas::V1_0::ICas;
+using android::hardware::cas::V1_0::ICasListener;
+using android::hardware::cas::V1_0::IDescramblerBase;
+using android::hardware::cas::V1_0::IMediaCasService;
+using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
+using android::hardware::Void;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::Mutex;
+using android::sp;
+
+namespace {
+
+class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>();
+ ASSERT_NE(mService, nullptr);
+ }
+
+ sp<IMediaCasService> mService;
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+};
+
+class MediaCasListener : public ICasListener {
+ public:
+ virtual ::android::hardware::Return<void> onEvent(
+ int32_t event, int32_t arg, const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ ALOGI("Info: received event: %d, arg: %d, size: %zu", event, arg, data.size());
+
+ return Void();
+ }
+};
+
+TEST_F(MediaCasHidlTest, EnumeratePlugins) {
+ description("Test enumerate plugins");
+ hidl_vec<HidlCasPluginDescriptor> descriptors;
+ EXPECT_TRUE(mService
+ ->enumeratePlugins([&descriptors](
+ hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
+ .isOk());
+
+ if (descriptors.size() == 0) {
+ ALOGW("[ WARN ] enumeratePlugins list empty");
+ return;
+ }
+
+ sp<MediaCasListener> casListener = new MediaCasListener();
+ for (size_t i = 0; i < descriptors.size(); i++) {
+ int32_t caSystemId = descriptors[i].caSystemId;
+ bool status = mService->isSystemIdSupported(caSystemId);
+ ASSERT_EQ(status, true);
+
+ status = mService->isDescramblerSupported(caSystemId);
+ ASSERT_EQ(status, true);
+
+ sp<ICas> mediaCas = mService->createPlugin(caSystemId, casListener);
+ ASSERT_NE(mediaCas, nullptr);
+
+ sp<IDescramblerBase> descramblerBase = mService->createDescrambler(caSystemId);
+ ASSERT_NE(descramblerBase, nullptr);
+ }
+}
+
+TEST_F(MediaCasHidlTest, TestInvalidSystemIdFails) {
+ description("Test failure for invalid system ID");
+ sp<MediaCasListener> casListener = new MediaCasListener();
+
+ ASSERT_FALSE(mService->isSystemIdSupported(INVALID_SYSTEM_ID));
+ ASSERT_FALSE(mService->isDescramblerSupported(INVALID_SYSTEM_ID));
+
+ sp<ICas> mediaCas = mService->createPlugin(INVALID_SYSTEM_ID, casListener);
+ EXPECT_EQ(mediaCas, nullptr);
+
+ sp<IDescramblerBase> descramblerBase = mService->createDescrambler(INVALID_SYSTEM_ID);
+ EXPECT_EQ(descramblerBase, nullptr);
+}
+
+TEST_F(MediaCasHidlTest, TestClearKeyPluginInstalled) {
+ description("Test if ClearKey plugin is installed");
+ hidl_vec<HidlCasPluginDescriptor> descriptors;
+ EXPECT_TRUE(mService
+ ->enumeratePlugins([&descriptors](
+ hidl_vec<HidlCasPluginDescriptor> const& _desc) { descriptors = _desc; })
+ .isOk());
+
+ if (descriptors.size() == 0) {
+ ALOGW("[ WARN ] enumeratePlugins list empty");
+ }
+
+ for (size_t i = 0; i < descriptors.size(); i++) {
+ int32_t caSystemId = descriptors[i].caSystemId;
+ if (CLEAR_KEY_SYSTEM_ID == caSystemId) {
+ return;
+ }
+ }
+
+ ASSERT_TRUE(false) << "ClearKey plugin not installed";
+}
+
+} // anonymous namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/cas/Android.bp b/cas/Android.bp
index 57532a0..8208d3d 100644
--- a/cas/Android.bp
+++ b/cas/Android.bp
@@ -1,6 +1,7 @@
// This is an autogenerated file, do not edit.
subdirs = [
"1.0",
+ "1.0/vts/functional",
"1.0/default",
"native/1.0",
]
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
index 8520757..1161444 100644
--- a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -15,6 +15,10 @@
*/
#define LOG_TAG "media_omx_hidl_audio_dec_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
@@ -171,7 +175,7 @@
{"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
{"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
{"pcm", pcm}, {"g711alaw", g711alaw}, {"g711mlaw", g711mlaw},
- {"gsm", gsm}, {"raw", raw},
+ {"gsm", gsm}, {"raw", raw}, {"flac", flac},
};
const size_t kNumStringToName =
sizeof(kStringToName) / sizeof(kStringToName[0]);
@@ -204,6 +208,7 @@
{g711mlaw, OMX_AUDIO_CodingG711},
{gsm, OMX_AUDIO_CodingGSMFR},
{raw, OMX_AUDIO_CodingPCM},
+ {flac, OMX_AUDIO_CodingFLAC},
};
static const size_t kNumCompToCoding =
sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
@@ -219,7 +224,7 @@
framesReceived = 0;
timestampUs = 0;
timestampDevTest = false;
- if (disableTest) std::cerr << "[ ] Warning ! Test Disabled\n";
+ if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -263,9 +268,8 @@
EXPECT_EQ(tsHit, true)
<< "TimeStamp not recognized";
} else {
- std::cerr
- << "[ ] Warning ! Received non-zero "
- "output / TimeStamp not recognized \n";
+ std::cout << "[ INFO ] Received non-zero "
+ "output / TimeStamp not recognized \n";
}
}
}
@@ -301,6 +305,7 @@
g711mlaw,
gsm,
raw,
+ flac,
unknown_comp,
};
@@ -431,6 +436,16 @@
*nSampleRate = param.nSampleRate;
break;
}
+ case OMX_AUDIO_CodingFLAC: {
+ OMX_AUDIO_PARAM_FLACTYPE param;
+ status = getPortParam(omxNode, OMX_IndexParamAudioFlac,
+ kPortIndexInput, ¶m);
+ ASSERT_EQ(status,
+ ::android::hardware::media::omx::V1_0::Status::OK);
+ *nChannels = param.nChannels;
+ *nSampleRate = param.nSampleRate;
+ break;
+ }
default:
ASSERT_TRUE(false);
break;
@@ -472,6 +487,9 @@
"bbb_gsm_1ch_8khz_13kbps.info"},
{AudioDecHidlTest::standardComp::raw, "bbb_raw_1ch_8khz_s32le.raw",
"bbb_raw_1ch_8khz_s32le.info"},
+ {AudioDecHidlTest::standardComp::flac,
+ "bbb_flac_stereo_680kbps_48000hz.flac",
+ "bbb_flac_stereo_680kbps_48000hz.info"},
};
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -628,39 +646,16 @@
AudioDecHidlTest::standardComp comp, bool signalEOS = true) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
-
- // dispatch output buffers
- for (size_t i = 0; i < oBuffer->size(); i++) {
- dispatchOutputBuffer(omxNode, oBuffer, i);
- }
- // dispatch input buffers
+ size_t index;
uint32_t flags = 0;
int frameID = offset;
- for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
- (frameID < (offset + range));
- i++) {
- char* ipBuffer = static_cast<char*>(
- static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
- ASSERT_LE((*Info)[frameID].bytesCount,
- static_cast<int>((*iBuffer)[i].mMemory->getSize()));
- eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
- ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
- flags = (*Info)[frameID].flags;
- if (signalEOS && ((frameID == (int)Info->size() - 1) ||
- (frameID == (offset + range - 1))))
- flags |= OMX_BUFFERFLAG_EOS;
- dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
- flags, (*Info)[frameID].timestamp);
- frameID++;
- }
-
int timeOut = TIMEOUT_COUNTER_Q;
bool iQueued, oQueued;
+
while (1) {
iQueued = oQueued = false;
status =
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
-
// Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK &&
msg.type == Message::Type::EVENT) {
@@ -673,7 +668,6 @@
if (frameID == (int)Info->size() || frameID == (offset + range)) break;
// Dispatch input buffer
- size_t index = 0;
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
char* ipBuffer = static_cast<char*>(
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
@@ -682,6 +676,11 @@
eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
flags = (*Info)[frameID].flags;
+ // Indicate to omx core that the buffer contains a full frame worth
+ // of data
+ flags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ // Indicate the omx core that this is the last buffer it needs to
+ // process
if (signalEOS && ((frameID == (int)Info->size() - 1) ||
(frameID == (offset + range - 1))))
flags |= OMX_BUFFERFLAG_EOS;
@@ -691,10 +690,12 @@
frameID++;
iQueued = true;
}
+ // Dispatch output buffer
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
oQueued = true;
}
+ // Reset Counters when either input or output buffer is dispatched
if (iQueued || oQueued)
timeOut = TIMEOUT_COUNTER_Q;
else
@@ -716,7 +717,7 @@
}
// port format enumeration
-TEST_F(AudioDecHidlTest, DISABLED_EnumeratePortFormat) {
+TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
description("Test Component on Mandatory Port Parameters (Port Format)");
if (disableTest) return;
android::hardware::media::omx::V1_0::Status status;
@@ -822,11 +823,7 @@
}
// end of sequence test
-// SPECIAL CASE; Sending Empty input EOS buffer is not supported across all
-// components. For instance soft vorbis and soft opus expects CSD buffers at
-// the start. Disabling this test for now. We shall revisit this at a later
-// stage
-TEST_F(AudioDecHidlTest, DISABLED_EOSTest_M) {
+TEST_F(AudioDecHidlTest, EOSTest_M) {
description("Test end of stream monkeying");
if (disableTest) return;
android::hardware::media::omx::V1_0::Status status;
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
index 038830d..66c4637 100644
--- a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
@@ -15,6 +15,10 @@
*/
#define LOG_TAG "media_omx_hidl_audio_enc_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
@@ -206,7 +210,7 @@
}
if (i == kNumCompToCoding) disableTest = true;
eosFlag = false;
- if (disableTest) std::cerr << "[ ] Warning ! Test Disabled\n";
+ if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -376,44 +380,25 @@
bool signalEOS = true) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
-
- // dispatch output buffers
- for (size_t i = 0; i < oBuffer->size(); i++) {
- dispatchOutputBuffer(omxNode, oBuffer, i);
- }
- // dispatch input buffers
+ size_t index;
int bytesCount = samplesPerFrame * nChannels * 2;
int32_t timestampIncr =
(int)(((float)samplesPerFrame / nSampleRate) * 1000000);
uint64_t timestamp = 0;
uint32_t flags = 0;
- for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
- char* ipBuffer = static_cast<char*>(
- static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
- ASSERT_LE(bytesCount,
- static_cast<int>((*iBuffer)[i].mMemory->getSize()));
- eleStream.read(ipBuffer, bytesCount);
- if (eleStream.gcount() != bytesCount) break;
- if (signalEOS && (nFrames == 1)) flags = OMX_BUFFERFLAG_EOS;
- dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, flags, timestamp);
- timestamp += timestampIncr;
- nFrames--;
- }
-
int timeOut = TIMEOUT_COUNTER_Q;
bool iQueued, oQueued;
+
while (1) {
iQueued = oQueued = false;
status =
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
-
if (status == android::hardware::media::omx::V1_0::Status::OK)
ASSERT_TRUE(false);
if (nFrames == 0) break;
// Dispatch input buffer
- size_t index = 0;
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
char* ipBuffer = static_cast<char*>(
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
@@ -421,7 +406,8 @@
static_cast<int>((*iBuffer)[index].mMemory->getSize()));
eleStream.read(ipBuffer, bytesCount);
if (eleStream.gcount() != bytesCount) break;
- if (signalEOS && (nFrames == 1)) flags = OMX_BUFFERFLAG_EOS;
+ flags = OMX_BUFFERFLAG_ENDOFFRAME;
+ if (signalEOS && (nFrames == 1)) flags |= OMX_BUFFERFLAG_EOS;
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, flags,
timestamp);
timestamp += timestampIncr;
@@ -433,6 +419,7 @@
dispatchOutputBuffer(omxNode, oBuffer, index);
oQueued = true;
}
+ // Reset Counters when either input or output buffer is dispatched
if (iQueued || oQueued)
timeOut = TIMEOUT_COUNTER_Q;
else
@@ -454,7 +441,7 @@
}
// port format enumeration
-TEST_F(AudioEncHidlTest, DISABLED_EnumeratePortFormat) {
+TEST_F(AudioEncHidlTest, EnumeratePortFormat) {
description("Test Component on Mandatory Port Parameters (Port Format)");
if (disableTest) return;
android::hardware::media::omx::V1_0::Status status;
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
index 4c68219..9500094 100644
--- a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
@@ -15,6 +15,10 @@
*/
#define LOG_TAG "media_omx_hidl_audio_test_common"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp
index af55e3a..cdc52fb 100644
--- a/media/omx/1.0/vts/functional/common/Android.bp
+++ b/media/omx/1.0/vts/functional/common/Android.bp
@@ -28,6 +28,7 @@
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"android.hardware.media.omx@1.0",
+ "android.hardware.graphics.allocator@2.0",
],
}
@@ -38,6 +39,8 @@
// Link to these statically as they are not guaranteed to be on the device.
static_libs: [
"VtsHalMediaOmxV1_0CommonUtil",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.common@1.0",
"android.hardware.media.omx@1.0",
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index 1ef645c..28616e2 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -15,13 +15,15 @@
*/
#define LOG_TAG "media_omx_hidl_video_test_common"
-
#ifdef __LP64__
#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
#endif
#include <android-base/logging.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -29,7 +31,10 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <cutils/atomic.h>
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
using ::android::hardware::media::omx::V1_0::IOmx;
using ::android::hardware::media::omx::V1_0::IOmxObserver;
using ::android::hardware::media::omx::V1_0::IOmxNode;
@@ -186,6 +191,73 @@
return status;
}
+void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+ BufferInfo* buffer, uint32_t nFrameWidth,
+ uint32_t nFrameHeight, int32_t* nStride,
+ int format) {
+ android::hardware::media::omx::V1_0::Status status;
+ sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
+ android::hardware::graphics::allocator::V2_0::IAllocator::getService();
+ ASSERT_NE(nullptr, allocator.get());
+
+ sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
+ android::hardware::graphics::mapper::V2_0::IMapper::getService();
+ ASSERT_NE(mapper.get(), nullptr);
+
+ android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
+ descriptorInfo;
+ uint32_t usage;
+
+ descriptorInfo.width = nFrameWidth;
+ descriptorInfo.height = nFrameHeight;
+ descriptorInfo.layerCount = 1;
+ descriptorInfo.format = static_cast<PixelFormat>(format);
+ descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
+ omxNode->getGraphicBufferUsage(
+ portIndex,
+ [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
+ uint32_t _n1) {
+ status = _s;
+ usage = _n1;
+ });
+ if (status == android::hardware::media::omx::V1_0::Status::OK) {
+ descriptorInfo.usage |= usage;
+ }
+
+ ::android::hardware::hidl_vec<uint32_t> descriptor;
+ android::hardware::graphics::mapper::V2_0::Error error;
+ mapper->createDescriptor(
+ descriptorInfo, [&error, &descriptor](
+ android::hardware::graphics::mapper::V2_0::Error _s,
+ ::android::hardware::hidl_vec<uint32_t> _n1) {
+ error = _s;
+ descriptor = _n1;
+ });
+ EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
+
+ static volatile int32_t nextId = 0;
+ uint64_t id = static_cast<uint64_t>(getpid()) << 32;
+ allocator->allocate(
+ descriptor, 1,
+ [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::hidl_handle>& _n2) {
+ ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
+ _s);
+ *nStride = _n1;
+ buffer->omxBuffer.nativeHandle = _n2[0];
+ buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
+ buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
+ buffer->omxBuffer.attr.anwBuffer.stride = _n1;
+ buffer->omxBuffer.attr.anwBuffer.format = descriptorInfo.format;
+ buffer->omxBuffer.attr.anwBuffer.usage = descriptorInfo.usage;
+ buffer->omxBuffer.attr.anwBuffer.layerCount =
+ descriptorInfo.layerCount;
+ buffer->omxBuffer.attr.anwBuffer.id =
+ id | static_cast<uint32_t>(android_atomic_inc(&nextId));
+ });
+}
+
// allocate buffers needed on a component port
void allocateBuffer(sp<IOmxNode> omxNode, BufferInfo* buffer, OMX_U32 portIndex,
OMX_U32 nBufferSize, PortMode portMode) {
@@ -243,13 +315,32 @@
buffer->id = id;
});
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ } else if (portMode == PortMode::PRESET_ANW_BUFFER) {
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+ &portDef);
+ int32_t nStride;
+ buffer->owner = client;
+ buffer->omxBuffer.type = CodecBuffer::Type::ANW_BUFFER;
+ allocateGraphicBuffers(omxNode, portIndex, buffer,
+ portDef.format.video.nFrameWidth,
+ portDef.format.video.nFrameHeight, &nStride,
+ portDef.format.video.eColorFormat);
+ omxNode->useBuffer(
+ portIndex, buffer->omxBuffer,
+ [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
+ uint32_t id) {
+ status = _s;
+ buffer->id = id;
+ });
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
}
}
// allocate buffers needed on a component port
void allocatePortBuffers(sp<IOmxNode> omxNode,
android::Vector<BufferInfo>* buffArray,
- OMX_U32 portIndex, PortMode portMode) {
+ OMX_U32 portIndex, PortMode portMode, bool allocGrap) {
android::hardware::media::omx::V1_0::Status status;
OMX_PARAM_PORTDEFINITIONTYPE portDef;
@@ -263,6 +354,13 @@
BufferInfo buffer;
allocateBuffer(omxNode, &buffer, portIndex, portDef.nBufferSize,
portMode);
+ if (allocGrap && portMode == PortMode::DYNAMIC_ANW_BUFFER) {
+ int32_t nStride;
+ allocateGraphicBuffers(omxNode, portIndex, &buffer,
+ portDef.format.video.nFrameWidth,
+ portDef.format.video.nFrameHeight, &nStride,
+ portDef.format.video.eColorFormat);
+ }
buffArray->push(buffer);
}
}
@@ -274,7 +372,7 @@
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer,
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
- PortMode* portMode) {
+ PortMode* portMode, bool allocGrap) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
PortMode defaultPortMode[2], *pm;
@@ -293,14 +391,14 @@
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
// allocate buffers on input port
- allocatePortBuffers(omxNode, iBuffer, kPortIndexInput, pm[0]);
+ allocatePortBuffers(omxNode, iBuffer, kPortIndexInput, pm[0], allocGrap);
// Dont switch states until the ports are populated
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
// allocate buffers on output port
- allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput, pm[1]);
+ allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput, pm[1], allocGrap);
// As the ports are populated, check if the state transition is complete
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
@@ -440,6 +538,7 @@
status =
omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
break;
+ case PortMode::PRESET_ANW_BUFFER:
case PortMode::PRESET_SECURE_BUFFER:
case PortMode::PRESET_BYTE_BUFFER:
t.sharedMemory = android::hardware::hidl_memory();
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index 71012b3..de043b2 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -126,8 +126,8 @@
android::Vector<BufferInfo>* iBuffers = nullptr,
android::Vector<BufferInfo>* oBuffers = nullptr) {
int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
- android::Mutex::Autolock autoLock(msgLock);
for (;;) {
+ android::Mutex::Autolock autoLock(msgLock);
android::List<Message>::iterator it = msgQueue.begin();
while (it != msgQueue.end()) {
if (it->type ==
@@ -303,13 +303,15 @@
void allocatePortBuffers(sp<IOmxNode> omxNode,
android::Vector<BufferInfo>* buffArray,
OMX_U32 portIndex,
- PortMode portMode = PortMode::PRESET_BYTE_BUFFER);
+ PortMode portMode = PortMode::PRESET_BYTE_BUFFER,
+ bool allocGrap = false);
void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer,
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
- PortMode* portMode = nullptr);
+ PortMode* portMode = nullptr,
+ bool allocGrap = false);
void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
index 2ec86b2..5d0ac35 100644
--- a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
+++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
@@ -15,6 +15,10 @@
*/
#define LOG_TAG "media_omx_hidl_component_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
@@ -181,7 +185,7 @@
strlen(gEnv->getComponent().c_str()) - suffixLen,
".secure");
}
- if (disableTest) std::cerr << "[ ] Warning ! Test Disabled\n";
+ if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -290,7 +294,7 @@
}
// port format enumeration
-TEST_F(ComponentHidlTest, DISABLED_EnumeratePortFormat) {
+TEST_F(ComponentHidlTest, EnumeratePortFormat) {
description("Test Component on Mandatory Port Parameters (Port Format)");
if (disableTest) return;
android::hardware::media::omx::V1_0::Status status;
@@ -397,14 +401,44 @@
EXPECT_NE(status,
::android::hardware::media::omx::V1_0::Status::OK);
- // Edit Read-Only fields.
+ // Port Direction - Read Only
portDef = mirror;
portDef.eDir = static_cast<OMX_DIRTYPE>(RANDOM_INDEX);
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
- EXPECT_EQ(portDef.eDir, mirror.eDir);
+ if (portDef.eDir != mirror.eDir) {
+ std::cerr << "[ ERROR ] port direction has to be read only "
+ "but is changeable \n";
+ }
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
+ // Port Min BufferCount - Read Only
+ portDef = mirror;
+ portDef.nBufferCountMin += 1;
+ setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
+ getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
+ if (portDef.nBufferCountMin != mirror.nBufferCountMin) {
+ std::cerr << "[ ERROR ] port Min BufferCount has to be "
+ "read only but is changeable \n";
+ }
+ EXPECT_EQ(portDef.nBufferCountMin, mirror.nBufferCountMin);
+ setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
+
+ // Port Actual BufferCount
+ portDef = mirror;
+ portDef.nBufferCountActual += 1;
+ status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
+ &portDef);
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i,
+ &portDef);
+ EXPECT_EQ(portDef.nBufferCountActual,
+ mirror.nBufferCountActual + 1);
+ }
+
+ // Port BufferSize is although read only as per OMX-IL 1.2, android
+ // doesnt abide by this.
+ // Decrease buffer size
portDef = mirror;
OMX_U32 nBufferSize = portDef.nBufferSize >> 1;
if (nBufferSize != 0) {
@@ -428,43 +462,21 @@
(compClass == video_decoder && i == kPortIndexInput)) {
double dev = (portDef.nBufferSize / (double)nBufferSize);
dev -= 1;
- if (dev < 0 || dev > 0.1) EXPECT_TRUE(false);
+ if (dev < 0 || dev > 0.1) {
+ std::cerr << "[ ERROR ] port buffer size deviation "
+ "larger than expected \n";
+ }
} else {
EXPECT_EQ(portDef.nBufferSize, mirror.nBufferSize);
}
setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
- portDef = mirror;
- portDef.nBufferCountMin += 1;
- setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
- getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
- EXPECT_EQ(portDef.nBufferCountMin, mirror.nBufferCountMin);
- setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror);
-
- portDef = mirror;
- portDef.nBufferCountActual += 1;
- status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
- &portDef);
- if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
- status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i,
- &portDef);
- EXPECT_EQ(portDef.nBufferCountActual,
- mirror.nBufferCountActual + 1);
- }
-
+ // Increase buffer size
portDef = mirror;
portDef.nBufferSize = mirror.nBufferSize << 1;
- status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i,
- &portDef);
- if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
- status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i,
- &portDef);
- if (portDef.nBufferSize != mirror.nBufferSize) {
- std::cout
- << "[ ] Warning ! Component input port does "
- "not preserve Read-Only fields \n";
- }
- }
+ setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
+ getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef);
+ EXPECT_EQ(portDef.nBufferSize, (mirror.nBufferSize << 1));
}
}
}
@@ -583,6 +595,109 @@
kPortIndexInput, kPortIndexOutput);
}
+// Flush test - monkeying
+TEST_F(ComponentHidlTest, Flush_M) {
+ description("Test Flush monkeying");
+ if (disableTest) return;
+ android::hardware::media::omx::V1_0::Status status;
+ uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+ Message msg;
+
+ status = setRole(omxNode, gEnv->getRole().c_str());
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ OMX_PORT_PARAM_TYPE params;
+ if (compClass == audio_decoder || compClass == audio_encoder) {
+ status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
+ } else {
+ status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
+ }
+ if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(params.nPorts, 2U);
+ kPortIndexInput = params.nStartPortNumber;
+ kPortIndexOutput = kPortIndexInput + 1;
+ }
+
+ android::Vector<BufferInfo> iBuffer, oBuffer;
+
+ // set port mode
+ PortMode portMode[2];
+ initPortMode(portMode, isSecure, compClass);
+ status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+ EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+ // // Flush all ports ; receive error OMX_ErrorIncorrectStateOperation
+ // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ // OMX_ALL);
+ // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to idle
+ changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
+ kPortIndexInput, kPortIndexOutput, portMode);
+
+ // // Flush all ports ; receive error OMX_ErrorIncorrectStateOperation
+ // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ // OMX_ALL);
+ // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // set state to executing
+ changeStateIdletoExecute(omxNode, observer);
+ // dispatch buffers
+ for (size_t i = 0; i < oBuffer.size(); i++) {
+ dispatchOutputBuffer(omxNode, &oBuffer, i, portMode[1]);
+ }
+
+ // // flush invalid port, expecting OMX_ErrorBadPortIndex
+ // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+ // RANDOM_INDEX);
+ // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // Flush all ports
+ status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush), OMX_ALL);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ for (int j = 0; j < 2; j++) {
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_PE, &iBuffer,
+ &oBuffer);
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+ if (msg.data.eventData.data2 == kPortIndexInput) {
+ // test if client got all its buffers back
+ for (size_t i = 0; i < iBuffer.size(); ++i) {
+ EXPECT_EQ(iBuffer[i].owner, client);
+ }
+ } else if (msg.data.eventData.data2 == kPortIndexOutput) {
+ // test if client got all its buffers back
+ for (size_t i = 0; i < oBuffer.size(); ++i) {
+ EXPECT_EQ(oBuffer[i].owner, client);
+ }
+ } else {
+ EXPECT_TRUE(false) << "Bad port Index";
+ }
+ }
+
+ // SPECIAL CASE: When OMX_ALL is used as argument, Android OMX Core sends
+ // an additional flush event with argument OMX_ALL. This we believe is
+ // not recognized by OMX-IL Spec. So read this event and ignore it
+ status =
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_PE, &iBuffer, &oBuffer);
+ if (status == android::hardware::media::omx::V1_0::Status::OK) {
+ ASSERT_EQ(msg.type, Message::Type::EVENT);
+ ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+ ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+ ASSERT_EQ(msg.data.eventData.data2, OMX_ALL);
+ }
+
+ // set state to idle
+ changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
+ // set state to loaded
+ changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
+ kPortIndexInput, kPortIndexOutput);
+}
+
// test port mode configuration when the component is in various states
TEST_F(ComponentHidlTest, PortModeConfig) {
description("Test Port Mode Configuration");
diff --git a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
index e8f5f77..7cffea8 100644
--- a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
+++ b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
@@ -15,6 +15,10 @@
*/
#define LOG_TAG "media_omx_hidl_master_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
diff --git a/media/omx/1.0/vts/functional/video/Android.bp b/media/omx/1.0/vts/functional/video/Android.bp
index e251a15..f0da2b3 100644
--- a/media/omx/1.0/vts/functional/video/Android.bp
+++ b/media/omx/1.0/vts/functional/video/Android.bp
@@ -21,10 +21,6 @@
"VtsHalMediaOmxV1_0TargetVideoDecTest.cpp",
"media_video_hidl_test_common.cpp"
],
- static_libs: [
- "android.hardware.graphics.allocator@2.0",
- "android.hardware.graphics.mapper@2.0",
- ],
}
cc_test {
@@ -36,6 +32,5 @@
],
static_libs: [
"libnativewindow",
- "android.hardware.graphics.mapper@2.0",
],
}
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index fb02cd4..a2547e8 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -15,11 +15,12 @@
*/
#define LOG_TAG "media_omx_hidl_video_dec_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
#include <android-base/logging.h>
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -27,10 +28,7 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
-#include <cutils/atomic.h>
-using ::android::hardware::graphics::common::V1_0::BufferUsage;
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
using ::android::hardware::media::omx::V1_0::IOmx;
using ::android::hardware::media::omx::V1_0::IOmxObserver;
using ::android::hardware::media::omx::V1_0::IOmxNode;
@@ -228,7 +226,7 @@
".secure");
}
if (isSecure) disableTest = true;
- if (disableTest) std::cout << "[ ] Warning ! Test Disabled\n";
+ if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -272,9 +270,8 @@
EXPECT_EQ(tsHit, true)
<< "TimeStamp not recognized";
} else {
- std::cout
- << "[ ] Warning ! Received non-zero "
- "output / TimeStamp not recognized \n";
+ std::cout << "[ INFO ] Received non-zero "
+ "output / TimeStamp not recognized \n";
}
}
}
@@ -433,82 +430,6 @@
}
}
-void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
- android::Vector<BufferInfo>* buffArray,
- uint32_t nFrameWidth, uint32_t nFrameHeight,
- int32_t* nStride, int format, uint32_t count) {
- android::hardware::media::omx::V1_0::Status status;
- sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
- android::hardware::graphics::allocator::V2_0::IAllocator::getService();
- ASSERT_NE(nullptr, allocator.get());
-
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- ASSERT_NE(mapper.get(), nullptr);
-
- android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
- descriptorInfo;
- uint32_t usage;
-
- descriptorInfo.width = nFrameWidth;
- descriptorInfo.height = nFrameHeight;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format = static_cast<PixelFormat>(format);
- descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
- omxNode->getGraphicBufferUsage(
- portIndex,
- [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
- uint32_t _n1) {
- status = _s;
- usage = _n1;
- });
- if (status == android::hardware::media::omx::V1_0::Status::OK) {
- descriptorInfo.usage |= usage;
- }
-
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- android::hardware::graphics::mapper::V2_0::Error error;
- mapper->createDescriptor(
- descriptorInfo, [&error, &descriptor](
- android::hardware::graphics::mapper::V2_0::Error _s,
- ::android::hardware::hidl_vec<uint32_t> _n1) {
- error = _s;
- descriptor = _n1;
- });
- EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
-
- EXPECT_EQ(buffArray->size(), count);
-
- static volatile int32_t nextId = 0;
- uint64_t id = static_cast<uint64_t>(getpid()) << 32;
- allocator->allocate(
- descriptor, count,
- [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
- const ::android::hardware::hidl_vec<
- ::android::hardware::hidl_handle>& _n2) {
- ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
- _s);
- *nStride = _n1;
- ASSERT_EQ(count, _n2.size());
- for (uint32_t i = 0; i < count; i++) {
- buffArray->editItemAt(i).omxBuffer.nativeHandle = _n2[i];
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.width =
- nFrameWidth;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.height =
- nFrameHeight;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.stride = _n1;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.format =
- descriptorInfo.format;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.usage =
- descriptorInfo.usage;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.layerCount =
- descriptorInfo.layerCount;
- buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.id =
- id | static_cast<uint32_t>(android_atomic_inc(&nextId));
- }
- });
-}
-
// port settings reconfiguration during runtime. reconfigures frame dimensions
void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
@@ -592,22 +513,7 @@
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput,
- oPortMode);
- if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
- OMX_PARAM_PORTDEFINITIONTYPE portDef;
-
- status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
- kPortIndexOutput, &portDef);
- ASSERT_EQ(
- status,
- ::android::hardware::media::omx::V1_0::Status::OK);
- allocateGraphicBuffers(omxNode, kPortIndexOutput, oBuffer,
- portDef.format.video.nFrameWidth,
- portDef.format.video.nFrameHeight,
- &portDef.format.video.nStride,
- portDef.format.video.eColorFormat,
- portDef.nBufferCountActual);
- }
+ oPortMode, true);
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
iBuffer, oBuffer);
ASSERT_EQ(status,
@@ -635,14 +541,14 @@
}
} else if (msg.data.eventData.data2 ==
OMX_IndexConfigCommonOutputCrop) {
- std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
+ std::cout << "[ INFO ] OMX_EventPortSettingsChanged/ "
"OMX_IndexConfigCommonOutputCrop not handled \n";
} else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
- std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
+ std::cout << "[ INFO ] OMX_EventPortSettingsChanged/ "
"kDescribeColorAspectsIndex not handled \n";
}
} else if (msg.data.eventData.event == OMX_EventError) {
- std::cout << "[ ] Warning ! OMX_EventError/ "
+ std::cerr << "[ ERROR ] OMX_EventError/ "
"Decode Frame Call might be failed \n";
return;
} else {
@@ -698,39 +604,16 @@
bool signalEOS = true) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
-
- // dispatch output buffers
- for (size_t i = 0; i < oBuffer->size(); i++) {
- dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
- }
- // dispatch input buffers
+ size_t index;
uint32_t flags = 0;
int frameID = offset;
- for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
- (frameID < (offset + range));
- i++) {
- char* ipBuffer = static_cast<char*>(
- static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
- ASSERT_LE((*Info)[frameID].bytesCount,
- static_cast<int>((*iBuffer)[i].mMemory->getSize()));
- eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
- ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
- flags = (*Info)[frameID].flags;
- if (signalEOS && ((frameID == (int)Info->size() - 1) ||
- (frameID == (offset + range - 1))))
- flags |= OMX_BUFFERFLAG_EOS;
- dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
- flags, (*Info)[frameID].timestamp);
- frameID++;
- }
-
int timeOut = TIMEOUT_COUNTER_Q;
bool iQueued, oQueued;
+
while (1) {
iQueued = oQueued = false;
status =
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
-
// Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK &&
msg.type == Message::Type::EVENT) {
@@ -742,7 +625,6 @@
if (frameID == (int)Info->size() || frameID == (offset + range)) break;
// Dispatch input buffer
- size_t index = 0;
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
char* ipBuffer = static_cast<char*>(
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
@@ -751,6 +633,11 @@
eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
flags = (*Info)[frameID].flags;
+ // Indicate to omx core that the buffer contains a full frame worth
+ // of data
+ flags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ // Indicate the omx core that this is the last buffer it needs to
+ // process
if (signalEOS && ((frameID == (int)Info->size() - 1) ||
(frameID == (offset + range - 1))))
flags |= OMX_BUFFERFLAG_EOS;
@@ -760,10 +647,12 @@
frameID++;
iQueued = true;
}
+ // Dispatch output buffer
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
oQueued = true;
}
+ // Reset Counters when either input or output buffer is dispatched
if (iQueued || oQueued)
timeOut = TIMEOUT_COUNTER_Q;
else
@@ -1000,23 +889,10 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
- if (portMode[1] != PortMode::PRESET_BYTE_BUFFER) {
- OMX_PARAM_PORTDEFINITIONTYPE portDef;
-
- status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
- kPortIndexOutput, &portDef);
- ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
- allocateGraphicBuffers(
- omxNode, kPortIndexOutput, &oBuffer,
- portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
- &portDef.format.video.nStride, portDef.format.video.eColorFormat,
- portDef.nBufferCountActual);
- }
-
// Port Reconfiguration
eleStream.open(mURL, std::ifstream::binary);
ASSERT_EQ(eleStream.is_open(), true);
@@ -1056,10 +932,16 @@
}
// set port mode
+ portMode[0] = PortMode::PRESET_BYTE_BUFFER;
+ portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
- ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
+ portMode[1] = PortMode::PRESET_BYTE_BUFFER;
+ status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ }
// prepare for adaptive playback
uint32_t adaptiveMaxWidth = 320;
@@ -1071,7 +953,10 @@
// support for adaptive play back is mandatory in Byte Buffer mode
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
} else {
- return;
+ // for vendor codecs, support for adaptive play back is optional
+ // in byte buffer mode.
+ if (portMode[1] == PortMode::PRESET_BYTE_BUFFER) return;
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
}
// TODO: Handle this better !!!
@@ -1101,7 +986,7 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
@@ -1211,7 +1096,7 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
@@ -1299,7 +1184,7 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
@@ -1387,10 +1272,16 @@
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
// set port mode
+ portMode[0] = PortMode::PRESET_BYTE_BUFFER;
+ portMode[1] = PortMode::PRESET_ANW_BUFFER;
status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
- ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
+ portMode[1] = PortMode::PRESET_BYTE_BUFFER;
+ status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+ ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+ }
// set Port Params
uint32_t nFrameWidth, nFrameHeight, xFramerate;
@@ -1412,7 +1303,7 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
@@ -1507,7 +1398,7 @@
// set state to idle
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
- kPortIndexInput, kPortIndexOutput, portMode);
+ kPortIndexInput, kPortIndexOutput, portMode, true);
// set state to executing
changeStateIdletoExecute(omxNode, observer);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index 23f051d..df90ccc 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -237,7 +237,7 @@
".secure");
}
if (isSecure) disableTest = true;
- if (disableTest) std::cerr << "[ ] Warning ! Test Disabled\n";
+ if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -278,9 +278,8 @@
EXPECT_EQ(tsHit, true)
<< "TimeStamp not recognized";
} else {
- std::cerr
- << "[ ] Warning ! Received non-zero "
- "output / TimeStamp not recognized \n";
+ std::cout << "[ INFO ] Received non-zero "
+ "output / TimeStamp not recognized \n";
}
}
}
@@ -442,7 +441,7 @@
status = setPortConfig(omxNode, OMX_IndexConfigVideoIntraVOPRefresh,
portIndex, ¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to request IDR \n";
+ std::cout << "[ INFO ] unable to request IDR \n";
}
// modify bitrate
@@ -453,7 +452,7 @@
status =
setPortConfig(omxNode, OMX_IndexConfigVideoBitrate, portIndex, ¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to change Bitrate \n";
+ std::cout << "[ INFO ] unable to change Bitrate \n";
}
// modify framerate
@@ -465,7 +464,7 @@
status = setPortConfig(omxNode, OMX_IndexConfigVideoFramerate, portIndex,
¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to change Framerate \n";
+ std::cout << "[ INFO ] unable to change Framerate \n";
return status;
}
@@ -479,7 +478,7 @@
(OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
portIndex, ¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to change Refresh Period\n";
+ std::cout << "[ INFO ] unable to change Refresh Period\n";
}
// set intra refresh interval
@@ -505,7 +504,7 @@
status = setPortParam(omxNode, OMX_IndexParamVideoIntraRefresh, portIndex,
¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to set Refresh Period \n";
+ std::cout << "[ INFO ] unable to set Refresh Period \n";
}
void setLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t latency) {
@@ -515,7 +514,7 @@
status = setPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
portIndex, ¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to set latency\n";
+ std::cout << "[ INFO ] unable to set latency\n";
}
void getLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t* latency) {
@@ -524,7 +523,7 @@
status = getPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
portIndex, ¶m);
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr << "[ ] Warning ! unable to get latency\n";
+ std::cout << "[ INFO ] unable to get latency\n";
else
*latency = param.nU32;
}
@@ -983,58 +982,25 @@
sp<CodecProducerListener> listener = nullptr) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
- uint32_t ipCount = 0;
+ uint64_t timestamp = 0;
+ uint32_t flags = 0;
+ int timeOut = TIMEOUT_COUNTER_Q;
+ bool iQueued, oQueued;
+ uint32_t ipCount = 0;
if (ipCount == 0) {
status = changeFrameRate(omxNode, portIndexOutput, (24U << 16));
if (status == ::android::hardware::media::omx::V1_0::Status::OK)
xFramerate = (24U << 16);
}
-
- // dispatch output buffers
- for (size_t i = 0; i < oBuffer->size(); i++) {
- dispatchOutputBuffer(omxNode, oBuffer, i);
- }
- // dispatch input buffers
int32_t timestampIncr = (int)((float)1000000 / (xFramerate >> 16));
- // timestamp scale = Nano sec
- if (inputDataIsMeta) timestampIncr *= 1000;
- uint64_t timestamp = 0;
- uint32_t flags = 0;
- for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
- if (inputDataIsMeta) {
- if (listener->freeBuffers > listener->minUnDequeuedCount) {
- if (dispatchGraphicBuffer(omxNode, producer, listener, iBuffer,
- portIndexInput, eleStream, timestamp))
- break;
- timestamp += timestampIncr;
- nFrames--;
- ipCount++;
- }
- } else {
- char* ipBuffer = static_cast<char*>(
- static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
- ASSERT_LE(bytesCount,
- static_cast<int>((*iBuffer)[i].mMemory->getSize()));
- if (fillByteBuffer(omxNode, ipBuffer, portIndexInput, eleStream))
- break;
- if (signalEOS && (nFrames == 1)) flags = OMX_BUFFERFLAG_EOS;
- dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, flags,
- timestamp);
- if (timestampUslist) timestampUslist->push_back(timestamp);
- timestamp += timestampIncr;
- nFrames--;
- ipCount++;
- }
- }
+ if (inputDataIsMeta) timestampIncr *= 1000; // timestamp scale: Nano sec
- int timeOut = TIMEOUT_COUNTER_Q;
- bool iQueued, oQueued;
while (1) {
iQueued = oQueued = false;
status =
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
-
+ // Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK) {
ASSERT_EQ(msg.type, Message::Type::EVENT);
if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
@@ -1046,7 +1012,7 @@
break;
} else if (msg.data.eventData.event == OMX_EventDataSpaceChanged) {
// TODO: how am i supposed to respond now?
- std::cout << "[ ] Info ! OMX_EventDataSpaceChanged \n";
+ std::cout << "[ INFO ] OMX_EventDataSpaceChanged \n";
} else {
ASSERT_TRUE(false);
}
@@ -1076,7 +1042,8 @@
if (fillByteBuffer(omxNode, ipBuffer, portIndexInput,
eleStream))
break;
- if (signalEOS && (nFrames == 1)) flags = OMX_BUFFERFLAG_EOS;
+ flags = OMX_BUFFERFLAG_ENDOFFRAME;
+ if (signalEOS && (nFrames == 1)) flags |= OMX_BUFFERFLAG_EOS;
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, flags,
timestamp);
if (timestampUslist) timestampUslist->push_back(timestamp);
@@ -1086,10 +1053,12 @@
iQueued = true;
}
}
+ // Dispatch output buffer
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
oQueued = true;
}
+ // Reset Counters when either input or output buffer is dispatched
if (iQueued || oQueued)
timeOut = TIMEOUT_COUNTER_Q;
else
@@ -1098,6 +1067,7 @@
EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
break;
}
+ // Runtime Param Configuration
if (ipCount == 15) {
changeBitrate(omxNode, portIndexOutput, 768000);
requestIDR(omxNode, portIndexOutput);
@@ -1266,8 +1236,7 @@
status = setParam(omxNode, static_cast<OMX_INDEXTYPE>(index), ¶m);
}
if (status != ::android::hardware::media::omx::V1_0::Status::OK)
- std::cerr
- << "[ ] Warning ! unable to prependSPSPPSToIDRFrames\n";
+ std::cout << "[ INFO ] unable to prependSPSPPSToIDRFrames\n";
else
prependSPSPPS = true;
diff --git a/media/omx/1.0/vts/functional/video/media_video_hidl_test_common.cpp b/media/omx/1.0/vts/functional/video/media_video_hidl_test_common.cpp
index 91aecf2..e1b6022 100644
--- a/media/omx/1.0/vts/functional/video/media_video_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/video/media_video_hidl_test_common.cpp
@@ -15,7 +15,6 @@
*/
#define LOG_TAG "media_omx_hidl_video_test_common"
-
#ifdef __LP64__
#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
#endif
diff --git a/media/res/bbb_flac_stereo_680kbps_48000hz.flac b/media/res/bbb_flac_stereo_680kbps_48000hz.flac
new file mode 100644
index 0000000..db94d8e
--- /dev/null
+++ b/media/res/bbb_flac_stereo_680kbps_48000hz.flac
Binary files differ
diff --git a/media/res/bbb_flac_stereo_680kbps_48000hz.info b/media/res/bbb_flac_stereo_680kbps_48000hz.info
new file mode 100644
index 0000000..c572430
--- /dev/null
+++ b/media/res/bbb_flac_stereo_680kbps_48000hz.info
@@ -0,0 +1,415 @@
+42 128 0
+1386 32 0
+2401 32 24000
+2321 32 48000
+2367 32 72000
+2370 32 96000
+2334 32 120000
+2396 32 144000
+2375 32 168000
+2431 32 192000
+2428 32 216000
+2334 32 240000
+2261 32 264000
+2124 32 288000
+2152 32 312000
+2295 32 336000
+2183 32 360000
+2393 32 384000
+2400 32 408000
+2246 32 432000
+2289 32 456000
+2400 32 480000
+2335 32 504000
+2294 32 528000
+2260 32 552000
+2206 32 576000
+2185 32 600000
+2155 32 624000
+2118 32 648000
+2094 32 672000
+2050 32 696000
+2059 32 720000
+2030 32 744000
+2022 32 768000
+2078 32 792000
+2082 32 816000
+2094 32 840000
+2111 32 864000
+2043 32 888000
+2023 32 912000
+2024 32 936000
+2056 32 960000
+2108 32 984000
+2138 32 1008000
+2140 32 1032000
+2111 32 1056000
+2110 32 1080000
+2137 32 1104000
+2157 32 1128000
+2174 32 1152000
+2200 32 1176000
+2203 32 1200000
+2237 32 1224000
+2261 32 1248000
+2215 32 1272000
+2133 32 1296000
+2091 32 1320000
+2088 32 1344000
+2122 32 1368000
+2139 32 1392000
+2146 32 1416000
+2231 32 1440000
+2282 32 1464000
+2273 32 1488000
+2304 32 1512000
+2292 32 1536000
+2255 32 1560000
+2181 32 1584000
+2081 32 1608000
+2012 32 1632000
+2011 32 1656000
+2066 32 1680000
+2069 32 1704000
+2120 32 1728000
+2141 32 1752000
+2148 32 1776000
+2181 32 1800000
+2176 32 1824000
+2240 32 1848000
+2297 32 1872000
+2325 32 1896000
+2336 32 1920000
+2329 32 1944000
+2299 32 1968000
+2322 32 1992000
+2347 32 2016000
+2287 32 2040000
+2286 32 2064000
+2269 32 2088000
+2320 32 2112000
+2305 32 2136000
+2384 32 2160000
+2429 32 2184000
+2370 32 2208000
+2365 32 2232000
+2361 32 2256000
+2370 32 2280000
+2393 32 2304000
+2342 32 2328000
+2325 32 2352000
+2334 32 2376000
+2316 32 2400000
+2317 32 2424000
+2305 32 2448000
+2360 32 2472000
+2331 32 2496000
+2332 32 2520000
+2361 32 2544000
+2417 32 2568000
+2438 32 2592000
+2403 32 2616000
+2386 32 2640000
+2382 32 2664000
+2350 32 2688000
+2355 32 2712000
+2383 32 2736000
+2384 32 2760000
+2383 32 2784000
+2373 32 2808000
+2374 32 2832000
+2347 32 2856000
+2353 32 2880000
+2381 32 2904000
+2401 32 2928000
+2401 32 2952000
+2385 32 2976000
+2382 32 3000000
+2328 32 3024000
+2303 32 3048000
+2272 32 3072000
+2270 32 3096000
+2312 32 3120000
+2273 32 3144000
+2330 32 3168000
+2339 32 3192000
+2296 32 3216000
+2317 32 3240000
+2440 32 3264000
+2353 32 3288000
+2346 32 3312000
+2303 32 3336000
+2308 32 3360000
+2287 32 3384000
+2316 32 3408000
+2367 32 3432000
+2335 32 3456000
+2350 32 3480000
+2395 32 3504000
+2408 32 3528000
+2413 32 3552000
+2415 32 3576000
+2468 32 3600000
+2437 32 3624000
+2372 32 3648000
+2371 32 3672000
+2341 32 3696000
+2328 32 3720000
+2273 32 3744000
+2244 32 3768000
+2233 32 3792000
+2229 32 3816000
+2252 32 3840000
+2236 32 3864000
+2217 32 3888000
+2179 32 3912000
+2251 32 3936000
+2192 32 3960000
+2199 32 3984000
+2212 32 4008000
+2190 32 4032000
+2102 32 4056000
+2120 32 4080000
+2167 32 4104000
+2024 32 4128000
+2010 32 4152000
+2067 32 4176000
+2035 32 4200000
+2051 32 4224000
+2012 32 4248000
+2066 32 4272000
+2025 32 4296000
+1987 32 4320000
+1972 32 4344000
+1966 32 4368000
+1999 32 4392000
+1987 32 4416000
+1922 32 4440000
+2020 32 4464000
+2072 32 4488000
+2021 32 4512000
+2017 32 4536000
+2099 32 4560000
+2064 32 4584000
+2109 32 4608000
+2093 32 4632000
+2090 32 4656000
+2148 32 4680000
+2184 32 4704000
+2179 32 4728000
+2152 32 4752000
+2143 32 4776000
+2159 32 4800000
+2123 32 4824000
+2129 32 4848000
+2147 32 4872000
+2192 32 4896000
+2051 32 4920000
+2116 32 4944000
+2124 32 4968000
+2088 32 4992000
+2073 32 5016000
+2146 32 5040000
+2133 32 5064000
+2073 32 5088000
+2059 32 5112000
+2044 32 5136000
+2012 32 5160000
+2034 32 5184000
+2053 32 5208000
+2013 32 5232000
+1981 32 5256000
+2094 32 5280000
+2076 32 5304000
+1968 32 5328000
+2028 32 5352000
+2031 32 5376000
+2020 32 5400000
+2019 32 5424000
+2030 32 5448000
+2015 32 5472000
+1962 32 5496000
+2070 32 5520000
+2087 32 5544000
+1964 32 5568000
+2069 32 5592000
+2034 32 5616000
+1994 32 5640000
+1985 32 5664000
+2030 32 5688000
+2066 32 5712000
+1954 32 5736000
+1733 32 5760000
+1649 32 5784000
+1652 32 5808000
+1631 32 5832000
+1656 32 5856000
+1672 32 5880000
+1667 32 5904000
+1696 32 5928000
+1672 32 5952000
+1701 32 5976000
+1651 32 6000000
+1674 32 6024000
+1695 32 6048000
+1702 32 6072000
+1707 32 6096000
+1694 32 6120000
+1727 32 6144000
+1730 32 6168000
+1708 32 6192000
+1704 32 6216000
+1735 32 6240000
+1758 32 6264000
+1753 32 6288000
+1748 32 6312000
+1763 32 6336000
+1737 32 6360000
+1783 32 6384000
+1839 32 6408000
+1861 32 6432000
+1832 32 6456000
+1947 32 6480000
+1939 32 6504000
+1926 32 6528000
+1896 32 6552000
+1909 32 6576000
+1869 32 6600000
+1900 32 6624000
+1896 32 6648000
+1883 32 6672000
+1903 32 6696000
+1895 32 6720000
+1865 32 6744000
+1878 32 6768000
+1881 32 6792000
+1861 32 6816000
+1791 32 6840000
+1787 32 6864000
+1798 32 6888000
+1811 32 6912000
+1824 32 6936000
+1895 32 6960000
+2079 32 6984000
+2034 32 7008000
+2038 32 7032000
+2018 32 7056000
+2030 32 7080000
+2067 32 7104000
+1982 32 7128000
+1911 32 7152000
+1904 32 7176000
+1874 32 7200000
+1876 32 7224000
+1944 32 7248000
+1977 32 7272000
+1977 32 7296000
+1979 32 7320000
+2012 32 7344000
+1961 32 7368000
+1773 32 7392000
+1780 32 7416000
+1801 32 7440000
+1892 32 7464000
+1869 32 7488000
+1936 32 7512000
+2154 32 7536000
+2226 32 7560000
+2159 32 7584000
+2253 32 7608000
+2286 32 7632000
+2214 32 7656000
+2111 32 7680000
+2027 32 7704000
+1994 32 7728000
+1882 32 7752000
+1887 32 7776000
+1993 32 7800000
+1962 32 7824000
+1982 32 7848000
+1966 32 7872000
+1962 32 7896000
+1928 32 7920000
+1878 32 7944000
+1857 32 7968000
+1885 32 7992000
+1919 32 8016000
+1904 32 8040000
+1909 32 8064000
+1909 32 8088000
+1933 32 8112000
+1824 32 8136000
+1756 32 8160000
+1733 32 8184000
+1705 32 8208000
+1755 32 8232000
+1756 32 8256000
+1725 32 8280000
+1761 32 8304000
+1736 32 8328000
+1706 32 8352000
+1662 32 8376000
+1604 32 8400000
+1613 32 8424000
+1692 32 8448000
+1736 32 8472000
+1779 32 8496000
+1768 32 8520000
+1758 32 8544000
+1708 32 8568000
+1642 32 8592000
+1645 32 8616000
+1581 32 8640000
+1651 32 8664000
+1731 32 8688000
+1743 32 8712000
+1717 32 8736000
+1715 32 8760000
+1646 32 8784000
+1551 32 8808000
+1563 32 8832000
+1649 32 8856000
+1742 32 8880000
+1724 32 8904000
+1676 32 8928000
+1664 32 8952000
+1587 32 8976000
+1497 32 9000000
+1503 32 9024000
+1644 32 9048000
+1658 32 9072000
+1680 32 9096000
+1611 32 9120000
+1694 32 9144000
+1668 32 9168000
+1677 32 9192000
+1604 32 9216000
+1567 32 9240000
+1639 32 9264000
+1552 32 9288000
+1486 32 9312000
+1494 32 9336000
+1480 32 9360000
+1509 32 9384000
+1457 32 9408000
+1423 32 9432000
+1459 32 9456000
+1444 32 9480000
+1424 32 9504000
+1413 32 9528000
+1498 32 9552000
+1455 32 9576000
+1393 32 9600000
+1638 32 9624000
+1919 32 9648000
+1979 32 9672000
+1894 32 9696000
+2002 32 9720000
+2062 32 9744000
+2098 32 9768000
+1919 32 9792000
+1738 32 9816000
+1890 32 9840000
+1971 32 9864000
+2429 32 9888000
+1861 32 9912000
diff --git a/neuralnetworks/1.0/IDevice.hal b/neuralnetworks/1.0/IDevice.hal
index b6f9433..91a9555 100644
--- a/neuralnetworks/1.0/IDevice.hal
+++ b/neuralnetworks/1.0/IDevice.hal
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-/* This HAL is a work in progress */
-
package android.hardware.neuralnetworks@1.0;
import IEvent;
@@ -28,7 +26,10 @@
/**
* Gets the capabilities of a driver.
*
- * @return status ErrorStatus::NONE if successful.
+ * @return status Error status of the call, must be:
+ * - NONE if successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
* @return capabilities Capabilities of the driver.
*/
getCapabilities() generates (ErrorStatus status, Capabilities capabilities);
@@ -43,7 +44,11 @@
*
* @param model A model whose operations--and their corresponding
* operands--are to be verified by the driver.
- * @return status ErrorStatus::NONE if successful.
+ * @return status Error status of the call, must be:
+ * - NONE if successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT when provided model is invalid
* @return supportedOperations A list of supported operations, where true
* indicates the operation is supported and
* false indicates the operation is not
@@ -52,7 +57,7 @@
* it is describing.
*/
getSupportedOperations(Model model)
- generates (ErrorStatus status, vec<bool> supportedOperations);
+ generates (ErrorStatus status, vec<bool> supportedOperations);
/**
* Prepares a model for execution.
@@ -60,7 +65,7 @@
* prepareModel is used to make any necessary transformations or alternative
* representations to a model for execution, possible including
* transformations on the constant data, optimization on the model's graph,
- * or compilation into the device's native binary.
+ * or compilation into the device's native binary format.
*
* The only information that may be unknown to the model at this stage is
* the shape of the tensors, which may only be known at execution time.
@@ -68,16 +73,25 @@
* @param model The model to be prepared for execution.
* @param event A synchronization callback that must be signaled once the
* execution has finished.
- * @return status ErrorStatus::NONE if successful.
+ * @return status Error status of the call, must be:
+ * - NONE if preparation task is successfully launched
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT when one of the input arguments is
+ * invalid
* @return preparedModel A handle to the resultant prepared model.
*/
prepareModel(Model model, IEvent event)
- generates (ErrorStatus status, IPreparedModel preparedModel);
+ generates (ErrorStatus status, IPreparedModel preparedModel);
/**
* Returns the current status of a driver.
*
- * @return status Status of the driver.
+ * @return status Status of the driver, one of:
+ * - DeviceStatus::AVAILABLE
+ * - DeviceStatus::BUSY
+ * - DeviceStatus::OFFLINE
+ * - DeviceStatus::UNKNOWN
*/
getStatus() generates (DeviceStatus status);
};
diff --git a/neuralnetworks/1.0/IEvent.hal b/neuralnetworks/1.0/IEvent.hal
index 2ebda58..2fe454c 100644
--- a/neuralnetworks/1.0/IEvent.hal
+++ b/neuralnetworks/1.0/IEvent.hal
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-/* This HAL is a work in progress */
-
package android.hardware.neuralnetworks@1.0;
/**
@@ -37,7 +35,11 @@
* the work) to mark the event as completed so that any threads requiring
* the corresponding output can continue executing.
*
- * @param status ErrorStatus::NONE if successful.
+ * @param status Error status returned from the asynchronous task, must be:
+ * - NONE if asynchronous task was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an
+ * unspecified error
*/
oneway notify(ErrorStatus status);
};
diff --git a/neuralnetworks/1.0/IPreparedModel.hal b/neuralnetworks/1.0/IPreparedModel.hal
index a7c3342..5df883e 100644
--- a/neuralnetworks/1.0/IPreparedModel.hal
+++ b/neuralnetworks/1.0/IPreparedModel.hal
@@ -36,11 +36,16 @@
*
* @param request The input and output information on which the prepared
* model is to be executed.
- * prepared model.
* @param event A callback used for synchronization that must be signaled
* once the execution has finished.
- * @return status ErrorStatus::NONE if the asynchronous task was
- * successfully launched.
+ * @return status Error status of the call, must be:
+ * - NONE if task is successfully launched
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is
+ * not large enough to store the resultant values
+ * - INVALID_ARGUMENT when one of the input arguments is
+ * invalid
*/
execute(Request request, IEvent event) generates (ErrorStatus status);
};
diff --git a/neuralnetworks/1.0/types.hal b/neuralnetworks/1.0/types.hal
index 39e3d34..54ed402 100644
--- a/neuralnetworks/1.0/types.hal
+++ b/neuralnetworks/1.0/types.hal
@@ -218,7 +218,7 @@
*
* Inputs:
* 0: A 4-D tensor, of shape [batches, height, width, depth_in], specifying the input.
- * 1: A 4-D tensor, of shape [depth_out, filter_height, filter_width, depth_in],
+ * 1: A 4-D tensor, of shape [1, filter_height, filter_width, depth_out],
* specifying the filter.
* 2: A 1-D tensor, of shape [depth_out], specifying the bias.
* For input tensor of {@link OperandType::TENSOR_FLOAT32} type, the bias should
@@ -1003,21 +1003,6 @@
};
/**
- * A typed operation.
- */
-struct OperationTuple {
- /**
- * The type of operation.
- */
- OperationType operationType;
-
- /**
- * The input data type of operation.
- */
- OperandType operandType;
-};
-
-/**
* Performance information for the reference workload.
*
* Used by a driver to report its performance characteristics.
@@ -1039,20 +1024,6 @@
*/
struct Capabilities {
/**
- * A collection of typed operations supported by the driver.
- */
- vec<OperationTuple> supportedOperationTuples;
-
- /**
- * Indicates whether a driver caches its prepared model for reuse the next
- * time the application begins. This is useful because the model may have
- * been prepared in a previous run.
- *
- * True if caching is supported, false otherwise.
- */
- bool cachesCompilation;
-
- /**
* Driver performance when operating on float32 data.
*/
PerformanceInfo float32Performance;
@@ -1105,14 +1076,16 @@
/**
* Quantized scale of the operand.
*
- * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM.
+ * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or
+ * TENSOR_INT32.
*/
float scale;
/**
* Quantized zero-point offset of the operand.
*
- * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM.
+ * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or
+ * TENSOR_INT32.
*/
int32_t zeroPoint;
@@ -1142,9 +1115,9 @@
*/
struct Operation {
/**
- * The tuple describing the operation type and input type.
+ * The operation type.
*/
- OperationTuple opTuple;
+ OperationType type;
/**
* Describes the table that contains the indexes of the inputs of the
@@ -1195,12 +1168,18 @@
/**
* A byte buffer containing operand data that were copied into the model.
+ *
+ * An operand's value must be located here if and only if Operand::lifetime
+ * equals OperandLifeTime::CONSTANT_COPY.
*/
vec<uint8_t> operandValues;
/**
* A collection of shared memory pools containing operand data that were
* registered by the model.
+ *
+ * An operand's value must be located here if and only if Operand::lifetime
+ * equals OperandLifeTime::CONSTANT_REFERENCE.
*/
vec<memory> pools;
};
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 2318430..89e1021 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -19,6 +19,7 @@
srcs: [
"Event.cpp",
"GeneratedTestHarness.cpp",
+ "Models.cpp",
"VtsHalNeuralnetworksV1_0TargetTest.cpp",
],
defaults: ["VtsHalTargetTestDefaults"],
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index db90ac2..4b8daec 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -42,6 +42,24 @@
using ::generated_tests::Float32Operands;
using ::generated_tests::Int32Operands;
using ::generated_tests::Quant8Operands;
+using ::generated_tests::compare;
+
+template <typename ty>
+void copy_back_(MixedTyped* dst, const std::vector<RequestArgument>& ra, char* src) {
+ MixedTyped& test = *dst;
+ for_each(test, [&ra, src](int index, std::vector<ty>& m) {
+ ASSERT_EQ(m.size(), ra[index].location.length / sizeof(ty));
+ char* begin = src + ra[index].location.offset;
+ memcpy(m.data(), begin, ra[index].location.length);
+ });
+}
+
+void copy_back(MixedTyped* dst, const std::vector<RequestArgument>& ra, char* src) {
+ copy_back_<float>(dst, ra, src);
+ copy_back_<int32_t>(dst, ra, src);
+ copy_back_<uint8_t>(dst, ra, src);
+}
+
// Top level driver for models and examples generated by test_generator.py
// Test driver for those generated from ml/nn/runtime/test/spec
void Execute(const sp<IDevice>& device, std::function<Model(void)> create_model,
@@ -97,9 +115,7 @@
MixedTyped test; // holding test results
// Go through all outputs, initialize RequestArgument descriptors
- resize_accordingly<float>(golden, test);
- resize_accordingly<int32_t>(golden, test);
- resize_accordingly<uint8_t>(golden, test);
+ resize_accordingly(golden, test);
for_all(golden, [&outputs_info, &outputSize](int index, auto, auto s) {
if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
RequestArgument arg = {
@@ -156,40 +172,16 @@
// validate results
outputMemory->read();
-#define COPY_BACK(ty) \
- for_each<ty>(test, [&outputs_info, outputPtr](int index, std::vector<ty>& m) { \
- RequestArgument& i = outputs_info[index]; \
- ASSERT_EQ(m.size(), i.location.length / sizeof(ty)); \
- char* begin = outputPtr + i.location.offset; \
- memcpy(m.data(), begin, i.location.length); \
- });
- COPY_BACK(float);
- COPY_BACK(int32_t);
- COPY_BACK(uint8_t);
-#undef COPY_BACK
+ copy_back(&test, outputs_info, outputPtr);
outputMemory->commit();
// Filter out don't cares
MixedTyped filtered_golden;
MixedTyped filtered_test;
- filter<float>(golden, &filtered_golden, is_ignored);
- filter<float>(test, &filtered_test, is_ignored);
- filter<int32_t>(golden, &filtered_golden, is_ignored);
- filter<int32_t>(test, &filtered_test, is_ignored);
- filter<uint8_t>(golden, &filtered_golden, is_ignored);
- filter<uint8_t>(test, &filtered_test, is_ignored);
+ filter(golden, &filtered_golden, is_ignored);
+ filter(test, &filtered_test, is_ignored);
// We want "close-enough" results for float
- for_each<float>(filtered_golden, [&filtered_test](int index, auto& golden_float) {
- auto& test_float_operands = std::get<Float32Operands>(filtered_test);
- auto& test_float = test_float_operands[index];
- for (unsigned int i = 0; i < golden_float.size(); i++) {
- SCOPED_TRACE(i);
- EXPECT_NEAR(golden_float[i], test_float[i], 1.e-5);
- }
- });
- EXPECT_EQ(std::get<Int32Operands>(filtered_golden), std::get<Int32Operands>(filtered_test));
- EXPECT_EQ(std::get<Quant8Operands>(filtered_golden),
- std::get<Quant8Operands>(filtered_test));
+ compare(filtered_golden, filtered_test);
}
}
diff --git a/neuralnetworks/1.0/vts/functional/Models.cpp b/neuralnetworks/1.0/vts/functional/Models.cpp
new file mode 100644
index 0000000..8ce4f25
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Models.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2017 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 "neuralnetworks_hidl_hal_test"
+
+#include "Models.h"
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace vts {
+namespace functional {
+
+// create a valid model
+Model createValidTestModel() {
+ const std::vector<float> operand2Data = {5.0f, 6.0f, 7.0f, 8.0f};
+ const uint32_t size = operand2Data.size() * sizeof(float);
+
+ const uint32_t operand1 = 0;
+ const uint32_t operand2 = 1;
+ const uint32_t operand3 = 2;
+ const uint32_t operand4 = 3;
+
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {1, 2, 2, 1},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {1, 2, 2, 1},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = size},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = size, .length = sizeof(int32_t)},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {1, 2, 2, 1},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ };
+
+ const std::vector<Operation> operations = {{
+ .type = OperationType::ADD, .inputs = {operand1, operand2, operand3}, .outputs = {operand4},
+ }};
+
+ const std::vector<uint32_t> inputIndexes = {operand1};
+ const std::vector<uint32_t> outputIndexes = {operand4};
+ std::vector<uint8_t> operandValues(
+ reinterpret_cast<const uint8_t*>(operand2Data.data()),
+ reinterpret_cast<const uint8_t*>(operand2Data.data()) + size);
+ int32_t activation[1] = {static_cast<int32_t>(FusedActivationFunc::NONE)};
+ operandValues.insert(operandValues.end(), reinterpret_cast<const uint8_t*>(&activation[0]),
+ reinterpret_cast<const uint8_t*>(&activation[1]));
+
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+// create first invalid model
+Model createInvalidTestModel1() {
+ Model model = createValidTestModel();
+ model.operations[0].type = static_cast<OperationType>(0xDEADBEEF); /* INVALID */
+ return model;
+}
+
+// create second invalid model
+Model createInvalidTestModel2() {
+ Model model = createValidTestModel();
+ const uint32_t operand1 = 0;
+ const uint32_t operand5 = 4; // INVALID OPERAND
+ model.inputIndexes = std::vector<uint32_t>({operand1, operand5 /* INVALID OPERAND */});
+ return model;
+}
+
+// allocator helper
+hidl_memory allocateSharedMemory(int64_t size, const std::string& type = "ashmem") {
+ hidl_memory memory;
+
+ sp<IAllocator> allocator = IAllocator::getService(type);
+ if (!allocator.get()) {
+ return {};
+ }
+
+ Return<void> ret = allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
+ ASSERT_TRUE(success);
+ memory = mem;
+ });
+ if (!ret.isOk()) {
+ return {};
+ }
+
+ return memory;
+}
+
+// create a valid request
+Request createValidTestRequest() {
+ std::vector<float> inputData = {1.0f, 2.0f, 3.0f, 4.0f};
+ std::vector<float> outputData = {-1.0f, -1.0f, -1.0f, -1.0f};
+ const uint32_t INPUT = 0;
+ const uint32_t OUTPUT = 1;
+
+ // prepare inputs
+ uint32_t inputSize = static_cast<uint32_t>(inputData.size() * sizeof(float));
+ uint32_t outputSize = static_cast<uint32_t>(outputData.size() * sizeof(float));
+ std::vector<RequestArgument> inputs = {{
+ .location = {.poolIndex = INPUT, .offset = 0, .length = inputSize}, .dimensions = {},
+ }};
+ std::vector<RequestArgument> outputs = {{
+ .location = {.poolIndex = OUTPUT, .offset = 0, .length = outputSize}, .dimensions = {},
+ }};
+ std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
+ allocateSharedMemory(outputSize)};
+ if (pools[INPUT].size() == 0 || pools[OUTPUT].size() == 0) {
+ return {};
+ }
+
+ // load data
+ sp<IMemory> inputMemory = mapMemory(pools[INPUT]);
+ sp<IMemory> outputMemory = mapMemory(pools[OUTPUT]);
+ if (inputMemory.get() == nullptr || outputMemory.get() == nullptr) {
+ return {};
+ }
+ float* inputPtr = reinterpret_cast<float*>(static_cast<void*>(inputMemory->getPointer()));
+ float* outputPtr = reinterpret_cast<float*>(static_cast<void*>(outputMemory->getPointer()));
+ if (inputPtr == nullptr || outputPtr == nullptr) {
+ return {};
+ }
+ inputMemory->update();
+ outputMemory->update();
+ std::copy(inputData.begin(), inputData.end(), inputPtr);
+ std::copy(outputData.begin(), outputData.end(), outputPtr);
+ inputMemory->commit();
+ outputMemory->commit();
+
+ return {.inputs = inputs, .outputs = outputs, .pools = pools};
+}
+
+// create first invalid request
+Request createInvalidTestRequest1() {
+ Request request = createValidTestRequest();
+ const uint32_t INVALID = 2;
+ std::vector<float> inputData = {1.0f, 2.0f, 3.0f, 4.0f};
+ uint32_t inputSize = static_cast<uint32_t>(inputData.size() * sizeof(float));
+ request.inputs[0].location = {
+ .poolIndex = INVALID /* INVALID */, .offset = 0, .length = inputSize};
+ return request;
+}
+
+// create second invalid request
+Request createInvalidTestRequest2() {
+ Request request = createValidTestRequest();
+ request.inputs[0].dimensions = std::vector<uint32_t>({1, 2, 3, 4, 5, 6, 7, 8} /* INVALID */);
+ return request;
+}
+
+} // namespace functional
+} // namespace vts
+} // namespace V1_0
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/Models.h b/neuralnetworks/1.0/vts/functional/Models.h
new file mode 100644
index 0000000..e0d57d5
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Models.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 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 "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace vts {
+namespace functional {
+
+// create the model
+Model createValidTestModel();
+Model createInvalidTestModel1();
+Model createInvalidTestModel2();
+
+// create the request
+Request createValidTestRequest();
+Request createInvalidTestRequest1();
+Request createInvalidTestRequest2();
+
+} // namespace functional
+} // namespace vts
+} // namespace V1_0
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
index 453e3e5..0f354d1 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
@@ -18,6 +18,7 @@
#include "VtsHalNeuralnetworksV1_0TargetTest.h"
#include "Event.h"
+#include "Models.h"
#include "TestHarness.h"
#include <android-base/logging.h>
@@ -65,6 +66,32 @@
void NeuralnetworksHidlTest::TearDown() {}
+sp<IPreparedModel> NeuralnetworksHidlTest::doPrepareModelShortcut(const Model& model) {
+ sp<IPreparedModel> preparedModel;
+ ErrorStatus prepareStatus;
+ sp<Event> preparationEvent = new Event();
+ if (preparationEvent.get() == nullptr) {
+ return nullptr;
+ }
+
+ Return<void> prepareRet = device->prepareModel(
+ model, preparationEvent, [&](ErrorStatus status, const sp<IPreparedModel>& prepared) {
+ prepareStatus = status;
+ preparedModel = prepared;
+ });
+
+ if (!prepareRet.isOk() || prepareStatus != ErrorStatus::NONE ||
+ preparedModel.get() == nullptr) {
+ return nullptr;
+ }
+ Event::Status eventStatus = preparationEvent->wait();
+ if (eventStatus != Event::Status::SUCCESS) {
+ return nullptr;
+ }
+
+ return preparedModel;
+}
+
// create device test
TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
@@ -80,9 +107,6 @@
Return<void> ret =
device->getCapabilities([](ErrorStatus status, const Capabilities& capabilities) {
EXPECT_EQ(ErrorStatus::NONE, status);
- EXPECT_NE(nullptr, capabilities.supportedOperationTuples.data());
- EXPECT_NE(0ull, capabilities.supportedOperationTuples.size());
- EXPECT_EQ(0u, static_cast<uint32_t>(capabilities.cachesCompilation) & ~0x1);
EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
@@ -91,107 +115,9 @@
EXPECT_TRUE(ret.isOk());
}
-namespace {
-// create the model
-Model createTestModel() {
- const std::vector<float> operand2Data = {5.0f, 6.0f, 7.0f, 8.0f};
- const uint32_t size = operand2Data.size() * sizeof(float);
-
- const uint32_t operand1 = 0;
- const uint32_t operand2 = 1;
- const uint32_t operand3 = 2;
- const uint32_t operand4 = 3;
-
- const std::vector<Operand> operands = {
- {
- .type = OperandType::TENSOR_FLOAT32,
- .dimensions = {1, 2, 2, 1},
- .numberOfConsumers = 1,
- .scale = 0.0f,
- .zeroPoint = 0,
- .lifetime = OperandLifeTime::MODEL_INPUT,
- .location = {.poolIndex = 0, .offset = 0, .length = 0},
- },
- {
- .type = OperandType::TENSOR_FLOAT32,
- .dimensions = {1, 2, 2, 1},
- .numberOfConsumers = 1,
- .scale = 0.0f,
- .zeroPoint = 0,
- .lifetime = OperandLifeTime::CONSTANT_COPY,
- .location = {.poolIndex = 0, .offset = 0, .length = size},
- },
- {
- .type = OperandType::INT32,
- .dimensions = {},
- .numberOfConsumers = 1,
- .scale = 0.0f,
- .zeroPoint = 0,
- .lifetime = OperandLifeTime::CONSTANT_COPY,
- .location = {.poolIndex = 0, .offset = size, .length = sizeof(int32_t)},
- },
- {
- .type = OperandType::TENSOR_FLOAT32,
- .dimensions = {1, 2, 2, 1},
- .numberOfConsumers = 0,
- .scale = 0.0f,
- .zeroPoint = 0,
- .lifetime = OperandLifeTime::MODEL_OUTPUT,
- .location = {.poolIndex = 0, .offset = 0, .length = 0},
- },
- };
-
- const std::vector<Operation> operations = {{
- .opTuple = {OperationType::ADD, OperandType::TENSOR_FLOAT32},
- .inputs = {operand1, operand2, operand3},
- .outputs = {operand4},
- }};
-
- const std::vector<uint32_t> inputIndexes = {operand1};
- const std::vector<uint32_t> outputIndexes = {operand4};
- std::vector<uint8_t> operandValues(
- reinterpret_cast<const uint8_t*>(operand2Data.data()),
- reinterpret_cast<const uint8_t*>(operand2Data.data()) + size);
- int32_t activation[1] = {static_cast<int32_t>(FusedActivationFunc::NONE)};
- operandValues.insert(operandValues.end(), reinterpret_cast<const uint8_t*>(&activation[0]),
- reinterpret_cast<const uint8_t*>(&activation[1]));
-
- const std::vector<hidl_memory> pools = {};
-
- return {
- .operands = operands,
- .operations = operations,
- .inputIndexes = inputIndexes,
- .outputIndexes = outputIndexes,
- .operandValues = operandValues,
- .pools = pools,
- };
-}
-} // anonymous namespace
-
-// allocator helper
-hidl_memory allocateSharedMemory(int64_t size, const std::string& type = "ashmem") {
- hidl_memory memory;
-
- sp<IAllocator> allocator = IAllocator::getService(type);
- if (!allocator.get()) {
- return {};
- }
-
- Return<void> ret = allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
- ASSERT_TRUE(success);
- memory = mem;
- });
- if (!ret.isOk()) {
- return {};
- }
-
- return memory;
-}
-
-// supported subgraph test
-TEST_F(NeuralnetworksHidlTest, SupportedOperationsTest) {
- Model model = createTestModel();
+// supported operations positive test
+TEST_F(NeuralnetworksHidlTest, SupportedOperationsPositiveTest) {
+ Model model = createValidTestModel();
Return<void> ret = device->getSupportedOperations(
model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
EXPECT_EQ(ErrorStatus::NONE, status);
@@ -200,76 +126,126 @@
EXPECT_TRUE(ret.isOk());
}
-// execute simple graph
-TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphTest) {
- std::vector<float> inputData = {1.0f, 2.0f, 3.0f, 4.0f};
- std::vector<float> outputData = {-1.0f, -1.0f, -1.0f, -1.0f};
- std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
- const uint32_t INPUT = 0;
- const uint32_t OUTPUT = 1;
+// supported operations negative test 1
+TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest1) {
+ Model model = createInvalidTestModel1();
+ Return<void> ret = device->getSupportedOperations(
+ model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ (void)supported;
+ });
+ EXPECT_TRUE(ret.isOk());
+}
- // prepare request
- Model model = createTestModel();
- sp<IPreparedModel> preparedModel;
+// supported operations negative test 2
+TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest2) {
+ Model model = createInvalidTestModel2();
+ Return<void> ret = device->getSupportedOperations(
+ model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ (void)supported;
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+
+// prepare simple model positive test
+TEST_F(NeuralnetworksHidlTest, SimplePrepareModelPositiveTest) {
+ Model model = createValidTestModel();
sp<Event> preparationEvent = new Event();
ASSERT_NE(nullptr, preparationEvent.get());
Return<void> prepareRet = device->prepareModel(
model, preparationEvent, [&](ErrorStatus status, const sp<IPreparedModel>& prepared) {
EXPECT_EQ(ErrorStatus::NONE, status);
- preparedModel = prepared;
+ (void)prepared;
});
ASSERT_TRUE(prepareRet.isOk());
+}
+
+// prepare simple model negative test 1
+TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest1) {
+ Model model = createInvalidTestModel1();
+ sp<Event> preparationEvent = new Event();
+ ASSERT_NE(nullptr, preparationEvent.get());
+ Return<void> prepareRet = device->prepareModel(
+ model, preparationEvent, [&](ErrorStatus status, const sp<IPreparedModel>& prepared) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ (void)prepared;
+ });
+ ASSERT_TRUE(prepareRet.isOk());
+}
+
+// prepare simple model negative test 2
+TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest2) {
+ Model model = createInvalidTestModel2();
+ sp<Event> preparationEvent = new Event();
+ ASSERT_NE(nullptr, preparationEvent.get());
+ Return<void> prepareRet = device->prepareModel(
+ model, preparationEvent, [&](ErrorStatus status, const sp<IPreparedModel>& prepared) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ (void)prepared;
+ });
+ ASSERT_TRUE(prepareRet.isOk());
+}
+
+// execute simple graph positive test
+TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphPositiveTest) {
+ Model model = createValidTestModel();
+ sp<IPreparedModel> preparedModel = doPrepareModelShortcut(model);
ASSERT_NE(nullptr, preparedModel.get());
- Event::Status preparationStatus = preparationEvent->wait();
- EXPECT_EQ(Event::Status::SUCCESS, preparationStatus);
+ Request request = createValidTestRequest();
- // prepare inputs
- uint32_t inputSize = static_cast<uint32_t>(inputData.size() * sizeof(float));
- uint32_t outputSize = static_cast<uint32_t>(outputData.size() * sizeof(float));
- std::vector<RequestArgument> inputs = {{
- .location = {.poolIndex = INPUT, .offset = 0, .length = inputSize}, .dimensions = {},
- }};
- std::vector<RequestArgument> outputs = {{
- .location = {.poolIndex = OUTPUT, .offset = 0, .length = outputSize}, .dimensions = {},
- }};
- std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
- allocateSharedMemory(outputSize)};
- ASSERT_NE(0ull, pools[INPUT].size());
- ASSERT_NE(0ull, pools[OUTPUT].size());
-
- // load data
- sp<IMemory> inputMemory = mapMemory(pools[INPUT]);
- sp<IMemory> outputMemory = mapMemory(pools[OUTPUT]);
- ASSERT_NE(nullptr, inputMemory.get());
- ASSERT_NE(nullptr, outputMemory.get());
- float* inputPtr = reinterpret_cast<float*>(static_cast<void*>(inputMemory->getPointer()));
- float* outputPtr = reinterpret_cast<float*>(static_cast<void*>(outputMemory->getPointer()));
- ASSERT_NE(nullptr, inputPtr);
- ASSERT_NE(nullptr, outputPtr);
- inputMemory->update();
- outputMemory->update();
- std::copy(inputData.begin(), inputData.end(), inputPtr);
- std::copy(outputData.begin(), outputData.end(), outputPtr);
- inputMemory->commit();
- outputMemory->commit();
-
- // execute request
sp<Event> executionEvent = new Event();
ASSERT_NE(nullptr, executionEvent.get());
- Return<ErrorStatus> executeStatus = preparedModel->execute(
- {.inputs = inputs, .outputs = outputs, .pools = pools}, executionEvent);
+ Return<ErrorStatus> executeStatus = preparedModel->execute(request, executionEvent);
ASSERT_TRUE(executeStatus.isOk());
EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executeStatus));
Event::Status eventStatus = executionEvent->wait();
EXPECT_EQ(Event::Status::SUCCESS, eventStatus);
- // validate results { 1+5, 2+6, 3+7, 4+8 }
+ std::vector<float> outputData = {-1.0f, -1.0f, -1.0f, -1.0f};
+ std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
+ const uint32_t OUTPUT = 1;
+
+ sp<IMemory> outputMemory = mapMemory(request.pools[OUTPUT]);
+ ASSERT_NE(nullptr, outputMemory.get());
+ float* outputPtr = reinterpret_cast<float*>(static_cast<void*>(outputMemory->getPointer()));
+ ASSERT_NE(nullptr, outputPtr);
outputMemory->read();
std::copy(outputPtr, outputPtr + outputData.size(), outputData.begin());
outputMemory->commit();
EXPECT_EQ(expectedData, outputData);
}
+// execute simple graph negative test 1
+TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest1) {
+ Model model = createValidTestModel();
+ sp<IPreparedModel> preparedModel = doPrepareModelShortcut(model);
+ ASSERT_NE(nullptr, preparedModel.get());
+ Request request = createInvalidTestRequest1();
+
+ sp<Event> executionEvent = new Event();
+ ASSERT_NE(nullptr, executionEvent.get());
+ Return<ErrorStatus> executeStatus = preparedModel->execute(request, executionEvent);
+ ASSERT_TRUE(executeStatus.isOk());
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeStatus));
+ executionEvent->wait();
+}
+
+// execute simple graph negative test 2
+TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest2) {
+ Model model = createValidTestModel();
+ sp<IPreparedModel> preparedModel = doPrepareModelShortcut(model);
+ ASSERT_NE(nullptr, preparedModel.get());
+ Request request = createInvalidTestRequest2();
+
+ sp<Event> executionEvent = new Event();
+ ASSERT_NE(nullptr, executionEvent.get());
+ Return<ErrorStatus> executeStatus = preparedModel->execute(request, executionEvent);
+ ASSERT_TRUE(executeStatus.isOk());
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeStatus));
+ executionEvent->wait();
+}
+
// Mixed-typed examples
typedef MixedTypedExampleType MixedTypedExample;
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
index 9c56e6a..1b3b334 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
@@ -72,6 +72,8 @@
void SetUp() override;
void TearDown() override;
+ sp<IPreparedModel> doPrepareModelShortcut(const Model& model);
+
sp<IDevice> device;
};
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
index fc61e1c..2cbe479 100644
--- a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
+++ b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
@@ -91,35 +91,42 @@
// Ensure handles can be set with correct socket options.
TEST_F(OffloadConfigHidlTest, TestSetHandles) {
- unique_fd fd1(netlinkSocket(kFd1Groups));
- if (fd1.get() < 0) {
- ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
- FAIL();
- }
- native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
- nativeHandle1->data[0] = fd1.release();
- const hidl_handle h1 = hidl_handle(nativeHandle1);
+ // Try multiple times in a row to see if it provokes file descriptor leaks.
+ for (int i = 0; i < 1024; i++) {
+ unique_fd fd1(netlinkSocket(kFd1Groups));
+ if (fd1.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+ nativeHandle1->data[0] = fd1.release();
+ hidl_handle h1;
+ h1.setTo(nativeHandle1, true);
- unique_fd fd2(netlinkSocket(kFd2Groups));
- if (fd2.get() < 0) {
- ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
- FAIL();
- }
- native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
- nativeHandle2->data[0] = fd2.release();
- const hidl_handle h2 = hidl_handle(nativeHandle2);
+ unique_fd fd2(netlinkSocket(kFd2Groups));
+ if (fd2.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+ nativeHandle2->data[0] = fd2.release();
+ hidl_handle h2;
+ h2.setTo(nativeHandle2, true);
- const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
- ASSERT_TRUE(ret.isOk());
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+ }
}
// Passing a handle without an associated file descriptor should return an error
// (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
- const hidl_handle h1 = hidl_handle(nativeHandle1);
+ hidl_handle h1;
+ h1.setTo(nativeHandle1, true);
native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
- const hidl_handle h2 = hidl_handle(nativeHandle2);
+ hidl_handle h2;
+ h2.setTo(nativeHandle2, true);
const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
ASSERT_TRUE(ret.isOk());
@@ -135,10 +142,12 @@
}
native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
nativeHandle1->data[0] = fd1.release();
- const hidl_handle h1 = hidl_handle(nativeHandle1);
+ hidl_handle h1;
+ h1.setTo(nativeHandle1, true);
native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
- const hidl_handle h2 = hidl_handle(nativeHandle2);
+ hidl_handle h2;
+ h2.setTo(nativeHandle2, true);
const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
ASSERT_TRUE(ret.isOk());
@@ -148,7 +157,8 @@
// (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
- const hidl_handle h1 = hidl_handle(nativeHandle1);
+ hidl_handle h1;
+ h1.setTo(nativeHandle1, true);
unique_fd fd2(netlinkSocket(kFd2Groups));
if (fd2.get() < 0) {
@@ -157,7 +167,8 @@
}
native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
nativeHandle2->data[0] = fd2.release();
- const hidl_handle h2 = hidl_handle(nativeHandle2);
+ hidl_handle h2;
+ h2.setTo(nativeHandle2, true);
const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
ASSERT_TRUE(ret.isOk());
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
index 3059eac..52dd026 100644
--- a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -46,6 +46,12 @@
using android::hardware::Void;
using android::sp;
+enum class ExpectBoolean {
+ Ignored = -1,
+ False = 0,
+ True = 1,
+};
+
// We use #defines here so as to get local lamba captures and error message line numbers
#define ASSERT_TRUE_CALLBACK \
[&](bool success, std::string errMsg) { \
@@ -112,7 +118,12 @@
prepareControlHal();
}
- virtual void TearDown() override { stopOffload(false); }
+ virtual void TearDown() override {
+ // For good measure, we should try stopOffload() once more. Since we
+ // don't know where we are in HAL call test cycle we don't know what
+ // return code to actually expect, so we just ignore it.
+ stopOffload(ExpectBoolean::Ignored);
+ }
// The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
// setup everything correctly and verify basic readiness.
@@ -127,7 +138,8 @@
}
native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
nativeHandle1->data[0] = fd1.release();
- hidl_handle h1 = hidl_handle(nativeHandle1);
+ hidl_handle h1;
+ h1.setTo(nativeHandle1, true);
unique_fd fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
if (fd2.get() < 0) {
@@ -136,7 +148,8 @@
}
native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
nativeHandle2->data[0] = fd2.release();
- hidl_handle h2 = hidl_handle(nativeHandle2);
+ hidl_handle h2;
+ h2.setTo(nativeHandle2, true);
const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
ASSERT_TRUE(ret.isOk());
@@ -166,12 +179,21 @@
initOffload(true);
}
- void stopOffload(const bool expected_result) {
+ void stopOffload(const ExpectBoolean value) {
auto cb = [&](bool success, const hidl_string& errMsg) {
if (!success) {
ALOGI("Error message: %s", errMsg.c_str());
}
- ASSERT_EQ(expected_result, success);
+ switch (value) {
+ case ExpectBoolean::False:
+ ASSERT_EQ(false, success);
+ break;
+ case ExpectBoolean::True:
+ ASSERT_EQ(true, success);
+ break;
+ case ExpectBoolean::Ignored:
+ break;
+ }
};
const Return<void> ret = control->stopOffload(cb);
ASSERT_TRUE(ret.isOk());
@@ -209,22 +231,22 @@
initOffload(false);
initOffload(false);
initOffload(false);
- stopOffload(true); // balance out initOffload(true)
+ stopOffload(ExpectBoolean::True); // balance out initOffload(true)
}
// Check that calling stopOffload() without first having called initOffload() returns false.
TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
- stopOffload(false);
- stopOffload(false);
- stopOffload(false);
+ stopOffload(ExpectBoolean::False);
+ stopOffload(ExpectBoolean::False);
+ stopOffload(ExpectBoolean::False);
}
// Check that calling stopOffload() after a complete init/stop cycle returns false.
TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
initOffload(true);
- stopOffload(true); // balance out initOffload(true)
- stopOffload(false);
- stopOffload(false);
+ stopOffload(ExpectBoolean::True); // balance out initOffload(true)
+ stopOffload(ExpectBoolean::False);
+ stopOffload(ExpectBoolean::False);
}
// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
@@ -305,7 +327,12 @@
setupControlHal();
}
- virtual void TearDown() override { stopOffload(true); }
+ virtual void TearDown() override {
+ // For good measure, we should try stopOffload() once more. Since we
+ // don't know where we are in HAL call test cycle we don't know what
+ // return code to actually expect, so we just ignore it.
+ stopOffload(ExpectBoolean::Ignored);
+ }
};
/*
@@ -575,16 +602,24 @@
TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
const hidl_string iface("dummy0");
const hidl_string prefix("192.0.2.0/24");
- const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
- EXPECT_TRUE(ret.isOk());
+ // First add the downstream, otherwise removeDownstream logic can reasonably
+ // return false for downstreams not previously added.
+ const Return<void> add = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(add.isOk());
+ const Return<void> del = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(del.isOk());
}
// Test removeDownstream() works given an IPv6 prefix.
TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
const hidl_string iface("dummy0");
const hidl_string prefix("2001:db8::/64");
- const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
- EXPECT_TRUE(ret.isOk());
+ // First add the downstream, otherwise removeDownstream logic can reasonably
+ // return false for downstreams not previously added.
+ const Return<void> add = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(add.isOk());
+ const Return<void> del = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(del.isOk());
}
// Test removeDownstream() fails given all empty parameters.