Merge "Refactor NNAPI VTS to remove unreasonable dependence between versions"
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
index f064367..d689e62 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
@@ -109,20 +109,13 @@
// An enum to represent the result of parsing START_SESSION message from the VMS service.
enum VmsSessionStatus {
- // New server session is received if the new client ID is -1 and the new server ID is not an
- // invalid ID.
+ // When a new session is received, the client should acknowledge it with the correct
+ // IDs in the START_SESSION message.
kNewServerSession,
- // Ack to new client session is received if the new client ID is same as the old one and the new
- // server ID is not an invalid ID.
- kAckToNewClientSession,
- // Error codes:
+ // When an acknowledgement it received, the client can start using the connection.
+ kAckToCurrentSession,
// Invalid message with either invalid format or unexpected data.
- kInvalidMessage,
- // Invalid server ID. New ID should always be greater than or equal to max_of(0, current server
- // ID)
- kInvalidServiceId,
- // Invalid client ID. New ID should always be either -1 or the current client ID.
- kInvalidClientId
+ kInvalidMessage
};
// Creates an empty base VMS message with some pre-populated default fields.
@@ -235,7 +228,7 @@
// Takes a start session message, current service ID, current client ID; and returns the type/status
// of the message. It also populates the new service ID with the correct value.
VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
- const int service_id, const int client_id,
+ const int current_service_id, const int current_client_id,
int* new_service_id);
} // namespace vms
diff --git a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
index a5fcbaf..d346206 100644
--- a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
@@ -272,27 +272,28 @@
}
VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
- const int service_id, const int client_id,
+ const int current_service_id, const int current_client_id,
int* new_service_id) {
if (isValidVmsMessage(start_session) &&
parseMessageType(start_session) == VmsMessageType::START_SESSION &&
start_session.value.int32Values.size() == kSessionIdsSize + 1) {
*new_service_id = start_session.value.int32Values[1];
const int new_client_id = start_session.value.int32Values[2];
- if (*new_service_id < std::max(0, service_id)) {
- *new_service_id = service_id;
- return VmsSessionStatus::kInvalidServiceId;
- }
- if (new_client_id == -1) {
+ if (new_client_id != current_client_id) {
+ // If the new_client_id = -1, it means the service has newly started.
+ // But if it is not -1 and is different than the current client ID, then
+ // it means that the service did not have the correct client ID. In
+ // both these cases, the client should acknowledge with a START_SESSION
+ // message containing the correct client ID. So here, the status is returned as
+ // kNewServerSession.
return VmsSessionStatus::kNewServerSession;
+ } else {
+ // kAckToCurrentSession is returned if the new client ID is same as the current one.
+ return VmsSessionStatus::kAckToCurrentSession;
}
- if (new_client_id == client_id) {
- return VmsSessionStatus::kAckToNewClientSession;
- }
- *new_service_id = service_id;
- return VmsSessionStatus::kInvalidClientId;
}
- *new_service_id = service_id;
+ // If the message is invalid then persist the old service ID.
+ *new_service_id = current_service_id;
return VmsSessionStatus::kInvalidMessage;
}
diff --git a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
index 3716738..7189212 100644
--- a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
@@ -371,25 +371,25 @@
int new_service_id;
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
- VmsSessionStatus::kAckToNewClientSession);
+ VmsSessionStatus::kAckToCurrentSession);
EXPECT_EQ(new_service_id, 123);
}
-TEST(VmsUtilsTest, startSessionClientNewlyStartedWithSameServerId) {
+TEST(VmsUtilsTest, startSessionClientNewlyStartedWithSameServerAndClientId) {
auto message = createBaseVmsMessage(3);
int new_service_id;
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
- VmsSessionStatus::kAckToNewClientSession);
+ VmsSessionStatus::kAckToCurrentSession);
EXPECT_EQ(new_service_id, 123);
}
-TEST(VmsUtilsTest, startSessionClientNewlyStartedEdgeCase) {
+TEST(VmsUtilsTest, startSessionWithZeroAsIds) {
auto message = createBaseVmsMessage(3);
int new_service_id;
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, 0};
EXPECT_EQ(parseStartSessionMessage(*message, 0, 0, &new_service_id),
- VmsSessionStatus::kAckToNewClientSession);
+ VmsSessionStatus::kAckToCurrentSession);
EXPECT_EQ(new_service_id, 0);
}
@@ -398,28 +398,19 @@
int new_service_id;
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 120, 456};
EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
- VmsSessionStatus::kInvalidServiceId);
- EXPECT_EQ(new_service_id, 123);
+ VmsSessionStatus::kAckToCurrentSession);
+ EXPECT_EQ(new_service_id, 120);
}
-TEST(VmsUtilsTest, startSessionInvalidServiceIdEdgeCase) {
+TEST(VmsUtilsTest, startSessionNegativeServerId) {
auto message = createBaseVmsMessage(3);
int new_service_id;
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), -1, 456};
EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
- VmsSessionStatus::kInvalidServiceId);
+ VmsSessionStatus::kAckToCurrentSession);
EXPECT_EQ(new_service_id, -1);
}
-TEST(VmsUtilsTest, startSessionInvalidClientId) {
- auto message = createBaseVmsMessage(3);
- int new_service_id;
- message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 457};
- EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
- VmsSessionStatus::kInvalidClientId);
- EXPECT_EQ(new_service_id, 123);
-}
-
TEST(VmsUtilsTest, startSessionInvalidMessageFormat) {
auto message = createBaseVmsMessage(2);
int new_service_id;
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index 40961f7..d3d7387 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -14,29 +14,24 @@
* limitations under the License.
*/
-#define LOG_TAG "face_hidl_test"
+#define LOG_TAG "biometrics_face_hidl_hal_test"
+#include <android/hardware/biometrics/face/1.0/IBiometricsFace.h>
+#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android/hardware/biometrics/face/1.0/IBiometricsFace.h>
-#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <utils/Condition.h>
-#include <cinttypes>
+#include <chrono>
#include <cstdint>
-#include <future>
-#include <utility>
+#include <random>
-using android::Condition;
-using android::Mutex;
using android::sp;
-using android::base::GetUintProperty;
using android::hardware::hidl_vec;
using android::hardware::Return;
+using android::hardware::Void;
using android::hardware::biometrics::face::V1_0::FaceAcquiredInfo;
using android::hardware::biometrics::face::V1_0::FaceError;
using android::hardware::biometrics::face::V1_0::Feature;
@@ -48,263 +43,203 @@
namespace {
-const uint32_t kTimeout = 3;
-const std::chrono::seconds kTimeoutInSeconds = std::chrono::seconds(kTimeout);
-const uint32_t kUserId = 99;
-const uint32_t kFaceId = 5;
-const char kTmpDir[] = "/data/system/users/0/facedata";
-const int kIterations = 1000;
+// Arbitrary, nonexistent userId
+constexpr uint32_t kUserId = 9;
+// Arbitrary, nonexistent faceId
+constexpr uint32_t kFaceId = 5;
+constexpr uint32_t kTimeoutSec = 3;
+constexpr auto kTimeout = std::chrono::seconds(kTimeoutSec);
+constexpr int kGenerateChallengeIterations = 10;
+constexpr char kFacedataDir[] = "/data/vendor_de/0/facedata";
+constexpr char kCallbackNameOnEnrollResult[] = "onEnrollResult";
+constexpr char kCallbackNameOnAuthenticated[] = "onAuthenticated";
+constexpr char kCallbackNameOnAcquired[] = "onAcquired";
+constexpr char kCallbackNameOnError[] = "onError";
+constexpr char kCallbackNameOnRemoved[] = "onRemoved";
+constexpr char kCallbackNameOnEnumerate[] = "onEnumerate";
+constexpr char kCallbackNameOnLockoutChanged[] = "onLockoutChanged";
-const auto kAssertCallbackIsSet = [](const OptionalUint64& res) {
- ASSERT_EQ(Status::OK, res.status);
- // Makes sure the "deviceId" represented by "res.value" is not 0.
- // 0 would mean the HIDL is not available.
- ASSERT_NE(0UL, res.value);
+// Callback arguments that need to be captured for the tests.
+struct FaceCallbackArgs {
+ // The error passed to the last onError() callback.
+ FaceError error;
+
+ // The userId passed to the last onRemoved() callback.
+ int32_t userId;
};
-// Wait for a callback to occur (signaled by the given future) up to the
-// provided timeout. If the future is invalid or the callback does not come
-// within the given time, returns false.
-template <class ReturnType>
-bool waitForCallback(std::future<ReturnType> future,
- std::chrono::milliseconds timeout = kTimeoutInSeconds) {
- auto expiration = std::chrono::system_clock::now() + timeout;
- EXPECT_TRUE(future.valid());
- if (future.valid()) {
- std::future_status status = future.wait_until(expiration);
- EXPECT_NE(std::future_status::timeout, status) << "Timed out waiting for callback";
- if (status == std::future_status::ready) {
- return true;
- }
- }
- return false;
-}
-
-// Base callback implementation that just logs all callbacks by default
-class FaceCallbackBase : public IBiometricsFaceClientCallback {
+// Test callback class for the BiometricsFace HAL.
+// The HAL will call these callback methods to notify about completed operations
+// or encountered errors.
+class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase<FaceCallbackArgs>,
+ public IBiometricsFaceClientCallback {
public:
Return<void> onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override {
- ALOGD("Enroll callback called.");
- return Return<void>();
+ NotifyFromCallback(kCallbackNameOnEnrollResult);
+ return Void();
}
Return<void> onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec<uint8_t>&) override {
- ALOGD("Authenticated callback called.");
- return Return<void>();
+ NotifyFromCallback(kCallbackNameOnAuthenticated);
+ return Void();
}
Return<void> onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override {
- ALOGD("Acquired callback called.");
- return Return<void>();
+ NotifyFromCallback(kCallbackNameOnAcquired);
+ return Void();
}
- Return<void> onError(uint64_t, int32_t, FaceError, int32_t) override {
- ALOGD("Error callback called.");
- EXPECT_TRUE(false); // fail any test that triggers an error
- return Return<void>();
+ Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
+ FaceCallbackArgs args = {};
+ args.error = error;
+ NotifyFromCallback(kCallbackNameOnError, args);
+ return Void();
}
- Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
- ALOGD("Removed callback called.");
- return Return<void>();
+ Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnRemoved, args);
+ return Void();
}
- Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t /* userId */) override {
- ALOGD("Enumerate callback called.");
- return Return<void>();
+ Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
+ NotifyFromCallback(kCallbackNameOnEnumerate);
+ return Void();
}
Return<void> onLockoutChanged(uint64_t) override {
- ALOGD("LockoutChanged callback called.");
- return Return<void>();
+ NotifyFromCallback(kCallbackNameOnLockoutChanged);
+ return Void();
}
};
-class EnumerateCallback : public FaceCallbackBase {
- public:
- Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
- promise.set_value();
- return Return<void>();
- }
-
- std::promise<void> promise;
-};
-
-class ErrorCallback : public FaceCallbackBase {
- public:
- ErrorCallback(bool filterErrors = false, FaceError errorType = FaceError::HW_UNAVAILABLE)
- : filterErrors(filterErrors), errorType(errorType), hasError(false) {}
-
- Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
- if ((filterErrors && errorType == error) || !filterErrors) {
- hasError = true;
- this->error = error;
- promise.set_value();
- }
- return Return<void>();
- }
-
- bool filterErrors;
- FaceError errorType;
- bool hasError;
- FaceError error;
- std::promise<void> promise;
-};
-
-class RemoveCallback : public FaceCallbackBase {
- public:
- explicit RemoveCallback(int32_t userId) : removeUserId(userId) {}
-
- Return<void> onRemoved(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
- EXPECT_EQ(removeUserId, userId);
- promise.set_value();
- return Return<void>();
- }
-
- int32_t removeUserId;
- std::promise<void> promise;
-};
-
-class LockoutChangedCallback : public FaceCallbackBase {
- public:
- Return<void> onLockoutChanged(uint64_t duration) override {
- this->hasDuration = true;
- this->duration = duration;
- promise.set_value();
- return Return<void>();
- }
- bool hasDuration;
- uint64_t duration;
- std::promise<void> promise;
-};
-
-// Test environment for Face HIDL HAL.
+// Test environment for the BiometricsFace HAL.
class FaceHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
- // get the test environment singleton
+ // Get the test environment singleton.
static FaceHidlEnvironment* Instance() {
static FaceHidlEnvironment* instance = new FaceHidlEnvironment;
return instance;
}
void registerTestServices() override { registerTestService<IBiometricsFace>(); }
+
+ private:
+ FaceHidlEnvironment() = default;
};
+// Test class for the BiometricsFace HAL.
class FaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
void SetUp() override {
mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFace>(
FaceHidlEnvironment::Instance()->getServiceName<IBiometricsFace>());
- ASSERT_FALSE(mService == nullptr);
- Return<Status> res = mService->setActiveUser(kUserId, kTmpDir);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ ASSERT_NE(mService, nullptr);
+ mCallback = new FaceCallback();
+ mCallback->SetWaitTimeoutDefault(kTimeout);
+ Return<void> ret1 = mService->setCallback(mCallback, [](const OptionalUint64& res) {
+ ASSERT_EQ(Status::OK, res.status);
+ // Makes sure the "deviceId" represented by "res.value" is not 0.
+ // 0 would mean the HIDL is not available.
+ ASSERT_NE(0UL, res.value);
+ });
+ ASSERT_TRUE(ret1.isOk());
+ Return<Status> ret2 = mService->setActiveUser(kUserId, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret2));
}
void TearDown() override {}
sp<IBiometricsFace> mService;
+ sp<FaceCallback> mCallback;
};
-// The service should be reachable.
-TEST_F(FaceHidlTest, ConnectTest) {
- sp<FaceCallbackBase> cb = new FaceCallbackBase();
- mService->setCallback(cb, kAssertCallbackIsSet);
-}
-
-// Starting the service with null callback should succeed.
-TEST_F(FaceHidlTest, ConnectNullTest) {
- mService->setCallback(nullptr, kAssertCallbackIsSet);
-}
-
// generateChallenge should always return a unique, cryptographically secure,
// non-zero number.
TEST_F(FaceHidlTest, GenerateChallengeTest) {
std::map<uint64_t, int> m;
- for (int i = 0; i < kIterations; ++i) {
- mService->generateChallenge(kTimeout, [&m](const OptionalUint64& res) {
- ASSERT_EQ(Status::OK, res.status);
- EXPECT_NE(0UL, res.value);
- m[res.value]++;
- EXPECT_EQ(1UL, m[res.value]);
- });
+ for (int i = 0; i < kGenerateChallengeIterations; ++i) {
+ Return<void> ret =
+ mService->generateChallenge(kTimeoutSec, [&m](const OptionalUint64& res) {
+ ASSERT_EQ(Status::OK, res.status);
+ EXPECT_NE(0UL, res.value);
+ m[res.value]++;
+ EXPECT_EQ(1UL, m[res.value]);
+ });
+ ASSERT_TRUE(ret.isOk());
}
}
// enroll with an invalid (all zeroes) HAT should fail.
TEST_F(FaceHidlTest, EnrollZeroHatTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
+ // Filling HAT with zeros
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
token[i] = 0;
}
- Return<Status> res = mService->enroll(token, kTimeout, {});
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->enroll(token, kTimeoutSec, {});
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
- // At least one call to onError should occur
- ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
- ASSERT_TRUE(cb->hasError);
+ // onError should be called with a meaningful (nonzero) error.
+ auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+ EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
// enroll with an invalid HAT should fail.
TEST_F(FaceHidlTest, EnrollGarbageHatTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
- // Filling HAT with invalid data
+ // Filling HAT with pseudorandom invalid data.
+ // Using default seed to make the test reproducible.
+ std::mt19937 gen(std::mt19937::default_seed);
+ std::uniform_int_distribution<uint8_t> dist;
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; ++i) {
- token[i] = i;
+ token[i] = dist(gen);
}
- Return<Status> res = mService->enroll(token, kTimeout, {});
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->enroll(token, kTimeoutSec, {});
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
- // At least one call to onError should occur
- ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
- ASSERT_TRUE(cb->hasError);
+ // onError should be called with a meaningful (nonzero) error.
+ auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+ EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
// setFeature with an invalid (all zeros) HAT should fail.
TEST_F(FaceHidlTest, SetFeatureZeroHatTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
token[i] = 0;
}
- Return<Status> res = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(res));
+ Return<Status> ret = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(ret));
}
// setFeature with an invalid HAT should fail.
TEST_F(FaceHidlTest, SetFeatureGarbageHatTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
- // Filling HAT with invalid data
+ // Filling HAT with pseudorandom invalid data.
+ // Using default seed to make the test reproducible.
+ std::mt19937 gen(std::mt19937::default_seed);
+ std::uniform_int_distribution<uint8_t> dist;
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; ++i) {
- token[i] = i;
+ token[i] = dist(gen);
}
- Return<Status> res = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
- ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(res));
+ Return<Status> ret = mService->setFeature(Feature::REQUIRE_DIVERSITY, false, token, 0);
+ ASSERT_EQ(Status::ILLEGAL_ARGUMENT, static_cast<Status>(ret));
}
-void assertGetFeatureFails(sp<IBiometricsFace> service, int faceId, Feature feature) {
- std::promise<void> promise;
-
+void assertGetFeatureFails(const sp<IBiometricsFace>& service, uint32_t faceId, Feature feature) {
// Features cannot be retrieved for invalid faces.
- Return<void> res = service->getFeature(feature, faceId, [&promise](const OptionalBool& result) {
+ Return<void> res = service->getFeature(feature, faceId, [](const OptionalBool& result) {
ASSERT_EQ(Status::ILLEGAL_ARGUMENT, result.status);
- promise.set_value();
});
- ASSERT_TRUE(waitForCallback(promise.get_future()));
+ ASSERT_TRUE(res.isOk());
}
TEST_F(FaceHidlTest, GetFeatureRequireAttentionTest) {
@@ -317,111 +252,95 @@
// revokeChallenge should always return within the timeout
TEST_F(FaceHidlTest, RevokeChallengeTest) {
- sp<FaceCallbackBase> cb = new FaceCallbackBase();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
auto start = std::chrono::system_clock::now();
- mService->revokeChallenge();
+ Return<Status> ret = mService->revokeChallenge();
auto elapsed = std::chrono::system_clock::now() - start;
- ASSERT_GE(kTimeoutInSeconds, elapsed);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+ ASSERT_GE(kTimeout, elapsed);
}
// The call to getAuthenticatorId should succeed.
TEST_F(FaceHidlTest, GetAuthenticatorIdTest) {
- mService->getAuthenticatorId(
+ Return<void> ret = mService->getAuthenticatorId(
[](const OptionalUint64& res) { ASSERT_EQ(Status::OK, res.status); });
+ ASSERT_TRUE(ret.isOk());
}
// The call to enumerate should succeed.
TEST_F(FaceHidlTest, EnumerateTest) {
- sp<EnumerateCallback> cb = new EnumerateCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
- Return<Status> res = mService->enumerate();
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
- ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
+ Return<Status> ret = mService->enumerate();
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+ auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
+ EXPECT_TRUE(res.no_timeout);
}
// The call to remove should succeed for any faceId
TEST_F(FaceHidlTest, RemoveFaceTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
// Remove a face
- Return<Status> res = mService->remove(kFaceId);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->remove(kFaceId);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Remove should accept 0 to delete all faces
TEST_F(FaceHidlTest, RemoveAllFacesTest) {
- sp<ErrorCallback> cb = new ErrorCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
// Remove all faces
- Return<Status> res = mService->remove(0);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->remove(0);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Active user should successfully set to a writable location.
TEST_F(FaceHidlTest, SetActiveUserTest) {
// Create an active user
- Return<Status> res = mService->setActiveUser(2, kTmpDir);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->setActiveUser(2, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
// Reset active user
- res = mService->setActiveUser(kUserId, kTmpDir);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ ret = mService->setActiveUser(kUserId, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Active user should fail to set to an unwritable location.
TEST_F(FaceHidlTest, SetActiveUserUnwritableTest) {
// Create an active user to an unwritable location (device root dir)
- Return<Status> res = mService->setActiveUser(3, "/");
- ASSERT_NE(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->setActiveUser(3, "/");
+ ASSERT_NE(Status::OK, static_cast<Status>(ret));
// Reset active user
- res = mService->setActiveUser(kUserId, kTmpDir);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ ret = mService->setActiveUser(kUserId, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Active user should fail to set to a null location.
TEST_F(FaceHidlTest, SetActiveUserNullTest) {
// Create an active user to a null location.
- Return<Status> res = mService->setActiveUser(4, nullptr);
- ASSERT_NE(Status::OK, static_cast<Status>(res));
+ Return<Status> ret = mService->setActiveUser(4, nullptr);
+ ASSERT_NE(Status::OK, static_cast<Status>(ret));
// Reset active user
- res = mService->setActiveUser(kUserId, kTmpDir);
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
+ ret = mService->setActiveUser(kUserId, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Cancel should always return CANCELED from any starting state including
// the IDLE state.
TEST_F(FaceHidlTest, CancelTest) {
- sp<ErrorCallback> cb = new ErrorCallback(true, FaceError::CANCELED);
- mService->setCallback(cb, kAssertCallbackIsSet);
-
- Return<Status> res = mService->cancel();
+ Return<Status> ret = mService->cancel();
// check that we were able to make an IPC request successfully
- ASSERT_EQ(Status::OK, static_cast<Status>(res));
-
- // make sure callback was invoked within kTimeoutInSeconds
- ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
- // check error should be CANCELED
- ASSERT_EQ(FaceError::CANCELED, cb->error);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
+ auto res = mCallback->WaitForCallback(kCallbackNameOnError);
+ // make sure callback was invoked within kRevokeChallengeTimeout
+ EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(FaceError::CANCELED, res.args->error);
}
TEST_F(FaceHidlTest, OnLockoutChangedTest) {
- sp<LockoutChangedCallback> cb = new LockoutChangedCallback();
- mService->setCallback(cb, kAssertCallbackIsSet);
-
- // Update active user and ensure lockout duration 0 is received
- mService->setActiveUser(5, kTmpDir);
+ // Update active user and ensure onLockoutChanged was called.
+ Return<Status> ret = mService->setActiveUser(kUserId + 1, kFacedataDir);
+ ASSERT_EQ(Status::OK, static_cast<Status>(ret));
// Make sure callback was invoked
- ASSERT_TRUE(waitForCallback(cb->promise.get_future()));
-
- // Check that duration 0 was received
- ASSERT_EQ(0, cb->duration);
+ auto res = mCallback->WaitForCallback(kCallbackNameOnLockoutChanged);
+ EXPECT_TRUE(res.no_timeout);
}
} // anonymous namespace
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c94c825..3cbcc7b 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -607,7 +607,9 @@
struct DeviceCb : public V3_5::ICameraDeviceCallback {
DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
- mParent(parent), mDeviceVersion(deviceVersion), mStaticMetadata(staticMeta) {}
+ mParent(parent), mDeviceVersion(deviceVersion) {
+ mStaticMetadata = staticMeta;
+ }
Return<void> processCaptureResult_3_4(
const hidl_vec<V3_4::CaptureResult>& results) override;
@@ -631,7 +633,7 @@
CameraHidlTest *mParent; // Parent object
int mDeviceVersion;
- const camera_metadata_t *mStaticMetadata;
+ android::hardware::camera::common::V1_0::helper::CameraMetadata mStaticMetadata;
bool hasOutstandingBuffersLocked();
/* members for requestStreamBuffers() and returnStreamBuffers()*/
@@ -755,7 +757,8 @@
uint32_t *partialResultCount /*out*/,
bool *useHalBufManager /*out*/,
sp<DeviceCb> *cb /*out*/,
- uint32_t streamConfigCounter = 0);
+ uint32_t streamConfigCounter = 0,
+ bool allowUnsupport = false);
void configurePreviewStream(const std::string &name, int32_t deviceVersion,
sp<ICameraProvider> provider,
const AvailableStream *previewThreshold,
@@ -1193,18 +1196,20 @@
// Verify final result metadata
bool isAtLeast_3_5 = mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
if (isAtLeast_3_5) {
+ auto staticMetadataBuffer = mStaticMetadata.getAndLock();
bool isMonochrome = Status::OK ==
- CameraHidlTest::isMonochromeCamera(mStaticMetadata);
+ CameraHidlTest::isMonochromeCamera(staticMetadataBuffer);
if (isMonochrome) {
mParent->verifyMonochromeCameraResult(request->collectedResult);
}
// Verify logical camera result metadata
bool isLogicalCamera =
- Status::OK == CameraHidlTest::isLogicalMultiCamera(mStaticMetadata);
+ Status::OK == CameraHidlTest::isLogicalMultiCamera(staticMetadataBuffer);
if (isLogicalCamera) {
- mParent->verifyLogicalCameraResult(mStaticMetadata, request->collectedResult);
+ mParent->verifyLogicalCameraResult(staticMetadataBuffer, request->collectedResult);
}
+ mStaticMetadata.unlock(staticMetadataBuffer);
}
}
@@ -4055,7 +4060,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
- if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
continue;
}
std::string version, deviceId;
@@ -4127,8 +4132,11 @@
configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds,
&session3_4, &session3_5, &previewStream, &halStreamConfig /*out*/,
&supportsPartialResults /*out*/, &partialResultCount /*out*/,
- &useHalBufManager /*out*/, &cb /*out*/);
- ASSERT_NE(session3_4, nullptr);
+ &useHalBufManager /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/,
+ true /*allowUnsupport*/);
+ if (session3_5 == nullptr) {
+ continue;
+ }
std::shared_ptr<ResultMetadataQueue> resultQueue;
auto resultQueueRet =
@@ -5174,7 +5182,8 @@
uint32_t *partialResultCount /*out*/,
bool *useHalBufManager /*out*/,
sp<DeviceCb> *outCb /*out*/,
- uint32_t streamConfigCounter) {
+ uint32_t streamConfigCounter,
+ bool allowUnsupport) {
ASSERT_NE(nullptr, session3_4);
ASSERT_NE(nullptr, session3_5);
ASSERT_NE(nullptr, halStreamConfig);
@@ -5273,6 +5282,28 @@
});
ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
+ if (allowUnsupport) {
+ sp<device::V3_5::ICameraDevice> cameraDevice3_5;
+ castDevice(device3_x, deviceVersion, &cameraDevice3_5);
+
+ bool supported = false;
+ ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
+ [&supported](Status s, bool combStatus) {
+ ASSERT_TRUE((Status::OK == s) ||
+ (Status::METHOD_NOT_SUPPORTED == s));
+ if (Status::OK == s) {
+ supported = combStatus;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ // If stream combination is not supported, return null session.
+ if (!supported) {
+ *session3_5 = nullptr;
+ return;
+ }
+ }
+
if (*session3_5 != nullptr) {
config3_5.v3_4 = config3_4;
config3_5.streamConfigCounter = streamConfigCounter;
@@ -5375,7 +5406,7 @@
ASSERT_EQ(Status::OK, s);
staticMeta = clone_camera_metadata(
reinterpret_cast<const camera_metadata_t*>(metadata.data()));
- ASSERT_NE(nullptr, staticMeta);
+ ASSERT_NE(nullptr, staticMeta);
});
ASSERT_TRUE(ret.isOk());
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 7d6fc60..01ec172 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -354,6 +354,10 @@
<instance>slot2</instance>
<instance>slot3</instance>
</interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio</name>
+ <version>1.2</version>
<interface>
<name>ISap</name>
<instance>slot1</instance>
@@ -361,7 +365,13 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio.config</name>
- <version>1.2</version>
+ <!--
+ Note: Devices launching with target-level 4, if implementing the
+ radio config HAL, must provide an implementation of 1.1 IRadioConfig
+ that can handle version 1.2 of IRadioConfigResponse and
+ IRadioConfigIndication.
+ -->
+ <version>1.1</version>
<interface>
<name>IRadioConfig</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 59af5d0..6e1bc8f 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -354,6 +354,10 @@
<instance>slot2</instance>
<instance>slot3</instance>
</interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio</name>
+ <version>1.2</version>
<interface>
<name>ISap</name>
<instance>slot1</instance>
@@ -361,7 +365,10 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio.config</name>
- <version>1.2</version>
+ <!--
+ See compatibility_matrix.4.xml on versioning of radio config HAL.
+ -->
+ <version>1.1</version>
<interface>
<name>IRadioConfig</name>
<instance>default</instance>
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp
index 381ac1d..f3b376e 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp
@@ -16,10 +16,16 @@
#define LOG_TAG "GnssHalTest"
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+
#include <gnss_hal_test.h>
#include <chrono>
#include "Utils.h"
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
using ::android::hardware::gnss::common::Utils;
// Implementations for the main test class for GNSS HAL
@@ -149,6 +155,28 @@
}
}
+bool GnssHalTest::IsGnssHalVersion_1_1() const {
+ using ::android::hidl::manager::V1_2::IServiceManager;
+ sp<IServiceManager> manager = ::android::hardware::defaultServiceManager1_2();
+
+ bool hasGnssHalVersion_1_1 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@1.1::IGnss",
+ [&hasGnssHalVersion_1_1](const hidl_vec<hidl_string>& registered) {
+ ASSERT_EQ(1, registered.size());
+ hasGnssHalVersion_1_1 = true;
+ });
+
+ bool hasGnssHalVersion_2_0 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@2.0::IGnss",
+ [&hasGnssHalVersion_2_0](const hidl_vec<hidl_string>& registered) {
+ hasGnssHalVersion_2_0 = registered.size() != 0;
+ });
+
+ return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0;
+}
+
void GnssHalTest::notify() {
std::unique_lock<std::mutex> lock(mtx_);
notify_count_++;
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h
index 64478b5..84a9f84 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.h
+++ b/gnss/1.1/vts/functional/gnss_hal_test.h
@@ -145,6 +145,12 @@
*/
void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+ /*
+ * IsGnssHalVersion_1_1:
+ * returns true if the GNSS HAL version is exactly 1.1.
+ */
+ bool IsGnssHalVersion_1_1() const;
+
sp<IGnss> gnss_hal_; // GNSS HAL to call into
sp<IGnssCallback> gnss_cb_; // Primary callback interface
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 2d901f3..4288d0d 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -202,6 +202,11 @@
* formerly strongest satellite
*/
TEST_F(GnssHalTest, BlacklistIndividualSatellites) {
+ if (!IsGnssHalVersion_1_1()) {
+ ALOGI("Test BlacklistIndividualSatellites skipped. GNSS HAL version is greater than 1.1.");
+ return;
+ }
+
const int kLocationsToAwait = 3;
const int kRetriesToUnBlacklist = 10;
@@ -323,6 +328,11 @@
* 4a & b) Clean up by turning off location, and send in empty blacklist.
*/
TEST_F(GnssHalTest, BlacklistConstellation) {
+ if (!IsGnssHalVersion_1_1()) {
+ ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
+ return;
+ }
+
const int kLocationsToAwait = 3;
StartAndCheckLocations(kLocationsToAwait);
diff --git a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
index a8e40ba..ae36c50 100644
--- a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
+++ b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
@@ -23,7 +23,6 @@
::testing::AddGlobalTestEnvironment(GnssHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
GnssHidlEnvironment::Instance()->init(&argc, argv);
- // TODO (b/122463165): Expand coverage to include 1.1 and 1.0 VTS tests.
int status = RUN_ALL_TESTS();
ALOGI("Test result = %d", status);
return status;
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index a9f858c..14ae43c 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -152,7 +152,7 @@
name_cbq_("name"),
capabilities_cbq_("capabilities"),
location_cbq_("location"),
- sv_info_cbq_("sv_info") {}
+ sv_info_list_cbq_("sv_info") {}
Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
const IGnssCallback_1_0::GnssSystemInfo& info) {
@@ -204,7 +204,7 @@
Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb_2_0(
const hidl_vec<IGnssCallback_2_0::GnssSvInfo>& svInfoList) {
ALOGI("gnssSvStatusCb_2_0. Size = %d", (int)svInfoList.size());
- sv_info_cbq_.store(svInfoList);
+ sv_info_list_cbq_.store(svInfoList);
return Void();
}
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 05e37d3..90a7866 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -23,6 +23,7 @@
#include <condition_variable>
#include <deque>
+#include <list>
#include <mutex>
using android::hardware::hidl_vec;
@@ -85,6 +86,14 @@
*/
bool retrieve(T& event, int timeout_seconds);
+ /*
+ * Removes parameter count number of callack events at the front of the queue, stores
+ * them in event_list parameter and returns the number of events retrieved. Waits up to
+ * timeout_seconds to retrieve each event. If timeout occurs, it returns the number of
+ * items retrieved which will be less than count.
+ */
+ int retrieve(list<T>& event_list, int count, int timeout_seconds);
+
/* Returns the number of events pending to be retrieved from the callback event queue. */
int size() const;
@@ -117,7 +126,7 @@
CallbackQueue<android::hardware::hidl_string> name_cbq_;
CallbackQueue<uint32_t> capabilities_cbq_;
CallbackQueue<GnssLocation_2_0> location_cbq_;
- CallbackQueue<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> sv_info_cbq_;
+ CallbackQueue<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> sv_info_list_cbq_;
GnssCallback();
virtual ~GnssCallback() = default;
@@ -265,6 +274,19 @@
}
template <class T>
+int GnssHalTest::CallbackQueue<T>::retrieve(list<T>& event_list, int count, int timeout_seconds) {
+ for (int i = 0; i < count; ++i) {
+ T event;
+ if (!retrieve(event, timeout_seconds)) {
+ return i;
+ }
+ event_list.push_back(event);
+ }
+
+ return count;
+}
+
+template <class T>
int GnssHalTest::CallbackQueue<T>::size() const {
std::unique_lock<std::recursive_mutex> lock(mtx_);
return events_.size();
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index 155afd6..6e0887f 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -23,7 +23,10 @@
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
+using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
+using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
+using IGnssConfiguration_1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
@@ -33,15 +36,12 @@
using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
-using IGnssBatching_V1_0 = android::hardware::gnss::V1_0::IGnssBatching;
-using IGnssBatching_V2_0 = android::hardware::gnss::V2_0::IGnssBatching;
using android::hardware::gnss::common::Utils;
using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
using android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
using android::hardware::gnss::V1_0::IGnssNi;
using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
-using android::hardware::gnss::V2_0::GnssConstellationType;
using android::hardware::gnss::V2_0::IGnssCallback;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
@@ -209,9 +209,9 @@
// Verify ConstellationType is valid.
ASSERT_TRUE(static_cast<uint8_t>(measurement.constellation) >=
- static_cast<uint8_t>(GnssConstellationType::UNKNOWN) &&
+ static_cast<uint8_t>(GnssConstellationType_2_0::UNKNOWN) &&
static_cast<uint8_t>(measurement.constellation) <=
- static_cast<uint8_t>(GnssConstellationType::IRNSS));
+ static_cast<uint8_t>(GnssConstellationType_2_0::IRNSS));
// Verify State is valid.
ASSERT_TRUE(
@@ -414,3 +414,356 @@
auto gnssBatching_2_0 = gnss_hal_->getExtensionGnssBatching_2_0();
ASSERT_TRUE(gnssBatching_2_0.isOk());
}
+
+/*
+ * MapConstellationType:
+ * Given a GnssConstellationType_2_0 type constellation, maps to its equivalent
+ * GnssConstellationType_1_0 type constellation. For constellations that do not have
+ * an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
+ */
+GnssConstellationType_1_0 MapConstellationType(GnssConstellationType_2_0 constellation) {
+ switch (constellation) {
+ case GnssConstellationType_2_0::GPS:
+ return GnssConstellationType_1_0::GPS;
+ case GnssConstellationType_2_0::SBAS:
+ return GnssConstellationType_1_0::SBAS;
+ case GnssConstellationType_2_0::GLONASS:
+ return GnssConstellationType_1_0::GLONASS;
+ case GnssConstellationType_2_0::QZSS:
+ return GnssConstellationType_1_0::QZSS;
+ case GnssConstellationType_2_0::BEIDOU:
+ return GnssConstellationType_1_0::BEIDOU;
+ case GnssConstellationType_2_0::GALILEO:
+ return GnssConstellationType_1_0::GALILEO;
+ default:
+ return GnssConstellationType_1_0::UNKNOWN;
+ }
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+IGnssConfiguration_1_1::BlacklistedSource FindStrongFrequentNonGpsSource(
+ const list<hidl_vec<IGnssCallback_2_0::GnssSvInfo>>& sv_info_lists,
+ const int min_observations) {
+ struct ComparableBlacklistedSource {
+ IGnssConfiguration_1_1::BlacklistedSource id;
+
+ ComparableBlacklistedSource() {
+ id.constellation = GnssConstellationType_1_0::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlacklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
+ std::map<ComparableBlacklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_list : sv_info_lists) {
+ for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
+ if ((sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (sv_info.constellation != GnssConstellationType_2_0::IRNSS) &&
+ (sv_info.constellation != GnssConstellationType_2_0::GPS)) {
+ ComparableBlacklistedSource source;
+ source.id.svid = sv_info.v1_0.svid;
+ source.id.constellation = MapConstellationType(sv_info.constellation);
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = sv_info.v1_0.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlacklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < sv_info.v1_0.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = sv_info.v1_0.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blacklisted_source_count_observation = 0;
+
+ ComparableBlacklistedSource source_to_blacklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blacklist = pairSignal.first;
+ blacklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blacklist.id.svid,
+ (int)source_to_blacklist.id.constellation, blacklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blacklist.id;
+}
+
+/*
+ * BlacklistIndividualSatellites:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for common satellites (strongest and one other.)
+ * 2a & b) Turns off location, and blacklists common satellites.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use those satellites.
+ * 4a & b) Turns off location, and send in empty blacklist.
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
+ */
+TEST_F(GnssHalTest, BlacklistIndividualSatellites) {
+ if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ const int kRetriesToUnBlacklist = 10;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ /*
+ * Identify strongest SV seen at least kLocationsToAwait -1 times
+ * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
+ * observability (one epoch RF null)
+ */
+
+ const int kGnssSvStatusTimeout = 2;
+ list<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> sv_info_lists;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, sv_info_list_cbq_size,
+ kGnssSvStatusTimeout);
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+
+ IGnssConfiguration_1_1::BlacklistedSource source_to_blacklist =
+ FindStrongFrequentNonGpsSource(sv_info_lists, kLocationsToAwait - 1);
+
+ if (source_to_blacklist.constellation == GnssConstellationType_1_0::UNKNOWN) {
+ // Cannot find a non-GPS satellite. Let the test pass.
+ return;
+ }
+
+ // Stop locations, blacklist the common SV
+ StopAndClearLocations();
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration_1_1> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration_1_1::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ auto result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure satellite not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
+ for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
+ auto constellation = MapConstellationType(sv_info.constellation);
+ EXPECT_FALSE((sv_info.v1_0.svid == source_to_blacklist.svid) &&
+ (constellation == source_to_blacklist.constellation) &&
+ (sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clear blacklist and restart - this time updating the blacklist while location is still on
+ sources.resize(0);
+
+ result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ bool strongest_sv_is_reobserved = false;
+ // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+ int unblacklist_loops_remaining = kRetriesToUnBlacklist;
+ while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
+ StopAndClearLocations();
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit loop if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Clear blacklist, observed %d GnssSvStatus, while awaiting %d Locations"
+ ", tries remaining %d",
+ sv_info_list_cbq_size, kLocationsToAwait, unblacklist_loops_remaining);
+
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
+ for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
+ auto constellation = MapConstellationType(sv_info.constellation);
+ if ((sv_info.v1_0.svid == source_to_blacklist.svid) &&
+ (constellation == source_to_blacklist.constellation) &&
+ (sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ if (strongest_sv_is_reobserved) break;
+ }
+ }
+ EXPECT_TRUE(strongest_sv_is_reobserved);
+ StopAndClearLocations();
+}
+
+/*
+ * BlacklistConstellation:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_F(GnssHalTest, BlacklistConstellation) {
+ if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ const int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ // Find first non-GPS constellation to blacklist. Exclude IRNSS in GnssConstellationType_2_0
+ // as blacklisting of this constellation is not supported in gnss@2.0.
+ const int kGnssSvStatusTimeout = 2;
+ GnssConstellationType_1_0 constellation_to_blacklist = GnssConstellationType_1_0::UNKNOWN;
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
+ for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
+ if ((sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (sv_info.constellation != GnssConstellationType_2_0::UNKNOWN) &&
+ (sv_info.constellation != GnssConstellationType_2_0::IRNSS) &&
+ (sv_info.constellation != GnssConstellationType_2_0::GPS)) {
+ // found a non-GPS V1_0 constellation
+ constellation_to_blacklist = MapConstellationType(sv_info.constellation);
+ break;
+ }
+ }
+ if (constellation_to_blacklist != GnssConstellationType_1_0::UNKNOWN) {
+ break;
+ }
+ }
+
+ if (constellation_to_blacklist == GnssConstellationType_1_0::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+ // Proceed functionally to blacklist something.
+ constellation_to_blacklist = GnssConstellationType_1_0::GLONASS;
+ }
+ IGnssConfiguration_1_1::BlacklistedSource source_to_blacklist;
+ source_to_blacklist.constellation = constellation_to_blacklist;
+ source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration_1_1> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration_1_1::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ auto result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_0::GnssSvInfo> sv_info_list;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_list, kGnssSvStatusTimeout);
+ for (IGnssCallback_2_0::GnssSvInfo sv_info : sv_info_list) {
+ auto constellation = MapConstellationType(sv_info.constellation);
+ EXPECT_FALSE((constellation == source_to_blacklist.constellation) &&
+ (sv_info.v1_0.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
\ No newline at end of file
diff --git a/graphics/composer/2.1/utils/vts/Android.bp b/graphics/composer/2.1/utils/vts/Android.bp
index fcb327f..88b1a8b 100644
--- a/graphics/composer/2.1/utils/vts/Android.bp
+++ b/graphics/composer/2.1/utils/vts/Android.bp
@@ -28,9 +28,18 @@
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@3.0-vts",
],
+ export_static_lib_headers: [
+ "VtsHalHidlTargetTestBase",
+ "android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.mapper@2.0-vts",
+ "android.hardware.graphics.mapper@3.0-vts",
+ ],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
],
+ export_header_lib_headers: [
+ "android.hardware.graphics.composer@2.1-command-buffer",
+ ],
cflags: [
"-O0",
"-g",
diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS
index a17a50c..3f1e82c 100644
--- a/graphics/composer/2.2/utils/OWNERS
+++ b/graphics/composer/2.2/utils/OWNERS
@@ -3,7 +3,3 @@
lpy@google.com
stoza@google.com
vhau@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
diff --git a/graphics/composer/2.2/utils/command-buffer/Android.bp b/graphics/composer/2.2/utils/command-buffer/Android.bp
index efaabd4..c4ceaab 100644
--- a/graphics/composer/2.2/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.2/utils/command-buffer/Android.bp
@@ -3,11 +3,16 @@
defaults: ["hidl_defaults"],
vendor_available: true,
shared_libs: [
- "android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
+ ],
+ export_shared_lib_headers: [
"android.hardware.graphics.composer@2.2",
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
],
+ export_header_lib_headers: [
+ "android.hardware.graphics.composer@2.1-command-buffer",
+ ],
export_include_dirs: ["include"],
}
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 56b12f5..1754a43 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -20,26 +20,31 @@
srcs: [
"ComposerVts.cpp",
"ReadbackVts.cpp",
+ "RenderEngineVts.cpp",
+ ],
+ shared_libs: [
+ "libui",
],
static_libs: [
"VtsHalHidlTargetTestBase",
- "android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.1-vts",
"android.hardware.graphics.composer@2.2",
- "android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@2.1-vts",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@3.0-vts",
+ "libarect",
+ "libmath",
+ "libnativewindow",
+ "librenderengine",
],
export_static_lib_headers: [
+ "VtsHalHidlTargetTestBase",
"android.hardware.graphics.composer@2.1-vts",
+ "android.hardware.graphics.composer@2.2",
+ "android.hardware.graphics.mapper@2.1-vts",
],
header_libs: [
- "android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
export_header_lib_headers: [
- "android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
cflags: [
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index 81a6452..91efc6f 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -34,6 +34,53 @@
writer->setLayerBlendMode(mBlendMode);
}
+const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
+const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
+ Dataspace::DISPLAY_P3};
+
+std::string ReadbackHelper::getColorModeString(ColorMode mode) {
+ switch (mode) {
+ case ColorMode::SRGB:
+ return std::string("SRGB");
+ case ColorMode::DISPLAY_P3:
+ return std::string("DISPLAY_P3");
+ default:
+ return std::string("Unsupported color mode for readback");
+ }
+}
+
+std::string ReadbackHelper::getDataspaceString(Dataspace dataspace) {
+ switch (dataspace) {
+ case Dataspace::V0_SRGB:
+ return std::string("V0_SRGB");
+ case Dataspace::DISPLAY_P3:
+ return std::string("DISPLAY_P3");
+ default:
+ return std::string("Unsupported dataspace for readback");
+ }
+}
+
+LayerSettings TestLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings;
+
+ layerSettings.alpha = half(mAlpha);
+ layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
+ layerSettings.geometry.boundaries = FloatRect(
+ static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
+ static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
+
+ const mat4 translation = mat4::translate(vec4(
+ (mTransform & Transform::FLIP_H ? -1.0f : 0.0f) * mDisplayFrame.right,
+ (mTransform & Transform::FLIP_V ? -1.0f : 0.0f) * mDisplayFrame.bottom, 0.0f, 1.0f));
+
+ const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
+ mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));
+
+ layerSettings.geometry.positionTransform = translation * scale;
+
+ return layerSettings;
+}
+
int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
switch (pixelFormat) {
case PixelFormat::RGBA_8888:
@@ -99,12 +146,31 @@
if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
return false;
}
- if (dataspace != Dataspace::V0_SRGB) {
+ if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
return false;
}
return true;
}
+void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
+ void* bufferData, const uint32_t stride,
+ const uint32_t width, const uint32_t height,
+ const PixelFormat pixelFormat) {
+ const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+ ASSERT_NE(-1, bytesPerPixel);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ int pixel = row * width + col;
+ int offset = (row * stride + col) * bytesPerPixel;
+ uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+
+ ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
+ ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
+ ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+ }
+ }
+}
+
ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
@@ -153,19 +219,8 @@
void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
- int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(mPixelFormat);
- ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < mHeight; row++) {
- for (int col = 0; col < mWidth; col++) {
- int pixel = row * mWidth + col;
- int offset = (row * mStride + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufData + offset;
-
- ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
- ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
- ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
- }
- }
+ ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
+ mPixelFormat);
int32_t unlockFence = mGralloc->unlock(mBufferHandle);
if (unlockFence != -1) {
sync_wait(unlockFence, -1);
@@ -179,6 +234,16 @@
writer->setLayerColor(mColor);
}
+LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+
+ layerSettings.source.solidColor =
+ half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
+ static_cast<half>(mColor.b) / 255.0);
+ layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
+ return layerSettings;
+}
+
TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
const std::shared_ptr<Gralloc>& gralloc, Display display,
int32_t width, int32_t height, PixelFormat format,
@@ -215,6 +280,27 @@
if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
}
+LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+ layerSettings.source.buffer.buffer =
+ new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
+ static_cast<int32_t>(mFormat), 1, mUsage, mStride);
+ // TODO(b/136483187): Why does this break the premultiply test
+ // layerSettings.source.buffer.usePremultipliedAlpha =
+ // mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
+
+ const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
+ const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
+ const float translateX = mSourceCrop.left / (mWidth);
+ const float translateY = mSourceCrop.top / (mHeight);
+
+ layerSettings.source.buffer.textureTransform =
+ mat4::translate(vec4(translateX, translateY, 0, 1)) *
+ mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));
+
+ return layerSettings;
+}
+
void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
ASSERT_NO_FATAL_FAILURE(
@@ -225,6 +311,7 @@
close(mFillFence);
}
}
+
void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
if (mBufferHandle != nullptr) {
mGralloc->freeBuffer(mBufferHandle);
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
new file mode 100644
index 0000000..d910169
--- /dev/null
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <composer-vts/2.2/RenderEngineVts.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace vts {
+
+using mapper::V2_1::IMapper;
+using renderengine::DisplaySettings;
+using renderengine::LayerSettings;
+
+TestRenderEngine::TestRenderEngine(common::V1_1::PixelFormat hwcFormat,
+ uint32_t renderEngineFeatures) {
+ mFormat = hwcFormat;
+ mRenderEngine = renderengine::RenderEngine::create(
+ static_cast<int32_t>(mFormat), renderEngineFeatures, mMaxFrameBufferAcquireBuffers);
+}
+
+void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
+ sort(layers.begin(), layers.end(),
+ [](const std::shared_ptr<TestLayer>& lhs, const std::shared_ptr<TestLayer>& rhs) -> bool {
+ return lhs->mZOrder < rhs->mZOrder;
+ });
+
+ if (!mCompositionLayers.empty()) {
+ mCompositionLayers.clear();
+ }
+ for (auto& layer : layers) {
+ LayerSettings settings = layer->toRenderEngineLayerSettings();
+ mCompositionLayers.push_back(settings);
+ }
+}
+
+void TestRenderEngine::initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
+ uint64_t usage) {
+ mGraphicBuffer =
+ new GraphicBuffer(width, height, static_cast<int32_t>(mFormat), layerCount, usage);
+}
+
+void TestRenderEngine::drawLayers() {
+ base::unique_fd bufferFence;
+ base::unique_fd readyFence;
+ mRenderEngine->drawLayers(mDisplaySettings, mCompositionLayers,
+ mGraphicBuffer->getNativeBuffer(), true, std::move(bufferFence),
+ &readyFence);
+ int fd = readyFence.release();
+ if (fd != -1) {
+ ASSERT_EQ(0, sync_wait(fd, -1));
+ ASSERT_EQ(0, close(fd));
+ }
+}
+
+void TestRenderEngine::checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors) {
+ void* bufferData;
+ ASSERT_EQ(0, mGraphicBuffer->lock(mGraphicBuffer->getUsage(), &bufferData));
+ ReadbackHelper::compareColorBuffers(expectedColors, bufferData, mGraphicBuffer->getStride(),
+ mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
+ mFormat);
+ ASSERT_EQ(0, mGraphicBuffer->unlock());
+}
+
+} // namespace vts
+} // namespace V2_2
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
index 7e93167..5304cd4 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
@@ -21,6 +23,7 @@
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
#include <mapper-vts/2.1/MapperVts.h>
+#include <renderengine/RenderEngine.h>
namespace android {
namespace hardware {
@@ -35,6 +38,7 @@
using common::V1_1::PixelFormat;
using IMapper2_1 = mapper::V2_1::IMapper;
using Gralloc2_1 = mapper::V2_1::vts::Gralloc;
+using renderengine::LayerSettings;
using V2_1::Display;
using V2_1::Layer;
using V2_1::vts::AccessRegion;
@@ -56,6 +60,7 @@
virtual ~TestLayer(){};
virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
+ virtual LayerSettings toRenderEngineLayerSettings();
void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
void setSourceCrop(IComposerClient::FRect crop) { mSourceCrop = crop; }
@@ -93,6 +98,8 @@
void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+ LayerSettings toRenderEngineLayerSettings() override;
+
void setColor(IComposerClient::Color color) { mColor = color; }
private:
@@ -110,6 +117,8 @@
void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+ LayerSettings toRenderEngineLayerSettings() override;
+
void fillBuffer(std::vector<IComposerClient::Color> expectedColors);
void setBuffer(std::vector<IComposerClient::Color> colors);
@@ -133,6 +142,10 @@
class ReadbackHelper : public ::testing::VtsHalHidlTargetTestBase {
public:
+ static std::string getColorModeString(ColorMode mode);
+
+ static std::string getDataspaceString(Dataspace dataspace);
+
static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
@@ -147,6 +160,13 @@
static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
const Error error);
+
+ static const std::vector<ColorMode> colorModes;
+ static const std::vector<Dataspace> dataspaces;
+
+ static void compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
+ void* bufferData, const uint32_t stride, const uint32_t width,
+ const uint32_t height, const PixelFormat pixelFormat);
};
class ReadbackBuffer {
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
new file mode 100644
index 0000000..0ac5a22
--- /dev/null
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <composer-vts/2.2/ReadbackVts.h>
+#include <math/half.h>
+#include <math/vec3.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace vts {
+
+using mapper::V2_1::IMapper;
+using renderengine::DisplaySettings;
+using vts::Gralloc;
+
+class TestRenderEngine {
+ public:
+ TestRenderEngine(common::V1_1::PixelFormat hwcFormat, uint32_t renderEngineFeatures);
+ ~TestRenderEngine() = default;
+
+ void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
+ void initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint64_t usage);
+ void setDisplaySettings(DisplaySettings& displaySettings) {
+ mDisplaySettings = displaySettings;
+ };
+ void drawLayers();
+ void checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors);
+
+ private:
+ static constexpr uint32_t mMaxFrameBufferAcquireBuffers = 2;
+ common::V1_1::PixelFormat mFormat;
+ std::vector<renderengine::LayerSettings> mCompositionLayers;
+ std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
+ std::vector<renderengine::LayerSettings> mRenderLayers;
+ sp<GraphicBuffer> mGraphicBuffer;
+ DisplaySettings mDisplaySettings;
+};
+
+} // namespace vts
+} // namespace V2_2
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 9f7e1cd..cc24774 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -20,6 +20,7 @@
srcs: [
"VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
"VtsHalGraphicsComposerV2_2TargetTest.cpp",
+ "VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp",
],
// TODO(b/64437680): Assume these libs are always available on the device.
@@ -27,9 +28,19 @@
"libfmq",
"libhidlbase",
"libhidltransport",
+ "libhwbinder",
"libsync",
+ "libui",
+ "libgui",
+ "libEGL",
+ "libGLESv1_CM",
+ "libGLESv2",
],
static_libs: [
+ "librenderengine",
+ "libmath",
+ "libarect",
+ "libnativewindow",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.1",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp
new file mode 100644
index 0000000..d694a5b
--- /dev/null
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2019 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 "graphics_composer_hidl_hal_readback_tests@2.2"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <composer-vts/2.1/GraphicsComposerCallback.h>
+#include <composer-vts/2.1/TestCommandReader.h>
+#include <composer-vts/2.2/ComposerVts.h>
+#include <composer-vts/2.2/ReadbackVts.h>
+#include <composer-vts/2.2/RenderEngineVts.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace vts {
+namespace {
+
+using android::GraphicBuffer;
+using android::Rect;
+using android::hardware::hidl_handle;
+using common::V1_1::BufferUsage;
+using common::V1_1::Dataspace;
+using common::V1_1::PixelFormat;
+using mapper::V2_1::IMapper;
+using V2_1::Config;
+using V2_1::Display;
+using V2_1::vts::TestCommandReader;
+using vts::Gralloc;
+
+// Test environment for graphics.composer
+class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static GraphicsComposerHidlEnvironment* Instance() {
+ static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
+ return instance;
+ }
+ virtual void registerTestServices() override { registerTestService<IComposer>(); }
+
+ private:
+ GraphicsComposerHidlEnvironment() {}
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
+};
+
+class GraphicsCompositionComparisonTest : public ::testing::VtsHalHidlTargetTestBase {
+ protected:
+ using PowerMode = V2_1::IComposerClient::PowerMode;
+ void SetUp() override {
+ VtsHalHidlTargetTestBase::SetUp();
+ ASSERT_NO_FATAL_FAILURE(
+ mComposer = std::make_unique<Composer>(
+ GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
+ mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
+ mComposerClient->registerCallback(mComposerCallback);
+
+ // assume the first display is primary and is never removed
+ mPrimaryDisplay = waitForFirstDisplay();
+ Config activeConfig;
+ ASSERT_NO_FATAL_FAILURE(activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay));
+ ASSERT_NO_FATAL_FAILURE(
+ mDisplayWidth = mComposerClient->getDisplayAttribute(
+ mPrimaryDisplay, activeConfig, IComposerClient::Attribute::WIDTH));
+ ASSERT_NO_FATAL_FAILURE(
+ mDisplayHeight = mComposerClient->getDisplayAttribute(
+ mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT));
+
+ setTestColorModes();
+
+ // explicitly disable vsync
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false));
+ mComposerCallback->setVsyncAllowed(false);
+
+ // set up command writer/reader and gralloc
+ mWriter = std::make_shared<CommandWriterBase>(1024);
+ mReader = std::make_unique<TestCommandReader>();
+ mGralloc = std::make_shared<Gralloc>();
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+
+ ASSERT_NO_FATAL_FAILURE(
+ mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
+ PixelFormat::RGBA_8888,
+ renderengine::RenderEngine::USE_COLOR_MANAGEMENT |
+ renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT)));
+
+ renderengine::DisplaySettings clientCompositionDisplay;
+ clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
+ clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
+ clientCompositionDisplay.clearRegion = Region(clientCompositionDisplay.physicalDisplay);
+
+ mTestRenderEngine->initGraphicBuffer(
+ static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
+ static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN));
+ mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+ EXPECT_EQ(0, mReader->mErrors.size());
+ EXPECT_EQ(0, mReader->mCompositionChanges.size());
+ if (mComposerCallback != nullptr) {
+ EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+ }
+ VtsHalHidlTargetTestBase::TearDown();
+ }
+
+ void clearCommandReaderState() {
+ mReader->mCompositionChanges.clear();
+ mReader->mErrors.clear();
+ }
+
+ void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+ for (auto layer : layers) {
+ layer->write(mWriter);
+ }
+ execute();
+ }
+
+ void execute() {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
+ }
+
+ std::unique_ptr<Composer> mComposer;
+ std::shared_ptr<ComposerClient> mComposerClient;
+
+ sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
+ // the first display and is assumed never to be removed
+ Display mPrimaryDisplay;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+ std::vector<ColorMode> mTestColorModes;
+ std::shared_ptr<CommandWriterBase> mWriter;
+ std::unique_ptr<TestCommandReader> mReader;
+ std::shared_ptr<Gralloc> mGralloc;
+ std::unique_ptr<TestRenderEngine> mTestRenderEngine;
+
+ bool mHasReadbackBuffer;
+ PixelFormat mPixelFormat;
+ Dataspace mDataspace;
+
+ private:
+ Display waitForFirstDisplay() {
+ while (true) {
+ std::vector<Display> displays = mComposerCallback->getDisplays();
+ if (displays.empty()) {
+ usleep(5 * 1000);
+ continue;
+ }
+ return displays[0];
+ }
+ }
+
+ void setTestColorModes() {
+ mTestColorModes.clear();
+ mComposerClient->getRaw()->getColorModes_2_2(mPrimaryDisplay, [&](const auto& tmpError,
+ const auto& tmpModes) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ for (ColorMode mode : tmpModes) {
+ if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
+ mode) != ReadbackHelper::colorModes.end()) {
+ mTestColorModes.push_back(mode);
+ }
+ }
+ });
+ }
+};
+
+TEST_F(GraphicsCompositionComparisonTest, SingleSolidColorLayer) {
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // expected color for each pixel
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ // if hwc cannot handle and asks for composition change,
+ // just succeed the test
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+} // namespace
+} // namespace vts
+} // namespace V2_2
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index eef0433..72c9496 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -78,6 +78,8 @@
mDisplayHeight = mComposerClient->getDisplayAttribute(
mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT));
+ setTestColorModes();
+
// explicitly disable vsync
ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false));
mComposerCallback->setVsyncAllowed(false);
@@ -87,14 +89,6 @@
mReader = std::make_unique<TestCommandReader>();
mGralloc = std::make_shared<Gralloc>();
- mComposerClient->getRaw()->getReadbackBufferAttributes(
- mPrimaryDisplay,
- [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
- mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
- tmpDataspace, tmpError);
- mPixelFormat = tmpPixelFormat;
- mDataspace = tmpDataspace;
- });
ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
}
@@ -134,6 +128,7 @@
Display mPrimaryDisplay;
int32_t mDisplayWidth;
int32_t mDisplayHeight;
+ std::vector<ColorMode> mTestColorModes;
std::shared_ptr<CommandWriterBase> mWriter;
std::unique_ptr<TestCommandReader> mReader;
std::shared_ptr<Gralloc> mGralloc;
@@ -155,190 +150,373 @@
return displays[0];
}
}
+
+ void setTestColorModes() {
+ mTestColorModes.clear();
+ mComposerClient->getRaw()->getColorModes_2_2(mPrimaryDisplay, [&](const auto& tmpError,
+ const auto& tmpModes) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ for (ColorMode mode : tmpModes) {
+ if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
+ mode) != ReadbackHelper::colorModes.end()) {
+ mTestColorModes.push_back(mode);
+ }
+ }
+ });
+ }
};
TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // expected color for each pixel
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ // if hwc cannot handle and asks for composition change,
+ // just succeed the test
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
- mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
- RenderIntent::COLORIMETRIC));
-
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
- IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setColor(BLUE);
- layer->setDisplayFrame(coloredSquare);
- layer->setZOrder(10);
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- // expected color for each pixel
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- // if hwc cannot handle and asks for composition change,
- // just succeed the test
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerBuffer) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+ GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+ mDisplayWidth, mDisplayHeight,
+ PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
- GREEN);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
-
- auto layer =
- std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
- mDisplayHeight, PixelFormat::RGBA_8888);
- layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setZOrder(10);
- ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
-
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
-
- mWriter->presentDisplay();
- execute();
-
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerBufferNoEffect) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+ layer->write(mWriter);
+
+ // This following buffer call should have no effect
+ uint64_t usage =
+ static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
+ const native_handle_t* bufferHandle =
+ mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage);
+ mWriter->setLayerBuffer(0, bufferHandle, -1);
+
+ // expected color for each pixel
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
- RenderIntent::COLORIMETRIC));
-
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
- IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setColor(BLUE);
- layer->setDisplayFrame(coloredSquare);
- layer->setZOrder(10);
- layer->write(mWriter);
-
- // This following buffer call should have no effect
- PixelFormat format = PixelFormat::RGBA_8888;
- uint64_t usage =
- static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
- const native_handle_t* bufferHandle =
- mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, format, usage);
- mWriter->setLayerBuffer(0, bufferHandle, -1);
-
- // expected color for each pixel
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- mWriter->validateDisplay();
- execute();
-
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, ClientComposition) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
- }
-
- mWriter->selectDisplay(mPrimaryDisplay);
-
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
- GREEN);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
-
- auto layer =
- std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
- mDisplayHeight, PixelFormat::RGBA_FP16);
- layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setZOrder(10);
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
-
- if (mReader->mCompositionChanges.size() != 0) {
- ASSERT_EQ(1, mReader->mCompositionChanges.size());
- ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
-
- ASSERT_NO_FATAL_FAILURE(
+ ASSERT_NO_FATAL_FAILURE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+ GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+ mDisplayWidth, mDisplayHeight,
+ PixelFormat::RGBA_FP16);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 0) {
+ ASSERT_EQ(1, mReader->mCompositionChanges.size());
+ ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+
+ // create client target buffer
+ uint32_t clientStride;
+ PixelFormat clientFormat = PixelFormat::RGBA_8888;
+ uint64_t clientUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN |
+ BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::COMPOSER_CLIENT_TARGET);
+ const native_handle_t* clientBufferHandle =
+ mGralloc->allocate(layer->mWidth, layer->mHeight, layer->mLayerCount,
+ clientFormat, clientUsage, /*import*/ true, &clientStride);
+ ASSERT_NE(nullptr, clientBufferHandle);
+
+ void* clientBufData =
+ mGralloc->lock(clientBufferHandle, clientUsage, layer->mAccessRegion, -1);
+
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(layer->mWidth, layer->mHeight,
+ clientStride, clientBufData,
+ clientFormat, expectedColors));
+ int clientFence = mGralloc->unlock(clientBufferHandle);
+ if (clientFence != -1) {
+ sync_wait(clientFence, -1);
+ close(clientFence);
+ }
+
+ IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+ mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+ std::vector<IComposerClient::Rect>(1, damage));
+
+ layer->setToClientComposition(mWriter);
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_F(GraphicsComposerReadbackTest, DeviceAndClientComposition) {
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ auto deviceLayer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
+ PixelFormat::RGBA_8888);
+ std::vector<IComposerClient::Color> deviceColors(deviceLayer->mWidth *
+ deviceLayer->mHeight);
+ ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth,
+ {0, 0, static_cast<int32_t>(deviceLayer->mWidth),
+ static_cast<int32_t>(deviceLayer->mHeight)},
+ GREEN);
+ deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mWidth),
+ static_cast<int32_t>(deviceLayer->mHeight)});
+ deviceLayer->setZOrder(10);
+ ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+ deviceLayer->write(mWriter);
+
+ auto clientLayer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
+ PixelFormat::RGBA_8888, IComposerClient::Composition::CLIENT);
+ IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+ clientLayer->setDisplayFrame(clientFrame);
+ clientLayer->setZOrder(0);
+ clientLayer->write(mWriter);
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
// create client target buffer
uint32_t clientStride;
PixelFormat clientFormat = PixelFormat::RGBA_8888;
@@ -346,354 +524,335 @@
static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_CLIENT_TARGET);
const native_handle_t* clientBufferHandle =
- mGralloc->allocate(layer->mWidth, layer->mHeight, layer->mLayerCount, clientFormat,
- clientUsage, /*import*/ true, &clientStride);
+ mGralloc->allocate(mDisplayWidth, mDisplayHeight, clientLayer->mLayerCount,
+ clientFormat, clientUsage, /*import*/ true, &clientStride);
ASSERT_NE(nullptr, clientBufferHandle);
- void* clientBufData =
- mGralloc->lock(clientBufferHandle, clientUsage, layer->mAccessRegion, -1);
+ void* clientBufData = mGralloc->lock(clientBufferHandle, clientUsage,
+ {0, 0, mDisplayWidth, mDisplayHeight}, -1);
- ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(layer->mWidth, layer->mHeight,
+ std::vector<IComposerClient::Color> clientColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(clientColors, mDisplayWidth, clientFrame, RED);
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mDisplayWidth, mDisplayHeight,
clientStride, clientBufData,
- clientFormat, expectedColors));
+ clientFormat, clientColors));
int clientFence = mGralloc->unlock(clientBufferHandle);
if (clientFence != -1) {
sync_wait(clientFence, -1);
close(clientFence);
}
- IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
- std::vector<IComposerClient::Rect>(1, damage));
-
- layer->setToClientComposition(mWriter);
+ std::vector<IComposerClient::Rect>(1, clientFrame));
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
mWriter->validateDisplay();
execute();
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ std::cout << "Composition change requested, skipping test" << std::endl;
+ GTEST_SUCCEED() << "Composition change requested, skipping test";
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
- ASSERT_EQ(0, mReader->mErrors.size());
-
- mWriter->presentDisplay();
- execute();
-
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-}
-
-TEST_F(GraphicsComposerReadbackTest, DeviceAndClientComposition) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
- }
-
- mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(
- mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
-
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- auto deviceLayer =
- std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
- mDisplayHeight / 2, PixelFormat::RGBA_8888);
- std::vector<IComposerClient::Color> deviceColors(deviceLayer->mWidth * deviceLayer->mHeight);
- ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth,
- {0, 0, static_cast<int32_t>(deviceLayer->mWidth),
- static_cast<int32_t>(deviceLayer->mHeight)},
- GREEN);
- deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mWidth),
- static_cast<int32_t>(deviceLayer->mHeight)});
- deviceLayer->setZOrder(10);
- ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
- deviceLayer->write(mWriter);
-
- auto clientLayer = std::make_shared<TestBufferLayer>(
- mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
- PixelFormat::RGBA_8888, IComposerClient::Composition::CLIENT);
- IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
- clientLayer->setDisplayFrame(clientFrame);
- clientLayer->setZOrder(0);
- clientLayer->write(mWriter);
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- uint64_t clientUsage =
- static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
- BufferUsage::COMPOSER_CLIENT_TARGET);
- uint32_t clientStride;
- const native_handle_t* clientBufferHandle =
- mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888,
- clientUsage, /*import*/ true, &clientStride);
- ASSERT_NE(nullptr, clientBufferHandle);
-
- AccessRegion clientAccessRegion;
- clientAccessRegion.left = 0;
- clientAccessRegion.top = 0;
- clientAccessRegion.width = mDisplayWidth;
- clientAccessRegion.height = mDisplayHeight;
- void* clientData = mGralloc->lock(clientBufferHandle, clientUsage, clientAccessRegion, -1);
- std::vector<IComposerClient::Color> clientColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(clientColors, mDisplayWidth, clientFrame, RED);
- ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mDisplayWidth, mDisplayHeight, clientStride,
- clientData, PixelFormat::RGBA_8888,
- clientColors));
- int clientFence = mGralloc->unlock(clientBufferHandle);
- if (clientFence != -1) {
- sync_wait(clientFence, -1);
- close(clientFence);
- }
-
- mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
- std::vector<IComposerClient::Rect>(1, clientFrame));
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerDamage) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelformat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ IComposerClient::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
+
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+ mDisplayWidth, mDisplayHeight,
+ PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+ // update surface damage and recheck
+ redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
+ ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
+ layer->setSurfaceDamage(std::vector<IComposerClient::Rect>(
+ 1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
-
- IComposerClient::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
-
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
-
- auto layer =
- std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
- mDisplayHeight, PixelFormat::RGBA_8888);
- layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setZOrder(10);
- ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-
- // update surface damage and recheck
- redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
- ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
-
- ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
- layer->setSurfaceDamage(
- std::vector<IComposerClient::Rect>(1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerPlaneAlpha) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ layer->setColor(RED);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setAlpha(0);
+ layer->setBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
- RenderIntent::COLORIMETRIC));
-
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
- layer->setColor(RED);
- layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setZOrder(10);
- layer->setAlpha(0);
- layer->setBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
-
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerSourceCrop) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+ mDisplayWidth, mDisplayHeight,
+ PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
+ static_cast<float>(mDisplayWidth),
+ static_cast<float>(mDisplayHeight)});
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // update expected colors to match crop
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
-
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
-
- auto layer =
- std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
- mDisplayHeight, PixelFormat::RGBA_8888);
- layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
- layer->setZOrder(10);
- layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
- static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)});
- ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
-
- std::vector<std::shared_ptr<TestLayer>> layers = {layer};
-
- // update expected colors to match crop
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
- {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
TEST_F(GraphicsComposerReadbackTest, SetLayerZOrder) {
- if (!mHasReadbackBuffer) {
- GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
- return;
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ IComposerClient::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
+ IComposerClient::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
+ auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ redLayer->setColor(RED);
+ redLayer->setDisplayFrame(redRect);
+
+ auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ blueLayer->setColor(BLUE);
+ blueLayer->setDisplayFrame(blueRect);
+ blueLayer->setZOrder(5);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+ // red in front of blue
+ redLayer->setZOrder(10);
+
+ // fill blue first so that red will overwrite on overlap
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+ redLayer->setZOrder(1);
+ ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
-
- mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
- RenderIntent::COLORIMETRIC));
-
- IComposerClient::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
- IComposerClient::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
- auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
- redLayer->setColor(RED);
- redLayer->setDisplayFrame(redRect);
-
- auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
- blueLayer->setColor(BLUE);
- blueLayer->setDisplayFrame(blueRect);
- blueLayer->setZOrder(5);
-
- std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
- std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
-
- // red in front of blue
- redLayer->setZOrder(10);
-
- // fill blue first so that red will overwrite on overlap
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
-
- ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
- mDisplayHeight, mPixelFormat, mDataspace);
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- if (mReader->mCompositionChanges.size() != 0) {
- clearCommandReaderState();
- GTEST_SUCCEED();
- return;
- }
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-
- redLayer->setZOrder(1);
- ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
- ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-
- writeLayers(layers);
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->validateDisplay();
- execute();
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
- ASSERT_EQ(0, mReader->mErrors.size());
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
-
- ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
class GraphicsComposerBlendModeReadbackTest : public GraphicsComposerReadbackTest,
@@ -891,8 +1050,6 @@
GraphicsComposerReadbackTest::SetUp();
mWriter->selectDisplay(mPrimaryDisplay);
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
- RenderIntent::COLORIMETRIC));
auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
backgroundLayer->setColor({0, 0, 0, 0});
diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS
index b3ea6be..cc6d937 100644
--- a/graphics/composer/2.3/utils/OWNERS
+++ b/graphics/composer/2.3/utils/OWNERS
@@ -2,7 +2,3 @@
lpy@google.com
stoza@google.com
vhau@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
diff --git a/graphics/composer/2.3/utils/command-buffer/Android.bp b/graphics/composer/2.3/utils/command-buffer/Android.bp
index c48fe7a..36ac297 100644
--- a/graphics/composer/2.3/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.3/utils/command-buffer/Android.bp
@@ -3,12 +3,15 @@
defaults: ["hidl_defaults"],
vendor_available: true,
shared_libs: [
- "android.hardware.graphics.composer@2.1",
- "android.hardware.graphics.composer@2.2",
+ "android.hardware.graphics.composer@2.3",
+ ],
+ export_shared_lib_headers: [
"android.hardware.graphics.composer@2.3",
],
header_libs: [
- "android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
+ ],
+ export_header_lib_headers: [
"android.hardware.graphics.composer@2.2-command-buffer",
],
export_include_dirs: ["include"],
diff --git a/graphics/composer/2.3/utils/vts/Android.bp b/graphics/composer/2.3/utils/vts/Android.bp
index 036ef69..f65a9c4 100644
--- a/graphics/composer/2.3/utils/vts/Android.bp
+++ b/graphics/composer/2.3/utils/vts/Android.bp
@@ -21,22 +21,17 @@
"ComposerVts.cpp",
],
static_libs: [
- "VtsHalHidlTargetTestBase",
- "android.hardware.graphics.composer@2.1",
- "android.hardware.graphics.composer@2.1-vts",
- "android.hardware.graphics.composer@2.2",
"android.hardware.graphics.composer@2.2-vts",
"android.hardware.graphics.composer@2.3",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@2.0-vts",
- "android.hardware.graphics.mapper@2.1",
- "android.hardware.graphics.mapper@2.1-vts",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@3.0-vts",
+ ],
+ export_static_lib_headers: [
+ "android.hardware.graphics.composer@2.2-vts",
+ "android.hardware.graphics.composer@2.3",
],
header_libs: [
- "android.hardware.graphics.composer@2.1-command-buffer",
- "android.hardware.graphics.composer@2.2-command-buffer",
+ "android.hardware.graphics.composer@2.3-command-buffer",
+ ],
+ export_header_lib_headers: [
"android.hardware.graphics.composer@2.3-command-buffer",
],
cflags: [
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index a7b6c98..3af1df3 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -216,8 +216,8 @@
std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> reported_time{
std::chrono::milliseconds(sw_enforced[i].f.dateTime)};
- // The test is flaky for EC keys, so a buffer time of 1 second will be added.
- EXPECT_LE(creation - 1s, reported_time);
+ // The test is flaky for EC keys, so a buffer time of 120 seconds will be added.
+ EXPECT_LE(creation - 120s, reported_time);
EXPECT_LE(reported_time, now + 1s);
}
}
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index c66f574..293c50c 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -309,6 +309,11 @@
return make_string(a, N);
}
+bool avb_verification_enabled() {
+ char value[PROPERTY_VALUE_MAX];
+ return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
+}
+
} // namespace
bool verify_attestation_record(const string& challenge, const string& app_id,
@@ -359,26 +364,32 @@
EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
char property_value[PROPERTY_VALUE_MAX] = {};
- for (int i = 0; i < att_hw_enforced.size(); i++) {
- if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
- att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
- std::string date = std::to_string(att_hw_enforced[i].f.integer);
- // strptime seems to require delimiters, but the tag value will be YYYYMMDD
- date.insert(6, "-");
- date.insert(4, "-");
- EXPECT_EQ(date.size(), 10);
- struct tm time;
- strptime(date.c_str(), "%Y-%m-%d", &time);
+ // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
+ // keymaster implementation will report YYYYMM dates instead of YYYYMMDD
+ // for the BOOT_PATCH_LEVEL.
+ if (avb_verification_enabled()) {
+ for (int i = 0; i < att_hw_enforced.size(); i++) {
+ if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+ att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+ std::string date = std::to_string(att_hw_enforced[i].f.integer);
+ // strptime seems to require delimiters, but the tag value will
+ // be YYYYMMDD
+ date.insert(6, "-");
+ date.insert(4, "-");
+ EXPECT_EQ(date.size(), 10);
+ struct tm time;
+ strptime(date.c_str(), "%Y-%m-%d", &time);
- // Day of the month (0-31)
- EXPECT_GE(time.tm_mday, 0);
- EXPECT_LT(time.tm_mday, 32);
- // Months since Jan (0-11)
- EXPECT_GE(time.tm_mon, 0);
- EXPECT_LT(time.tm_mon, 12);
- // Years since 1900
- EXPECT_GT(time.tm_year, 110);
- EXPECT_LT(time.tm_year, 200);
+ // Day of the month (0-31)
+ EXPECT_GE(time.tm_mday, 0);
+ EXPECT_LT(time.tm_mday, 32);
+ // Months since Jan (0-11)
+ EXPECT_GE(time.tm_mon, 0);
+ EXPECT_LT(time.tm_mon, 12);
+ // Years since 1900
+ EXPECT_GT(time.tm_year, 110);
+ EXPECT_LT(time.tm_year, 200);
+ }
}
}
@@ -410,18 +421,20 @@
&verified_boot_state, &device_locked, &verified_boot_hash);
EXPECT_EQ(ErrorCode::OK, error);
- property_get("ro.boot.vbmeta.digest", property_value, "nogood");
- EXPECT_NE(strcmp(property_value, "nogood"), 0);
- string prop_string(property_value);
- EXPECT_EQ(prop_string.size(), 64);
- EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
+ if (avb_verification_enabled()) {
+ property_get("ro.boot.vbmeta.digest", property_value, "nogood");
+ EXPECT_NE(strcmp(property_value, "nogood"), 0);
+ string prop_string(property_value);
+ EXPECT_EQ(prop_string.size(), 64);
+ EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
- property_get("ro.boot.vbmeta.device_state", property_value, "nogood");
- EXPECT_NE(property_value, "nogood");
- if (!strcmp(property_value, "unlocked")) {
- EXPECT_FALSE(device_locked);
- } else {
- EXPECT_TRUE(device_locked);
+ property_get("ro.boot.vbmeta.device_state", property_value, "nogood");
+ EXPECT_NE(strcmp(property_value, "nogood"), 0);
+ if (!strcmp(property_value, "unlocked")) {
+ EXPECT_FALSE(device_locked);
+ } else {
+ EXPECT_TRUE(device_locked);
+ }
}
// Verified boot key should be all 0's if the boot state is not verified or self signed
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 696c746..26f2c90 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -41,6 +41,12 @@
ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
}
/*
@@ -67,6 +73,12 @@
ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
toString(radioRsp_v1_4->rspInfo.error).c_str());
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
}
/*
@@ -93,6 +105,12 @@
ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
toString(radioRsp_v1_4->rspInfo.error).c_str());
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
}
/*
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
index d2d21ce..63e5f6e 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
@@ -87,6 +87,23 @@
return status;
}
+void RadioHidlTest_v1_4::clearPotentialEstablishedCalls() {
+ // Get the current call Id to hangup the established emergency call.
+ serial = GetRandomSerialNumber();
+ radio_v1_4->getCurrentCalls(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+
+ // Hang up to disconnect the established call channels.
+ for (const ::android::hardware::radio::V1_2::Call& call : radioRsp_v1_4->currentCalls) {
+ serial = GetRandomSerialNumber();
+ radio_v1_4->hangup(serial, call.base.index);
+ ALOGI("Hang up to disconnect the established call channel: %d", call.base.index);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ // Give some time for modem to disconnect the established call channel.
+ sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
+ }
+}
+
void RadioHidlTest_v1_4::updateSimCardStatus() {
serial = GetRandomSerialNumber();
radio_v1_4->getIccCardStatus(serial);
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index f662472..b07f9c3 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -44,6 +44,9 @@
using ::android::hardware::Void;
#define TIMEOUT_PERIOD 75
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+
#define RADIO_SERVICE_NAME "slot1"
class RadioHidlTest_v1_4;
@@ -59,6 +62,9 @@
RadioResponseInfo rspInfo;
+ // Call
+ hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+
// Modem
bool isModemEnabled;
bool enableModemResponseToggle;
@@ -725,6 +731,9 @@
/* Serial number for radio request */
int serial;
+ /* Clear Potential Established Calls */
+ void clearPotentialEstablishedCalls();
+
/* Update Sim Card Status */
void updateSimCardStatus();
diff --git a/radio/1.4/vts/functional/radio_response.cpp b/radio/1.4/vts/functional/radio_response.cpp
index eac0c68..a849926 100644
--- a/radio/1.4/vts/functional/radio_response.cpp
+++ b/radio/1.4/vts/functional/radio_response.cpp
@@ -77,7 +77,9 @@
return Void();
}
-Return<void> RadioResponse_v1_4::hangupConnectionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_4::hangupConnectionResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_4.notify(info.serial);
return Void();
}
@@ -729,9 +731,10 @@
Return<void> RadioResponse_v1_4::getCurrentCallsResponse_1_2(
const RadioResponseInfo& info,
- const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& /*calls*/) {
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) {
rspInfo = info;
parent_v1_4.notify(info.serial);
+ currentCalls = calls;
return Void();
}
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index 03fcc17..dc54f27 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -130,8 +130,8 @@
void SensorsHidlEnvironmentV2_0::startPollingThread() {
mStopThread = false;
- mPollThread = std::thread(pollingThread, this);
mEvents.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
+ mPollThread = std::thread(pollingThread, this);
}
void SensorsHidlEnvironmentV2_0::readEvents() {
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index c6d7cad..91b4fa5 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -696,11 +696,16 @@
Result flushResult = flush(sensor.sensorHandle);
ASSERT_EQ(flushResult, expectedResponse);
}
- activate(sensor.sensorHandle, false);
}
// Wait up to one second for the flush events
callback.waitForFlushEvents(sensors, flushCalls, 1000 /* timeoutMs */);
+
+ // Deactivate all sensors after waiting for flush events so pending flush events are not
+ // abandoned by the HAL.
+ for (const SensorInfo& sensor : sensors) {
+ activate(sensor.sensorHandle, false);
+ }
getEnvironment()->unregisterCallback();
// Check that the correct number of flushes are present for each sensor
diff --git a/tests/libhwbinder/aidl/Android.bp b/tests/libhwbinder/aidl/Android.bp
index 6d49704..c9e09f7 100644
--- a/tests/libhwbinder/aidl/Android.bp
+++ b/tests/libhwbinder/aidl/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
name: "android.hardware.tests.libbinder",
defaults: ["hidl_defaults"],
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 36bde16..1b78ac3 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -127,25 +127,33 @@
});
}
+bool isMacRandomizationSupported(const SupplicantStatus& status) {
+ return status.code != SupplicantStatusCode::FAILURE_ARGS_INVALID;
+}
+
/*
* Verify that setMacRandomization successes.
*/
TEST_F(SupplicantP2pIfaceHidlTest, EnableMacRandomization) {
p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) {
+ if (!isMacRandomizationSupported(status)) return;
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
// enable twice
p2p_iface_->setMacRandomization(true, [](const SupplicantStatus& status) {
+ if (!isMacRandomizationSupported(status)) return;
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) {
+ if (!isMacRandomizationSupported(status)) return;
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
// disable twice
p2p_iface_->setMacRandomization(false, [](const SupplicantStatus& status) {
+ if (!isMacRandomizationSupported(status)) return;
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}