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 d689e62061..8ee3c545dc 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 @@ -153,7 +153,7 @@ std::unique_ptr createOfferingMessage(const VmsOffers& offers) std::unique_ptr createAvailabilityRequest(); // Creates a VehiclePropValue containing a message of type -// VmsMessageType.AVAILABILITY_REQUEST. +// VmsMessageType.SUBSCRIPTIONS_REQUEST. std::unique_ptr createSubscriptionsRequest(); // Creates a VehiclePropValue containing a message of type VmsMessageType.DATA. @@ -202,21 +202,21 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response); // Returns true if the new sequence number is greater than the last seen // sequence number. -bool isSequenceNumberNewer(const VehiclePropValue& subscription_change, +bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state, const int last_seen_sequence_number); // Returns sequence number of the message. -int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change); +int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state); -// Takes a subscription change message and returns the layers that have active +// Takes a subscriptions state message and returns the layers that have active // subscriptions of the layers that are offered by your HAL client/publisher. // -// A publisher can use this function when receiving a subscription change message -// to determine which layers to publish data on. +// A publisher can use this function when receiving a subscriptions response or subscriptions +// change message to determine which layers to publish data on. // The caller of this function can optionally decide to not consume these layers // if the subscription change has the sequence number less than the last seen // sequence number. -std::vector getSubscribedLayers(const VehiclePropValue& subscription_change, +std::vector getSubscribedLayers(const VehiclePropValue& subscriptions_state, const VmsOffers& offers); // Takes an availability change message and returns true if the parsed message implies that diff --git a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp index d346206c35..9eba905901 100644 --- a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp +++ b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp @@ -194,32 +194,35 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response) return -1; } -bool isSequenceNumberNewer(const VehiclePropValue& subscription_change, +bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state, const int last_seen_sequence_number) { - return (isValidVmsMessage(subscription_change) && - parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE && - subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex && - subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex] > + return (isValidVmsMessage(subscriptions_state) && + (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE || + parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) && + subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex && + subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex] > last_seen_sequence_number); } -int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change) { - if (isValidVmsMessage(subscription_change) && - parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE && - subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) { - return subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex]; +int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state) { + if (isValidVmsMessage(subscriptions_state) && + (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE || + parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) && + subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) { + return subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex]; } return -1; } -std::vector getSubscribedLayers(const VehiclePropValue& subscription_change, +std::vector getSubscribedLayers(const VehiclePropValue& subscriptions_state, const VmsOffers& offers) { - if (isValidVmsMessage(subscription_change) && - parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE && - subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) { - const int32_t num_of_layers = subscription_change.value.int32Values[toInt( + if (isValidVmsMessage(subscriptions_state) && + (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE || + parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) && + subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) { + const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt( VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)]; - const int32_t num_of_associated_layers = subscription_change.value.int32Values[toInt( + const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt( VmsSubscriptionsStateIntegerValuesIndex ::NUMBER_OF_ASSOCIATED_LAYERS)]; std::unordered_set offered_layers; @@ -231,9 +234,9 @@ std::vector getSubscribedLayers(const VehiclePropValue& subscription_c int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START); // Add all subscribed layers which are offered by the current publisher. for (int i = 0; i < num_of_layers; i++) { - VmsLayer layer = VmsLayer(subscription_change.value.int32Values[current_index], - subscription_change.value.int32Values[current_index + 1], - subscription_change.value.int32Values[current_index + 2]); + VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index], + subscriptions_state.value.int32Values[current_index + 1], + subscriptions_state.value.int32Values[current_index + 2]); if (offered_layers.find(layer) != offered_layers.end()) { subscribed_layers.push_back(layer); } @@ -243,15 +246,15 @@ std::vector getSubscribedLayers(const VehiclePropValue& subscription_c // For this, we need to check if the associated layer has a publisher ID which is // same as that of the current publisher. for (int i = 0; i < num_of_associated_layers; i++) { - VmsLayer layer = VmsLayer(subscription_change.value.int32Values[current_index], - subscription_change.value.int32Values[current_index + 1], - subscription_change.value.int32Values[current_index + 2]); + VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index], + subscriptions_state.value.int32Values[current_index + 1], + subscriptions_state.value.int32Values[current_index + 2]); current_index += kLayerSize; if (offered_layers.find(layer) != offered_layers.end()) { - int32_t num_of_publisher_ids = subscription_change.value.int32Values[current_index]; + int32_t num_of_publisher_ids = subscriptions_state.value.int32Values[current_index]; current_index++; for (int j = 0; j < num_of_publisher_ids; j++) { - if (subscription_change.value.int32Values[current_index] == + if (subscriptions_state.value.int32Values[current_index] == offers.publisher_id) { subscribed_layers.push_back(layer); } diff --git a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp index 7189212505..8b547f1733 100644 --- a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp +++ b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp @@ -214,57 +214,82 @@ TEST(VmsUtilsTest, invalidPublisherIdResponse) { EXPECT_EQ(parsePublisherIdResponse(*message), -1); } -TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsState) { +TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsChange) { auto message = createBaseVmsMessage(2); message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234}; EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234); } +TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsResponse) { + auto message = createBaseVmsMessage(2); + message->value.int32Values = + hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234}; + EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234); +} + TEST(VmsUtilsTest, invalidSubscriptionsState) { auto message = createBaseVmsMessage(1); EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), -1); } -TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumber) { +TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForChange) { auto message = createBaseVmsMessage(2); message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234}; EXPECT_TRUE(isSequenceNumberNewer(*message, 1233)); } -TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumber) { +TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForResponse) { + auto message = createBaseVmsMessage(2); + message->value.int32Values = + hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234}; + EXPECT_TRUE(isSequenceNumberNewer(*message, 1233)); +} + +TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForChange) { auto message = createBaseVmsMessage(2); message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234}; EXPECT_FALSE(isSequenceNumberNewer(*message, 1235)); } -TEST(VmsUtilsTest, newSequenceNumberForSameNumber) { +TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForResponse) { + auto message = createBaseVmsMessage(2); + message->value.int32Values = + hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234}; + EXPECT_FALSE(isSequenceNumberNewer(*message, 1235)); +} + +TEST(VmsUtilsTest, newSequenceNumberForSameNumberForChange) { auto message = createBaseVmsMessage(2); message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234}; EXPECT_FALSE(isSequenceNumberNewer(*message, 1234)); } -TEST(VmsUtilsTest, subscribedLayers) { +TEST(VmsUtilsTest, newSequenceNumberForSameNumberForResponse) { + auto message = createBaseVmsMessage(2); + message->value.int32Values = + hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234}; + EXPECT_FALSE(isSequenceNumberNewer(*message, 1234)); +} + +void testSubscribedLayers(VmsMessageType type) { VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}), VmsLayerOffering(VmsLayer(2, 0, 1))}}; auto message = createBaseVmsMessage(2); - message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), + message->value.int32Values = hidl_vec{toInt(type), 1234, // sequence number 2, // number of layers 1, // number of associated layers 1, // layer 1 - 0, - 1, + 0, 1, 4, // layer 2 - 1, - 1, + 1, 1, 2, // associated layer - 0, - 1, + 0, 1, 2, // number of publisher IDs 111, // publisher IDs 123}; @@ -275,10 +300,18 @@ TEST(VmsUtilsTest, subscribedLayers) { EXPECT_EQ(result.at(1), VmsLayer(2, 0, 1)); } -TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) { +TEST(VmsUtilsTest, subscribedLayersForChange) { + testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_CHANGE); +} + +TEST(VmsUtilsTest, subscribedLayersForResponse) { + testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE); +} + +void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) { VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}}; auto message = createBaseVmsMessage(2); - message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), + message->value.int32Values = hidl_vec{toInt(type), 1234, // sequence number 1, // number of layers 0, // number of associated layers @@ -289,36 +322,58 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) { EXPECT_TRUE(getSubscribedLayers(*message, offers).empty()); } -TEST(VmsUtilsTest, subscribedLayersWithDifferentVersion) { +TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForChange) { + testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_CHANGE); +} + +TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForResponse) { + testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_RESPONSE); +} + +void subscribedLayersWithDifferentVersion(VmsMessageType type) { VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}}; auto message = createBaseVmsMessage(2); - message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), - 1234, // sequence number - 1, // number of layers - 0, // number of associated layers - 1, // layer 1 - 0, - 2}; // different version + message->value.int32Values = hidl_vec{toInt(type), + 1234, // sequence number + 1, // number of layers + 0, // number of associated layers + 1, // layer 1 + 0, 2}; // different version EXPECT_TRUE(isValidVmsMessage(*message)); EXPECT_TRUE(getSubscribedLayers(*message, offers).empty()); } -TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherId) { +TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForChange) { + subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_CHANGE); +} + +TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForResponse) { + subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_RESPONSE); +} + +void subscribedLayersWithDifferentPublisherId(VmsMessageType type) { VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}}; auto message = createBaseVmsMessage(2); - message->value.int32Values = hidl_vec{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), + message->value.int32Values = hidl_vec{toInt(type), 1234, // sequence number 0, // number of layers 1, // number of associated layers 1, // associated layer 1 - 0, - 1, + 0, 1, 1, // number of publisher IDs 234}; // publisher ID 1 EXPECT_TRUE(isValidVmsMessage(*message)); EXPECT_TRUE(getSubscribedLayers(*message, offers).empty()); } +TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForChange) { + subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_CHANGE); +} + +TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForResponse) { + subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_RESPONSE); +} + TEST(VmsUtilsTest, serviceNewlyStarted) { auto message = createBaseVmsMessage(2); message->value.int32Values = hidl_vec{toInt(VmsMessageType::AVAILABILITY_CHANGE), 0}; diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index 666653b261..8ddc380229 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -101,11 +101,20 @@ namespace implementation { std::unique_ptr legacySubSamples = std::make_unique(subSamples.size()); + size_t destSize = 0; for (size_t i = 0; i < subSamples.size(); i++) { - legacySubSamples[i].mNumBytesOfClearData - = subSamples[i].numBytesOfClearData; - legacySubSamples[i].mNumBytesOfEncryptedData - = subSamples[i].numBytesOfEncryptedData; + uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData; + legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData; + uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData; + legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData; + if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow"); + return Void(); + } + if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow"); + return Void(); + } } AString detailMessage; @@ -137,11 +146,24 @@ namespace implementation { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } + + if (destSize > destBuffer.size) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large"); + return Void(); + } + destPtr = static_cast(base + destination.nonsecureMemory.offset); } else if (destination.type == BufferType::NATIVE_HANDLE) { + if (!secure) { + _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure"); + return Void(); + } native_handle_t *handle = const_cast( destination.secureMemory.getNativeHandle()); destPtr = static_cast(handle); + } else { + _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); + return Void(); } ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), legacyMode, legacyPattern, srcPtr, legacySubSamples.get(), diff --git a/media/omx/1.0/vts/functional/README.md b/media/omx/1.0/vts/functional/README.md index acffc42943..274b30d8be 100644 --- a/media/omx/1.0/vts/functional/README.md +++ b/media/omx/1.0/vts/functional/README.md @@ -18,17 +18,17 @@ This folder includes test fixtures associated with testing audio encoder and dec usage: -VtsHalMediaOmxV1\_0TargetAudioDecTest -I default -C -R audio_decoder. -P /sdcard/media/ +VtsHalMediaOmxV1\_0TargetAudioDecTest -I default -C -R audio_decoder. -P /data/local/tmp/media/ -VtsHalMediaOmxV1\_0TargetAudioEncTest -I default -C -R audio_encoder. -P /sdcard/media/ +VtsHalMediaOmxV1\_0TargetAudioEncTest -I default -C -R audio_encoder. -P /data/local/tmp/media/ #### video : This folder includes test fixtures associated with testing video encoder and decoder components such as simple encoding of a raw clip or decoding of an elementary stream, end of stream test, timestamp deviations test, flush test and so on. These tests are aimed towards testing the plugin that connects the component to the omx core. usage: -VtsHalMediaOmxV1\_0TargetVideoDecTest -I default -C -R video_decoder. -P /sdcard/media/ +VtsHalMediaOmxV1\_0TargetVideoDecTest -I default -C -R video_decoder. -P /data/local/tmp/media/ -VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C -R video_encoder. -P /sdcard/media/ +VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C -R video_encoder. -P /data/local/tmp/media/ -While tesing audio/video encoder, decoder components, test fixtures require input files. These input are files are present in the folder 'res'. Before running the tests all the files in 'res' have to be placed in '/media/sdcard/' or a path of your choice and this path needs to be provided as an argument to the test application \ No newline at end of file +While tesing audio/video encoder, decoder components, test fixtures require input files. These input are files are present in the folder 'res'. Before running the tests all the files in 'res' have to be placed in '/data/local/tmp/media' or a path of your choice and this path needs to be provided as an argument to the test application diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp index cdc52fb477..5a79e55426 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 @@ cc_library_static { "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 @@ cc_defaults { 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 f299e36f23..8d4c022013 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 #include +#include #include #include +#include +#include #include #include #include @@ -31,7 +34,9 @@ #include #include #include -#include + +#include +#include using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::PixelFormat; @@ -195,67 +200,104 @@ void allocateGraphicBuffers(sp omxNode, OMX_U32 portIndex, BufferInfo* buffer, uint32_t nFrameWidth, uint32_t nFrameHeight, int32_t* nStride, int format) { - android::hardware::media::omx::V1_0::Status status; - sp allocator = - android::hardware::graphics::allocator::V2_0::IAllocator::getService(); - ASSERT_NE(nullptr, allocator.get()); + struct AllocatorV2 : public GrallocV2 { + sp mAllocator; + sp mMapper; + AllocatorV2(sp&& allocator, sp&& mapper) + : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {} + AllocatorV2() = default; + }; + struct AllocatorV3 : public GrallocV3 { + sp mAllocator; + sp mMapper; + AllocatorV3(sp&& allocator, sp&& mapper) + : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {} + AllocatorV3() = default; + }; + std::variant grallocVar; - sp mapper = - android::hardware::graphics::mapper::V2_0::IMapper::getService(); - ASSERT_NE(mapper.get(), nullptr); + sp mapper2{}; + sp mapper3{}; + sp allocator2{}; + sp 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(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(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(format); - descriptorInfo.usage = static_cast(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 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 _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(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(android_atomic_inc(&nextId)); - }); + std::visit([buffer, nFrameWidth, nFrameHeight, format, usage, nStride](auto&& gralloc) { + using Gralloc = std::remove_reference_t; + 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); + 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(descriptorInfo.format); + buffer->omxBuffer.attr.anwBuffer.usage = + static_cast(descriptorInfo.usage); + buffer->omxBuffer.attr.anwBuffer.layerCount = + descriptorInfo.layerCount; + buffer->omxBuffer.attr.anwBuffer.id = + (static_cast(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 1575ba252e..ac077a3c76 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -288,6 +298,36 @@ Return setPortConfig( /* * 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 setRole( sp omxNode, const char* role); @@ -368,7 +408,7 @@ class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { public: virtual void registerTestServices() override { registerTestService(); } - ComponentTestEnvironment() : res("/sdcard/media/") {} + ComponentTestEnvironment() : res("/data/local/tmp/media/") {} void setComponent(const char* _component) { component = _component; } 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 a740a8093b..2280cee8c2 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 @@ using ::android::sp; #include #include #include +#include static ComponentTestEnvironment* gEnv = nullptr; @@ -364,6 +365,61 @@ Return DummyBufferSource::onInputBufferEmptied( return Void(); }; +// Variant of mappers +struct MapperV2 : public GrallocV2 { + sp mMapper; + MapperV2(sp&& mapper): mMapper{std::move(mapper)} {} + MapperV2() = default; + android::hardware::Return 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 mMapper; + MapperV3(sp&& mapper): mMapper{std::move(mapper)} {} + MapperV3() = default; + android::hardware::Return 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; +// Initializes the MapperVar by trying services of different versions. +bool initialize(MapperVar& mapperVar) { + sp mapper3 = + android::hardware::graphics::mapper::V3_0::IMapper::getService(); + if (mapper3) { + mapperVar.emplace(std::move(mapper3)); + return true; + } + sp mapper2 = + android::hardware::graphics::mapper::V2_0::IMapper::getService(); + if (mapper2) { + mapperVar.emplace(std::move(mapper2)); + return true; + } + return false; +} + // request VOP refresh void requestIDR(sp omxNode, OMX_U32 portIndex) { android::hardware::media::omx::V1_0::Status status; @@ -574,150 +630,166 @@ void waitOnInputConsumption(sp omxNode, sp observer, int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format, std::ifstream& eleStream) { - sp 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(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(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(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(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; + 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( + 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(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(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(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(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 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; + 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 omxNode,