Merge "Update paths to NNAPI VTS models"
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index bec22df..1a9df21 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -378,7 +378,7 @@
}
Return<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) {
- auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect;
+ auto key = connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect;
return setParam(key, address);
}
#endif
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index b995657..e62f6d3 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -243,8 +243,8 @@
Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) {
return setParam(
- connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect,
- address);
+ connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect,
+ address);
}
#elif MAJOR_VERSION >= 4
Return<void> Stream::getDevices(getDevices_cb _hidl_cb) {
diff --git a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
index e82da7e..1a95cd0 100644
--- a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
+++ b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.authsecret-1-0 /vendor/bin/hw/android.hardware.authsecret@1.0-service
+ interface android.hardware.authsecret@1.0::IAuthSecret default
class hal
user system
group system
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/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
index b615227..9fa128d 100644
--- a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
+++ b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.bluetooth-1-0 /vendor/bin/hw/android.hardware.bluetooth@1.0-service
+ interface android.hardware.bluetooth@1.0::IBluetoothHci default
class hal
capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
user bluetooth
diff --git a/boot/1.0/default/android.hardware.boot@1.0-service.rc b/boot/1.0/default/android.hardware.boot@1.0-service.rc
index 32f3a45..b8125e1 100644
--- a/boot/1.0/default/android.hardware.boot@1.0-service.rc
+++ b/boot/1.0/default/android.hardware.boot@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.boot-hal-1-0 /vendor/bin/hw/android.hardware.boot@1.0-service
+ interface android.hardware.boot@1.0::IBootControl default
class early_hal
user root
group root
diff --git a/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc b/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
index 7c57135..6fcbfa6 100644
--- a/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
+++ b/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
@@ -1,4 +1,6 @@
service broadcastradio-hal /vendor/bin/hw/android.hardware.broadcastradio@1.1-service
+ interface android.hardware.broadcastradio@1.0::IBroadcastRadioFactory default
+ interface android.hardware.broadcastradio@1.1::IBroadcastRadioFactory default
class hal
user audioserver
group audio
diff --git a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
index 7d68b6c..dd8c9c6 100644
--- a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
+++ b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
@@ -1,4 +1,5 @@
service broadcastradio-hal2 /vendor/bin/hw/android.hardware.broadcastradio@2.0-service
+ interface android.hardware.broadcastradio@2.0::IBroadcastRadio default
class hal
user audioserver
group audio
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c94c825..a5369e7 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,13 @@
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) {
+ ret = session3_4->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
std::shared_ptr<ResultMetadataQueue> resultQueue;
auto resultQueueRet =
@@ -5174,7 +5184,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 +5284,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 +5408,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/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
index 105678a..d62c4a8 100644
--- a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
+++ b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
@@ -1,4 +1,6 @@
service vendor.configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
+ interface android.hardware.configstore@1.0::ISurfaceFlingerConfigs default
+ interface android.hardware.configstore@1.1::ISurfaceFlingerConfigs default
class hal animation
user system
group system
diff --git a/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc b/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
index c04e55e..adc7222 100644
--- a/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
+++ b/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.confirmationui-1-0 /vendor/bin/hw/android.hardware.confirmationui@1.0-service
+ interface android.hardware.confirmationui@1.0::IConfirmationUI default
class hal
user nobody
group drmrpc
diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
index a8c9487..b659be8 100644
--- a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
+++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.contexthub-hal-1-0 /vendor/bin/hw/android.hardware.contexthub@1.0-service
+ interface android.hardware.contexthub@1.0::IContexthub default
class hal
user system
group system
diff --git a/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc b/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
index da332c7..b13a9ba 100644
--- a/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
+++ b/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gatekeeper-1-0 /vendor/bin/hw/android.hardware.gatekeeper@1.0-service
+ interface android.hardware.gatekeeper@1.0::IGatekeeper default
class hal
user system
group system
diff --git a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
index 1a44d34..1300d81 100644
--- a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
+++ b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service
+ interface android.hardware.gnss@1.0::IGnss default
class hal
user gps
group system gps radio
diff --git a/gnss/1.1/default/android.hardware.gnss@1.1-service.rc b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
index 0cf7c49..73901bf 100644
--- a/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
+++ b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
@@ -1,4 +1,6 @@
service gnss-1-1 /vendor/bin/hw/android.hardware.gnss@1.1-service
+ interface android.hardware.gnss@1.0::IGnss default
+ interface android.hardware.gnss@1.1::IGnss default
class hal
user system
group system
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/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
index a2a881a..038e87c 100644
--- a/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
+++ b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gralloc-2-0 /vendor/bin/hw/android.hardware.graphics.allocator@2.0-service
+ interface android.hardware.graphics.allocator@2.0::IAllocator default
class hal animation
interface android.hardware.graphics.allocator@2.0::IAllocator default
user system
diff --git a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
index 5a5b51e..cbd589a 100644
--- a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
+++ b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
@@ -1,4 +1,5 @@
service vendor.hwcomposer-2-1 /vendor/bin/hw/android.hardware.graphics.composer@2.1-service
+ interface android.hardware.graphics.composer@2.1::IComposer default
class hal animation
user system
group graphics drmrpc
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/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
index efe6dad..0d7e86f 100644
--- a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
+++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
@@ -1,4 +1,6 @@
service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@2.2-service
+ interface android.hardware.graphics.composer@2.1::IComposer default
+ interface android.hardware.graphics.composer@2.2::IComposer default
class hal animation
user system
group graphics drmrpc
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/ir/1.0/default/android.hardware.ir@1.0-service.rc b/ir/1.0/default/android.hardware.ir@1.0-service.rc
index 0d06967..b2f1f7d 100644
--- a/ir/1.0/default/android.hardware.ir@1.0-service.rc
+++ b/ir/1.0/default/android.hardware.ir@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.ir-hal-1-0 /vendor/bin/hw/android.hardware.ir@1.0-service
+ interface android.hardware.ir@1.0::IConsumerIr default
class hal
user system
group system
diff --git a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
index ea8d490..dffaca5 100644
--- a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
+++ b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
@@ -1,4 +1,5 @@
service vendor.keymaster-3-0 /vendor/bin/hw/android.hardware.keymaster@3.0-service
+ interface android.hardware.keymaster@3.0::IKeymasterDevice default
class early_hal
user nobody
group drmrpc
diff --git a/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc b/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
index 2ce439e..2adfd88 100644
--- a/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
+++ b/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
@@ -1,4 +1,5 @@
service vendor.keymaster-4-0 /vendor/bin/hw/android.hardware.keymaster@4.0-service
+ interface android.hardware.keymaster@4.0::IKeymasterDevice default
class early_hal
user system
group system drmrpc
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/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp
index cdc52fb..5a79e55 100644
--- a/media/omx/1.0/vts/functional/common/Android.bp
+++ b/media/omx/1.0/vts/functional/common/Android.bp
@@ -29,6 +29,21 @@
"android.hidl.memory@1.0",
"android.hardware.media.omx@1.0",
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
+ ],
+ export_static_lib_headers: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
],
}
@@ -40,7 +55,12 @@
static_libs: [
"VtsHalMediaOmxV1_0CommonUtil",
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.common@1.0",
"android.hardware.media.omx@1.0",
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index f299e36..8d4c022 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -22,8 +22,11 @@
#include <android-base/logging.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/types.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -31,7 +34,9 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
-#include <cutils/atomic.h>
+
+#include <atomic>
+#include <variant>
using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -195,67 +200,104 @@
BufferInfo* buffer, uint32_t nFrameWidth,
uint32_t nFrameHeight, int32_t* nStride,
int format) {
- android::hardware::media::omx::V1_0::Status status;
- sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
- android::hardware::graphics::allocator::V2_0::IAllocator::getService();
- ASSERT_NE(nullptr, allocator.get());
+ struct AllocatorV2 : public GrallocV2 {
+ sp<IAllocator> mAllocator;
+ sp<IMapper> mMapper;
+ AllocatorV2(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
+ : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
+ AllocatorV2() = default;
+ };
+ struct AllocatorV3 : public GrallocV3 {
+ sp<IAllocator> mAllocator;
+ sp<IMapper> mMapper;
+ AllocatorV3(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
+ : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
+ AllocatorV3() = default;
+ };
+ std::variant<AllocatorV2, AllocatorV3> grallocVar;
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- ASSERT_NE(mapper.get(), nullptr);
+ sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2{};
+ sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3{};
+ sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator2{};
+ sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocator3 =
+ android::hardware::graphics::allocator::V3_0::IAllocator::getService();
+ if (allocator3) {
+ mapper3 =
+ android::hardware::graphics::mapper::V3_0::IMapper::getService();
+ ASSERT_NE(nullptr, mapper3.get());
+ grallocVar.emplace<AllocatorV3>(std::move(allocator3), std::move(mapper3));
+ } else {
+ allocator2 =
+ android::hardware::graphics::allocator::V2_0::IAllocator::getService();
+ ASSERT_NE(nullptr, allocator2.get());
+ mapper2 =
+ android::hardware::graphics::mapper::V2_0::IMapper::getService();
+ ASSERT_NE(nullptr, allocator2.get());
+ grallocVar.emplace<AllocatorV2>(std::move(allocator2), std::move(mapper2));
+ }
- android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
- descriptorInfo;
- uint32_t usage;
-
- descriptorInfo.width = nFrameWidth;
- descriptorInfo.height = nFrameHeight;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format = static_cast<PixelFormat>(format);
- descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
- omxNode->getGraphicBufferUsage(
+ android::hardware::media::omx::V1_0::Status status{};
+ uint64_t usage{};
+ ASSERT_TRUE(omxNode->getGraphicBufferUsage(
portIndex,
[&status, &usage](android::hardware::media::omx::V1_0::Status _s,
uint32_t _n1) {
status = _s;
usage = _n1;
- });
- if (status == android::hardware::media::omx::V1_0::Status::OK) {
- descriptorInfo.usage |= usage;
- }
+ }).isOk());
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- android::hardware::graphics::mapper::V2_0::Error error;
- mapper->createDescriptor(
- descriptorInfo, [&error, &descriptor](
- android::hardware::graphics::mapper::V2_0::Error _s,
- ::android::hardware::hidl_vec<uint32_t> _n1) {
- error = _s;
- descriptor = _n1;
- });
- ASSERT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
+ static std::atomic_int32_t bufferIdCounter{0};
- static volatile int32_t nextId = 0;
- uint64_t id = static_cast<uint64_t>(getpid()) << 32;
- allocator->allocate(
- descriptor, 1,
- [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
- const ::android::hardware::hidl_vec<
- ::android::hardware::hidl_handle>& _n2) {
- ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
- _s);
- *nStride = _n1;
- buffer->omxBuffer.nativeHandle = _n2[0];
- buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
- buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
- buffer->omxBuffer.attr.anwBuffer.stride = _n1;
- buffer->omxBuffer.attr.anwBuffer.format = descriptorInfo.format;
- buffer->omxBuffer.attr.anwBuffer.usage = descriptorInfo.usage;
- buffer->omxBuffer.attr.anwBuffer.layerCount =
- descriptorInfo.layerCount;
- buffer->omxBuffer.attr.anwBuffer.id =
- id | static_cast<uint32_t>(android_atomic_inc(&nextId));
- });
+ std::visit([buffer, nFrameWidth, nFrameHeight, format, usage, nStride](auto&& gralloc) {
+ using Gralloc = std::remove_reference_t<decltype(gralloc)>;
+ using Descriptor = typename Gralloc::Descriptor;
+ using DescriptorInfo = typename Gralloc::DescriptorInfo;
+ using Error = typename Gralloc::Error;
+ using Format = typename Gralloc::Format;
+ using Usage = typename Gralloc::Usage;
+
+ Error error{};
+ Descriptor descriptor{};
+
+ DescriptorInfo descriptorInfo{};
+ descriptorInfo.width = nFrameWidth;
+ descriptorInfo.height = nFrameHeight;
+ descriptorInfo.layerCount = 1;
+ descriptorInfo.format = static_cast<Format>(format);
+ descriptorInfo.usage = usage | Usage(BufferUsage::CPU_READ_OFTEN);
+
+ gralloc.mMapper->createDescriptor(descriptorInfo,
+ [&error, &descriptor](
+ Error _s,
+ const Descriptor& _n1) {
+ error = _s;
+ descriptor = _n1;
+ });
+ ASSERT_EQ(error, Error::NONE);
+
+ gralloc.mAllocator->allocate(
+ descriptor, 1,
+ [&](Error _s, uint32_t _n1,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::hidl_handle>& _n2) {
+ ASSERT_EQ(Error::NONE, _s);
+ *nStride = _n1;
+ buffer->omxBuffer.nativeHandle = _n2[0];
+ buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
+ buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
+ buffer->omxBuffer.attr.anwBuffer.stride = _n1;
+ buffer->omxBuffer.attr.anwBuffer.format =
+ static_cast<PixelFormat>(descriptorInfo.format);
+ buffer->omxBuffer.attr.anwBuffer.usage =
+ static_cast<uint32_t>(descriptorInfo.usage);
+ buffer->omxBuffer.attr.anwBuffer.layerCount =
+ descriptorInfo.layerCount;
+ buffer->omxBuffer.attr.anwBuffer.id =
+ (static_cast<uint64_t>(getpid()) << 32) |
+ bufferIdCounter.fetch_add(1, std::memory_order_relaxed);
+ });
+ }, grallocVar);
}
// allocate buffers needed on a component port
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index 1575ba2..08af26b 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -22,6 +22,16 @@
#endif
#include <getopt.h>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/common/1.0/types.h>
+#include <android/hardware/graphics/common/1.1/types.h>
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/2.0/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/types.h>
#include <media/stagefright/foundation/ALooper.h>
#include <utils/Condition.h>
#include <utils/List.h>
@@ -288,6 +298,36 @@
/*
* common functions declarations
*/
+struct GrallocV2 {
+ using Format = android::hardware::graphics::common::V1_0::PixelFormat;
+ using Usage = android::hardware::hidl_bitfield<
+ android::hardware::graphics::common::V1_0::BufferUsage>;
+
+ using IAllocator = android::hardware::graphics::allocator::V2_0::IAllocator;
+
+ using IMapper = android::hardware::graphics::mapper::V2_0::IMapper;
+ using Error = android::hardware::graphics::mapper::V2_0::Error;
+ using Descriptor = android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+ using YCbCrLayout = android::hardware::graphics::mapper::V2_0::YCbCrLayout;
+ using DescriptorInfo = IMapper::BufferDescriptorInfo;
+ using Rect = IMapper::Rect;
+};
+
+struct GrallocV3 {
+ using Format = android::hardware::graphics::common::V1_2::PixelFormat;
+ using Usage = android::hardware::hidl_bitfield<
+ android::hardware::graphics::common::V1_2::BufferUsage>;
+
+ using IAllocator = android::hardware::graphics::allocator::V3_0::IAllocator;
+
+ using IMapper = android::hardware::graphics::mapper::V3_0::IMapper;
+ using Error = android::hardware::graphics::mapper::V3_0::Error;
+ using Descriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+ using YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout;
+ using DescriptorInfo = IMapper::BufferDescriptorInfo;
+ using Rect = IMapper::Rect;
+};
+
Return<android::hardware::media::omx::V1_0::Status> setRole(
sp<IOmxNode> omxNode, const char* role);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index a740a80..2280cee 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -63,6 +63,7 @@
#include <media_video_hidl_test_common.h>
#include <system/window.h>
#include <fstream>
+#include <variant>
static ComponentTestEnvironment* gEnv = nullptr;
@@ -364,6 +365,61 @@
return Void();
};
+// Variant of mappers
+struct MapperV2 : public GrallocV2 {
+ sp<IMapper> mMapper;
+ MapperV2(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
+ MapperV2() = default;
+ android::hardware::Return<void> lock(
+ void* buffer,
+ Usage usage,
+ const Rect& rect,
+ const android::hardware::hidl_handle& handle,
+ Error* error,
+ void** data) {
+ return mMapper->lock(buffer, usage, rect, handle,
+ [error, data](Error e, void* d) {
+ *error = e;
+ *data = d;
+ });
+ }
+};
+struct MapperV3 : public GrallocV3 {
+ sp<IMapper> mMapper;
+ MapperV3(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
+ MapperV3() = default;
+ android::hardware::Return<void> lock(
+ void* buffer,
+ Usage usage,
+ const Rect& rect,
+ const android::hardware::hidl_handle& handle,
+ Error* error,
+ void** data) {
+ return mMapper->lock(buffer, usage, rect, handle,
+ [error, data](Error e, void* d, int32_t, int32_t) {
+ *error = e;
+ *data = d;
+ });
+ }
+};
+using MapperVar = std::variant<MapperV2, MapperV3>;
+// Initializes the MapperVar by trying services of different versions.
+bool initialize(MapperVar& mapperVar) {
+ sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3 =
+ android::hardware::graphics::mapper::V3_0::IMapper::getService();
+ if (mapper3) {
+ mapperVar.emplace<MapperV3>(std::move(mapper3));
+ return true;
+ }
+ sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2 =
+ android::hardware::graphics::mapper::V2_0::IMapper::getService();
+ if (mapper2) {
+ mapperVar.emplace<MapperV2>(std::move(mapper2));
+ return true;
+ }
+ return false;
+}
+
// request VOP refresh
void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
android::hardware::media::omx::V1_0::Status status;
@@ -574,150 +630,166 @@
int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
std::ifstream& eleStream) {
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- EXPECT_NE(mapper.get(), nullptr);
- if (mapper.get() == nullptr) return 1;
-
- android::hardware::hidl_handle fence;
- android::hardware::graphics::mapper::V2_0::IMapper::Rect rect;
- android::hardware::graphics::mapper::V2_0::YCbCrLayout ycbcrLayout;
- android::hardware::graphics::mapper::V2_0::Error error;
- rect.left = 0;
- rect.top = 0;
- rect.width = buffer->omxBuffer.attr.anwBuffer.width;
- rect.height = buffer->omxBuffer.attr.anwBuffer.height;
-
- if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
- format == PixelFormat::YCBCR_420_888) {
- mapper->lockYCbCr(
- buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
- [&](android::hardware::graphics::mapper::V2_0::Error _e,
- android::hardware::graphics::mapper::V2_0::YCbCrLayout _n1) {
- error = _e;
- ycbcrLayout = _n1;
- });
- EXPECT_EQ(error,
- android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
- return 1;
-
- int size = ((rect.width * rect.height * 3) >> 1);
- char* img = new char[size];
- if (img == nullptr) return 1;
- eleStream.read(img, size);
- if (eleStream.gcount() != size) {
- delete[] img;
- return 1;
- }
-
- char* imgTmp = img;
- char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
- for (size_t y = rect.height; y > 0; --y) {
- memcpy(ipBuffer, imgTmp, rect.width);
- ipBuffer += ycbcrLayout.yStride;
- imgTmp += rect.width;
- }
-
- if (format == PixelFormat::YV12)
- EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
- else if (format == PixelFormat::YCRCB_420_SP)
- EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
-
- ipBuffer = static_cast<char*>(ycbcrLayout.cb);
- for (size_t y = rect.height >> 1; y > 0; --y) {
- for (int32_t x = 0; x < (rect.width >> 1); ++x) {
- ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
- }
- ipBuffer += ycbcrLayout.cStride;
- }
- ipBuffer = static_cast<char*>(ycbcrLayout.cr);
- for (size_t y = rect.height >> 1; y > 0; --y) {
- for (int32_t x = 0; x < (rect.width >> 1); ++x) {
- ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
- }
- ipBuffer += ycbcrLayout.cStride;
- }
-
- delete[] img;
-
- mapper->unlock(buff,
- [&](android::hardware::graphics::mapper::V2_0::Error _e,
- android::hardware::hidl_handle _n1) {
- error = _e;
- fence = _n1;
- });
- EXPECT_EQ(error,
- android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
- return 1;
- } else {
- void* data;
- mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
- [&](android::hardware::graphics::mapper::V2_0::Error _e,
- void* _n1) {
- error = _e;
- data = _n1;
- });
- EXPECT_EQ(error,
- android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
- return 1;
-
- if (format == PixelFormat::BGRA_8888) {
- char* ipBuffer = static_cast<char*>(data);
- for (size_t y = rect.height; y > 0; --y) {
- eleStream.read(ipBuffer, rect.width * 4);
- if (eleStream.gcount() != rect.width * 4) return 1;
- ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
- }
- } else {
- EXPECT_TRUE(false) << "un expected pixel format";
- return 1;
- }
-
- mapper->unlock(buff,
- [&](android::hardware::graphics::mapper::V2_0::Error _e,
- android::hardware::hidl_handle _n1) {
- error = _e;
- fence = _n1;
- });
- EXPECT_EQ(error,
- android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
- return 1;
+ MapperVar mapperVar;
+ if (!initialize(mapperVar)) {
+ EXPECT_TRUE(false) << "failed to obtain mapper service";
+ return 1;
}
- return 0;
+ return std::visit([buffer, buff, format, &eleStream](auto&& mapper) -> int {
+ using Gralloc = std::remove_reference_t<decltype(mapper)>;
+ using Error = typename Gralloc::Error;
+ using Rect = typename Gralloc::Rect;
+ using Usage = typename Gralloc::Usage;
+ using YCbCrLayout = typename Gralloc::YCbCrLayout;
+
+ android::hardware::hidl_handle fence;
+ Rect rect;
+ YCbCrLayout ycbcrLayout;
+ Error error;
+ rect.left = 0;
+ rect.top = 0;
+ rect.width = buffer->omxBuffer.attr.anwBuffer.width;
+ rect.height = buffer->omxBuffer.attr.anwBuffer.height;
+
+ if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
+ format == PixelFormat::YCBCR_420_888) {
+ mapper.mMapper->lockYCbCr(
+ buff,
+ static_cast<Usage>(
+ buffer->omxBuffer.attr.anwBuffer.usage),
+ rect,
+ fence,
+ [&](Error _e,
+ const YCbCrLayout& _n1) {
+ error = _e;
+ ycbcrLayout = _n1;
+ });
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
+
+ int size = ((rect.width * rect.height * 3) >> 1);
+ char* img = new char[size];
+ if (img == nullptr) return 1;
+ eleStream.read(img, size);
+ if (eleStream.gcount() != size) {
+ delete[] img;
+ return 1;
+ }
+
+ char* imgTmp = img;
+ char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
+ for (size_t y = rect.height; y > 0; --y) {
+ memcpy(ipBuffer, imgTmp, rect.width);
+ ipBuffer += ycbcrLayout.yStride;
+ imgTmp += rect.width;
+ }
+
+ if (format == PixelFormat::YV12)
+ EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
+ else if (format == PixelFormat::YCRCB_420_SP)
+ EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
+
+ ipBuffer = static_cast<char*>(ycbcrLayout.cb);
+ for (size_t y = rect.height >> 1; y > 0; --y) {
+ for (int32_t x = 0; x < (rect.width >> 1); ++x) {
+ ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
+ }
+ ipBuffer += ycbcrLayout.cStride;
+ }
+ ipBuffer = static_cast<char*>(ycbcrLayout.cr);
+ for (size_t y = rect.height >> 1; y > 0; --y) {
+ for (int32_t x = 0; x < (rect.width >> 1); ++x) {
+ ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
+ }
+ ipBuffer += ycbcrLayout.cStride;
+ }
+
+ delete[] img;
+
+ mapper.mMapper->unlock(buff,
+ [&](Error _e,
+ const android::hardware::hidl_handle& _n1) {
+ error = _e;
+ fence = _n1;
+ });
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
+ } else {
+ void* data;
+ mapper.lock(
+ buff,
+ buffer->omxBuffer.attr.anwBuffer.usage,
+ rect,
+ fence,
+ &error,
+ &data);
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
+
+ if (format == PixelFormat::BGRA_8888) {
+ char* ipBuffer = static_cast<char*>(data);
+ for (size_t y = rect.height; y > 0; --y) {
+ eleStream.read(ipBuffer, rect.width * 4);
+ if (eleStream.gcount() != rect.width * 4) return 1;
+ ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
+ }
+ } else {
+ EXPECT_TRUE(false) << "un expected pixel format";
+ return 1;
+ }
+
+ mapper.mMapper->unlock(
+ buff,
+ [&](Error _e, const android::hardware::hidl_handle& _n1) {
+ error = _e;
+ fence = _n1;
+ });
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
+ }
+
+ return 0;
+ }, mapperVar);
}
int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
std::ifstream& eleStream) {
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- EXPECT_NE(mapper.get(), nullptr);
- if (mapper.get() == nullptr) return 1;
-
- void* buff = nullptr;
- android::hardware::graphics::mapper::V2_0::Error error;
- mapper->importBuffer(
- buffer->omxBuffer.nativeHandle,
- [&](android::hardware::graphics::mapper::V2_0::Error _e, void* _n1) {
- error = _e;
- buff = _n1;
- });
- EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
+ MapperVar mapperVar;
+ if (!initialize(mapperVar)) {
+ EXPECT_TRUE(false) << "failed to obtain mapper service";
return 1;
+ }
- if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
+ return std::visit([buffer, format, &eleStream](auto&& mapper) -> int {
+ using Gralloc = std::remove_reference_t<decltype(mapper)>;
+ using Error = typename Gralloc::Error;
- error = mapper->freeBuffer(buff);
- EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
- if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
- return 1;
+ void* buff = nullptr;
+ Error error;
+ mapper.mMapper->importBuffer(
+ buffer->omxBuffer.nativeHandle,
+ [&](Error _e, void* _n1) {
+ error = _e;
+ buff = _n1;
+ });
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
- return 0;
+ if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
+
+ error = mapper.mMapper->freeBuffer(buff);
+ EXPECT_EQ(error, Error::NONE);
+ if (error != Error::NONE)
+ return 1;
+
+ return 0;
+ }, mapperVar);
}
int dispatchGraphicBuffer(sp<IOmxNode> omxNode,
diff --git a/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc b/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
index 4327a20..f5eee54 100644
--- a/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
+++ b/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.memtrack-hal-1-0 /vendor/bin/hw/android.hardware.memtrack@1.0-service
+ interface android.hardware.memtrack@1.0::IMemtrack default
class hal
user system
group system
diff --git a/nfc/1.0/default/android.hardware.nfc@1.0-service.rc b/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
index 3a5c776..27e35d2 100644
--- a/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
+++ b/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.0-service
+ interface android.hardware.nfc@1.0::INfc default
class hal
user nfc
group nfc
diff --git a/power/1.0/default/android.hardware.power@1.0-service.rc b/power/1.0/default/android.hardware.power@1.0-service.rc
index 657c733..f3fd303 100644
--- a/power/1.0/default/android.hardware.power@1.0-service.rc
+++ b/power/1.0/default/android.hardware.power@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.0-service
+ interface android.hardware.power@1.0::IPower default
class hal
user system
group system
diff --git a/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc b/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
index e126cd8..eab37ec 100644
--- a/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
+++ b/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
@@ -1,4 +1,13 @@
service vendor.radio-1-2 /vendor/bin/hw/android.hardware.radio@1.2-radio-service
+ interface android.hardware.radio@1.0::IRadio slot1
+ interface android.hardware.radio@1.0::IRadio slot2
+ interface android.hardware.radio@1.0::IRadio slot3
+ interface android.hardware.radio@1.1::IRadio slot1
+ interface android.hardware.radio@1.1::IRadio slot2
+ interface android.hardware.radio@1.1::IRadio slot3
+ interface android.hardware.radio@1.2::IRadio slot1
+ interface android.hardware.radio@1.2::IRadio slot2
+ interface android.hardware.radio@1.2::IRadio slot3
class hal
user system
group system
diff --git a/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc b/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
index 845e6e5..9f163f6 100644
--- a/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
+++ b/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
@@ -1,4 +1,7 @@
service vendor.sap-1-2 /vendor/bin/hw/android.hardware.radio@1.2-sap-service
+ interface android.hardware.radio@1.0::ISap slot1
+ interface android.hardware.radio@1.1::ISap slot1
+ interface android.hardware.radio@1.2::ISap slot1
class hal
user system
group system
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
index bff7481..6b84810 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <android/hardware/radio/1.1/IRadio.h>
#include <radio_hidl_hal_utils_v1_2.h>
void RadioHidlTest_v1_2::SetUp() {
@@ -88,25 +87,7 @@
}
void RadioHidlTest_v1_2::stopNetworkScan() {
- sp<::android::hardware::radio::V1_1::IRadio> radio_v1_1;
-
- radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
- if (radio_v1_1 == NULL) {
- sleep(60);
- radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
- }
- ASSERT_NE(nullptr, radio_v1_1.get());
-
serial = GetRandomSerialNumber();
-
- radio_v1_1->stopNetworkScan(serial);
+ radio_v1_2->stopNetworkScan(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
}
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/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
index fad16b1..94d5edb 100644
--- a/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
+++ b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.radio-config-hal-1-0 /vendor/bin/hw/android.hardware.radio.config@1.0-service
+ interface android.hardware.radio.config@1.0::IRadioConfig default
class hal
user system
group system
diff --git a/sensors/1.0/default/android.hardware.sensors@1.0-service.rc b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
index b54842d..4faa562 100644
--- a/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
+++ b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.sensors-hal-1-0 /vendor/bin/hw/android.hardware.sensors@1.0-service
+ interface android.hardware.sensors@1.0::ISensors default
class hal
user system
group system wakelock
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/thermal/1.0/default/android.hardware.thermal@1.0-service.rc b/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
index cf9bdee..ba3ce82 100644
--- a/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
+++ b/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.thermal-hal-1-0 /vendor/bin/hw/android.hardware.thermal@1.0-service
+ interface android.hardware.thermal@1.0::IThermal default
class hal
user system
group system
diff --git a/tv/cec/1.0/config/sadConfig.xsd b/tv/cec/1.0/config/sadConfig.xsd
new file mode 100644
index 0000000..7f99311
--- /dev/null
+++ b/tv/cec/1.0/config/sadConfig.xsd
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 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.
+-->
+<xs:schema version="1.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:include schemaLocation="../../../../audio/4.0/config/audio_policy_configuration.xsd"/>
+ <xs:complexType name="config">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ List the config versions supported by Short Audio Descriptor(SAD) config.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="device" type="device" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="version" type="version"/>
+ </xs:complexType>
+ <xs:complexType name="device">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Device section:
+ There is a list of configurations in this SAD config for all the input audio
+ devices that the current Android device supports.
+ Each device has the following attributes:
+ "type": type of the audio device.
+ And the following element
+ <supportedFormat/>: the supported format info of the device. There can be
+ multiple formats supported by one audio device.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="supportedFormat" type="supportedFormat" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="type" type="extendableAudioDevice" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="supportedFormat">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ SupportedFormat section:
+ The details of the short audio descriptor of a specific audio format
+ supported by the audio device. Attributes as follows:
+ "format": format enum of the current supported format.
+ "descriptor": three-byte short audio descriptor for the given format in hex.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="format" type="hdmiAudioFormat" use="required"/>
+ <xs:attribute name="descriptor" type="descriptor" use="required"/>
+ </xs:complexType>
+ <xs:simpleType name="descriptor">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-fA-F0-9]{6}"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="hdmiAudioFormat">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_FORMAT_NONE"/>
+ <xs:enumeration value="AUDIO_FORMAT_LPCM"/>
+ <xs:enumeration value="AUDIO_FORMAT_DD"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEG1"/>
+ <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+ <xs:enumeration value="AUDIO_FORMAT_MPEG2"/>
+ <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+ <xs:enumeration value="AUDIO_FORMAT_ATRAC"/>
+ <xs:enumeration value="AUDIO_FORMAT_ONEBITAUDIO"/>
+ <xs:enumeration value="AUDIO_FORMAT_DDP"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTSHD"/>
+ <xs:enumeration value="AUDIO_FORMAT_TRUEHD"/>
+ <xs:enumeration value="AUDIO_FORMAT_DST"/>
+ <xs:enumeration value="AUDIO_FORMAT_WMAPRO"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="config" type="config"/>
+</xs:schema>
diff --git a/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc b/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
index 8595099..6d25229 100644
--- a/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
+++ b/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.cec-hal-1-0 /vendor/bin/hw/android.hardware.tv.cec@1.0-service
+ interface android.hardware.tv.cec@1.0::IHdmiCec default
class hal
user system
group system
diff --git a/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc b/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
index 972c654..6cb9a43 100644
--- a/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
+++ b/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.tv-input-1-0 /vendor/bin/hw/android.hardware.tv.input@1.0-service
+ interface android.hardware.tv.input@1.0::ITvInput default
class hal
user system
group system
diff --git a/usb/1.0/default/android.hardware.usb@1.0-service.rc b/usb/1.0/default/android.hardware.usb@1.0-service.rc
index b7a0c63..3c44d21 100644
--- a/usb/1.0/default/android.hardware.usb@1.0-service.rc
+++ b/usb/1.0/default/android.hardware.usb@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.usb-hal-1-0 /vendor/bin/hw/android.hardware.usb@1.0-service
+ interface android.hardware.usb@1.0::IUsb default
class hal
user system
group system
diff --git a/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc b/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
index 1123eab..1bd5c10 100644
--- a/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
+++ b/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.vibrator-1-0 /vendor/bin/hw/android.hardware.vibrator@1.0-service
+ interface android.hardware.vibrator@1.0::IVibrator default
class hal
user system
group system
diff --git a/vr/1.0/default/android.hardware.vr@1.0-service.rc b/vr/1.0/default/android.hardware.vr@1.0-service.rc
index fc4934c..5486674 100644
--- a/vr/1.0/default/android.hardware.vr@1.0-service.rc
+++ b/vr/1.0/default/android.hardware.vr@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.vr-1-0 /vendor/bin/hw/android.hardware.vr@1.0-service
+ interface android.hardware.vr@1.0::IVr default
class hal
user system
group system
diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service.rc b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
index cf849d0..2317bac 100644
--- a/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
+++ b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
@@ -1,4 +1,7 @@
service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service
+ interface android.hardware.wifi@1.0::IWifi default
+ interface android.hardware.wifi@1.1::IWifi default
+ interface android.hardware.wifi@1.2::IWifi default
class hal
capabilities NET_ADMIN NET_RAW SYS_MODULE
user wifi
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);
});
}