[automerger skipped] Merge "Add CAS AIDL/HIDL support for Tuner Descrambler Tests" into main am: 658276f781 -s ours am: 65a8abc93e -s ours
am skip reason: Merged-In I55074360587735256c4f0efa8228d28f57b21592 with SHA-1 e8730a7113 is already in history
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2733317
Change-Id: I3579f171467bb7139331b0687737771412d2ab92
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 356673f..790d60b 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -32,11 +32,11 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <broadcastradio-utils-aidl/Utils.h>
-#include <broadcastradio-vts-utils/mock-timeout.h>
#include <cutils/bitops.h>
#include <gmock/gmock.h>
#include <chrono>
+#include <condition_variable>
#include <optional>
#include <regex>
@@ -61,11 +61,6 @@
namespace bcutils = ::aidl::android::hardware::broadcastradio::utils;
-inline constexpr std::chrono::seconds kTuneTimeoutSec =
- std::chrono::seconds(IBroadcastRadio::TUNER_TIMEOUT_MS * 1000);
-inline constexpr std::chrono::seconds kProgramListScanTimeoutSec =
- std::chrono::seconds(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS * 1000);
-
const ConfigFlag kConfigFlagValues[] = {
ConfigFlag::FORCE_MONO,
ConfigFlag::FORCE_ANALOG,
@@ -108,20 +103,68 @@
} // namespace
-class TunerCallbackMock : public BnTunerCallback {
+class CallbackFlag final {
public:
- TunerCallbackMock();
+ CallbackFlag(int timeoutMs) { mTimeoutMs = timeoutMs; }
+ /**
+ * Notify that the callback is called.
+ */
+ void notify() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCalled = true;
+ lock.unlock();
+ mCv.notify_all();
+ };
+
+ /**
+ * Wait for the timeout passed into the constructor.
+ */
+ bool wait() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ return mCv.wait_for(lock, std::chrono::milliseconds(mTimeoutMs),
+ [this] { return mCalled; });
+ };
+
+ /**
+ * Reset the callback to not called.
+ */
+ void reset() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCalled = false;
+ }
+
+ private:
+ std::mutex mMutex;
+ bool mCalled GUARDED_BY(mMutex) = false;
+ std::condition_variable mCv;
+ int mTimeoutMs;
+};
+
+class TunerCallbackImpl final : public BnTunerCallback {
+ public:
+ TunerCallbackImpl();
ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
- MOCK_TIMEOUT_METHOD1(onCurrentProgramInfoChangedMock, ScopedAStatus(const ProgramInfo&));
ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
- MOCK_METHOD1(onAntennaStateChange, ScopedAStatus(bool connected));
- MOCK_METHOD1(onParametersUpdated, ScopedAStatus(const vector<VendorKeyValue>& parameters));
- MOCK_METHOD2(onConfigFlagUpdated, ScopedAStatus(ConfigFlag in_flag, bool in_value));
- MOCK_TIMEOUT_METHOD0(onProgramListReady, void());
+ ScopedAStatus onParametersUpdated(const vector<VendorKeyValue>& parameters) override;
+ ScopedAStatus onAntennaStateChange(bool connected) override;
+ ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override;
+ bool waitOnCurrentProgramInfoChangedCallback();
+ bool waitProgramReady();
+ void reset();
+
+ bool getAntennaConnectionState();
+ ProgramInfo getCurrentProgramInfo();
+ bcutils::ProgramInfoSet getProgramList();
+
+ private:
std::mutex mLock;
+ bool mAntennaConnectionState GUARDED_BY(mLock);
+ ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock);
bcutils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
+ CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS);
+ CallbackFlag mOnProgramListReadyFlag = CallbackFlag(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS);
};
struct AnnouncementListenerMock : public BnAnnouncementListener {
@@ -139,7 +182,7 @@
std::shared_ptr<IBroadcastRadio> mModule;
Properties mProperties;
- std::shared_ptr<TunerCallbackMock> mCallback = SharedRefBase::make<TunerCallbackMock>();
+ std::shared_ptr<TunerCallbackImpl> mCallback;
};
MATCHER_P(InfoHasId, id, string(negation ? "does not contain" : "contains") + " " + id.toString()) {
@@ -147,20 +190,18 @@
return ids.end() != find(ids.begin(), ids.end(), id.value);
}
-TunerCallbackMock::TunerCallbackMock() {
- EXPECT_TIMEOUT_CALL(*this, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
-
- // we expect the antenna is connected through the whole test
- EXPECT_CALL(*this, onAntennaStateChange(false)).Times(0);
+TunerCallbackImpl::TunerCallbackImpl() {
+ mAntennaConnectionState = true;
}
-ScopedAStatus TunerCallbackMock::onTuneFailed(Result result, const ProgramSelector& selector) {
+ScopedAStatus TunerCallbackImpl::onTuneFailed(Result result, const ProgramSelector& selector) {
LOG(DEBUG) << "Tune failed for selector" << selector.toString();
EXPECT_TRUE(result == Result::CANCELED);
return ndk::ScopedAStatus::ok();
}
-ScopedAStatus TunerCallbackMock::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+ScopedAStatus TunerCallbackImpl::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+ LOG(DEBUG) << "onCurrentProgramInfoChanged called";
for (const auto& id : info.selector) {
EXPECT_NE(id.type, IdentifierType::INVALID);
}
@@ -196,21 +237,75 @@
}
}
- return onCurrentProgramInfoChangedMock(info);
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ mCurrentProgramInfo = info;
+ }
+
+ mOnCurrentProgramInfoChangedFlag.notify();
+ return ndk::ScopedAStatus::ok();
}
-ScopedAStatus TunerCallbackMock::onProgramListUpdated(const ProgramListChunk& chunk) {
- std::lock_guard<std::mutex> lk(mLock);
-
- updateProgramList(chunk, &mProgramList);
+ScopedAStatus TunerCallbackImpl::onProgramListUpdated(const ProgramListChunk& chunk) {
+ LOG(DEBUG) << "onProgramListUpdated called";
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ updateProgramList(chunk, &mProgramList);
+ }
if (chunk.complete) {
- onProgramListReady();
+ mOnProgramListReadyFlag.notify();
}
return ndk::ScopedAStatus::ok();
}
+ScopedAStatus TunerCallbackImpl::onParametersUpdated(
+ [[maybe_unused]] const vector<VendorKeyValue>& parameters) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onAntennaStateChange(bool connected) {
+ if (!connected) {
+ std::lock_guard<std::mutex> lk(mLock);
+ mAntennaConnectionState = false;
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onConfigFlagUpdated([[maybe_unused]] ConfigFlag in_flag,
+ [[maybe_unused]] bool in_value) {
+ return ndk::ScopedAStatus::ok();
+}
+
+bool TunerCallbackImpl::waitOnCurrentProgramInfoChangedCallback() {
+ return mOnCurrentProgramInfoChangedFlag.wait();
+}
+
+bool TunerCallbackImpl::waitProgramReady() {
+ return mOnProgramListReadyFlag.wait();
+}
+
+void TunerCallbackImpl::reset() {
+ mOnCurrentProgramInfoChangedFlag.reset();
+ mOnProgramListReadyFlag.reset();
+}
+
+bool TunerCallbackImpl::getAntennaConnectionState() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return mAntennaConnectionState;
+}
+
+ProgramInfo TunerCallbackImpl::getCurrentProgramInfo() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return mCurrentProgramInfo;
+}
+
+bcutils::ProgramInfoSet TunerCallbackImpl::getProgramList() {
+ std::lock_guard<std::mutex> lk(mLock);
+ return mProgramList;
+}
+
void BroadcastRadioHalTest::SetUp() {
EXPECT_EQ(mModule.get(), nullptr) << "Module is already open";
@@ -228,6 +323,8 @@
EXPECT_FALSE(mProperties.product.empty());
EXPECT_GT(mProperties.supportedIdentifierTypes.size(), 0u);
+ mCallback = SharedRefBase::make<TunerCallbackImpl>();
+
// set callback
EXPECT_TRUE(mModule->setTunerCallback(mCallback).isOk());
}
@@ -236,6 +333,11 @@
if (mModule) {
ASSERT_TRUE(mModule->unsetTunerCallback().isOk());
}
+ if (mCallback) {
+ // we expect the antenna is connected through the whole test
+ EXPECT_TRUE(mCallback->getAntennaConnectionState());
+ mCallback = nullptr;
+ }
}
bool BroadcastRadioHalTest::getAmFmRegionConfig(bool full, AmFmRegionConfig* config) {
@@ -256,7 +358,7 @@
std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
const ProgramFilter& filter) {
- EXPECT_TIMEOUT_CALL(*mCallback, onProgramListReady).Times(AnyNumber());
+ mCallback->reset();
auto startResult = mModule->startProgramListUpdates(filter);
@@ -268,13 +370,13 @@
if (!startResult.isOk()) {
return std::nullopt;
}
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onProgramListReady, kProgramListScanTimeoutSec);
+ EXPECT_TRUE(mCallback->waitProgramReady());
auto stopResult = mModule->stopProgramListUpdates();
EXPECT_TRUE(stopResult.isOk());
- return mCallback->mProgramList;
+ return mCallback->getProgramList();
}
/**
@@ -456,7 +558,7 @@
* - if it is supported, the test is ignored;
*/
TEST_P(BroadcastRadioHalTest, TuneFailsWithNotSupported) {
- LOG(DEBUG) << "TuneFailsWithInvalid Test";
+ LOG(DEBUG) << "TuneFailsWithNotSupported Test";
vector<ProgramIdentifier> supportTestId = {
makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0), // invalid
@@ -477,9 +579,9 @@
for (const auto& id : supportTestId) {
ProgramSelector sel{id, {}};
- auto result = mModule->tune(sel);
-
if (!bcutils::isSupported(mProperties, sel)) {
+ auto result = mModule->tune(sel);
+
EXPECT_EQ(result.getServiceSpecificError(), notSupportedError);
}
}
@@ -508,9 +610,9 @@
for (const auto& id : invalidId) {
ProgramSelector sel{id, {}};
- auto result = mModule->tune(sel);
-
if (bcutils::isSupported(mProperties, sel)) {
+ auto result = mModule->tune(sel);
+
EXPECT_EQ(result.getServiceSpecificError(), invalidArgumentsError);
}
}
@@ -549,13 +651,7 @@
int64_t freq = 90900; // 90.9 FM
ProgramSelector sel = makeSelectorAmfm(freq);
// try tuning
- ProgramInfo infoCb = {};
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock,
- InfoHasId(makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq)))
- .Times(AnyNumber())
- .WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(ndk::ScopedAStatus::ok()))))
- .WillRepeatedly(testing::InvokeWithoutArgs([] { return ndk::ScopedAStatus::ok(); }));
-
+ mCallback->reset();
auto result = mModule->tune(sel);
// expect a failure if it's not supported
@@ -566,7 +662,8 @@
// expect a callback if it succeeds
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
LOG(DEBUG) << "Current program info: " << infoCb.toString();
@@ -638,12 +735,6 @@
}
// try tuning
- ProgramInfo infoCb = {};
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock,
- InfoHasId(makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq)))
- .Times(AnyNumber())
- .WillOnce(
- DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(ndk::ScopedAStatus::ok()))));
auto result = mModule->tune(sel);
@@ -655,7 +746,9 @@
// expect a callback if it succeeds
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+
LOG(DEBUG) << "Current program info: " << infoCb.toString();
// it should tune exactly to what was requested
@@ -669,13 +762,13 @@
*
* Verifies that:
* - the method succeeds;
- * - the program info is changed within kTuneTimeoutSec;
+ * - the program info is changed within kTuneTimeoutMs;
* - works both directions and with or without skipping sub-channel.
*/
TEST_P(BroadcastRadioHalTest, Seek) {
LOG(DEBUG) << "Seek Test";
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+ mCallback->reset();
auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
@@ -685,14 +778,14 @@
}
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+ mCallback->reset();
result = mModule->seek(/* in_directionUp= */ false, /* in_skipSubChannel= */ false);
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
}
/**
@@ -720,13 +813,13 @@
*
* Verifies that:
* - the method succeeds or returns NOT_SUPPORTED;
- * - the program info is changed within kTuneTimeoutSec if the method succeeded;
+ * - the program info is changed within kTuneTimeoutMs if the method succeeded;
* - works both directions.
*/
TEST_P(BroadcastRadioHalTest, Step) {
LOG(DEBUG) << "Step Test";
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+ mCallback->reset();
auto result = mModule->step(/* in_directionUp= */ true);
@@ -735,14 +828,14 @@
return;
}
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+ mCallback->reset();
result = mModule->step(/* in_directionUp= */ false);
EXPECT_TRUE(result.isOk());
- EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
}
/**
@@ -904,13 +997,12 @@
LOG(DEBUG) << "SetConfigFlags Test";
auto get = [&](ConfigFlag flag) -> bool {
- bool* gotValue = nullptr;
+ bool gotValue;
- auto halResult = mModule->isConfigFlagSet(flag, gotValue);
+ auto halResult = mModule->isConfigFlagSet(flag, &gotValue);
- EXPECT_FALSE(gotValue == nullptr);
EXPECT_TRUE(halResult.isOk());
- return *gotValue;
+ return gotValue;
};
auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
@@ -955,7 +1047,7 @@
*
* Verifies that:
* - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
- * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
* - stopProgramListUpdates does not crash.
*/
TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
@@ -969,7 +1061,7 @@
*
* Verifies that:
* - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
- * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
* - stopProgramListUpdates does not crash;
* - result for startProgramListUpdates using a filter with AMFM_FREQUENCY_KHZ value of the first
* AMFM program matches the expected result.
@@ -1017,7 +1109,7 @@
*
* Verifies that:
* - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
- * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
* - stopProgramListUpdates does not crash;
* - result for startProgramListUpdates using a filter with DAB_ENSEMBLE value of the first DAB
* program matches the expected result.
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index aee5366..2845180 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -551,6 +551,11 @@
stream.rotation = StreamRotation::ROTATION_0;
stream.dynamicRangeProfile = RequestAvailableDynamicRangeProfilesMap::
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+ stream.useCase = ScalerAvailableStreamUseCases::
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ stream.colorSpace = static_cast<int>(
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
std::vector<Stream> streams = {stream};
StreamConfiguration config;
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 7665f79..08ad0bb 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -45,8 +45,6 @@
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::ICameraDevice;
using ::aidl::android::hardware::camera::metadata::CameraMetadataTag;
-using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
-using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
using ::aidl::android::hardware::camera::metadata::SensorInfoColorFilterArrangement;
using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
@@ -2237,21 +2235,26 @@
}
std::vector<Stream> streams(1);
- streams[0] = {0,
- StreamType::OUTPUT,
- outputPreviewStreams[0].width,
- outputPreviewStreams[0].height,
- static_cast<PixelFormat>(outputPreviewStreams[0].format),
- static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_CPU_READ),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- std::string(),
- 0,
- -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+ streams[0] = {
+ 0,
+ StreamType::OUTPUT,
+ outputPreviewStreams[0].width,
+ outputPreviewStreams[0].height,
+ static_cast<PixelFormat>(outputPreviewStreams[0].format),
+ static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_CPU_READ),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ 0,
+ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ static_cast<int>(
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
int32_t streamConfigCounter = 0;
CameraMetadata req;
@@ -2395,7 +2398,11 @@
/*groupId*/ -1,
{SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ static_cast<int>(
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
StreamConfiguration config;
config.streams = streams;
@@ -2726,21 +2733,26 @@
std::vector<Stream> streams(physicalIds.size());
int32_t streamId = 0;
for (auto const& physicalId : physicalIds) {
- streams[streamId] = {streamId,
- StreamType::OUTPUT,
- outputPreviewStreams[0].width,
- outputPreviewStreams[0].height,
- static_cast<PixelFormat>(outputPreviewStreams[0].format),
- static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- physicalId,
- 0,
- -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+ streams[streamId] = {
+ streamId,
+ StreamType::OUTPUT,
+ outputPreviewStreams[0].width,
+ outputPreviewStreams[0].height,
+ static_cast<PixelFormat>(outputPreviewStreams[0].format),
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ physicalId,
+ 0,
+ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ static_cast<int>(
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
streamId++;
}
@@ -2799,7 +2811,8 @@
bool* supportsPartialResults, int32_t* partialResultCount,
bool* useHalBufManager, std::shared_ptr<DeviceCb>* outCb,
uint32_t streamConfigCounter, bool maxResolution,
- RequestAvailableDynamicRangeProfilesMap prof) {
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProf,
+ RequestAvailableColorSpaceProfilesMap colorSpaceProf) {
ASSERT_NE(nullptr, session);
ASSERT_NE(nullptr, halStreams);
ASSERT_NE(nullptr, previewStream);
@@ -2881,7 +2894,9 @@
-1,
{maxResolution ? SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION
: SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- prof};
+ dynamicRangeProf,
+ ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ static_cast<int>(colorSpaceProf)};
StreamConfiguration config;
config.streams = streams;
@@ -3332,7 +3347,11 @@
/*groupId*/ 0,
{SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ static_cast<int>(
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE, CameraMetadata()};
@@ -3447,15 +3466,12 @@
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
- previewStream.usage =
- static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
- previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
- previewStream.colorSpace = static_cast<int32_t>(colorSpace);
+ previewStream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
- &previewStream, &halStreams, &supportsPartialResults,
- &partialResultCount, &useHalBufManager, &cb, 0,
- /*maxResolution*/ false, dynamicRangeProfile);
+ &previewStream, &halStreams, &supportsPartialResults, &partialResultCount,
+ &useHalBufManager, &cb, 0,
+ /*maxResolution*/ false, dynamicRangeProfile, colorSpace);
ASSERT_NE(mSession, nullptr);
::aidl::android::hardware::common::fmq::MQDescriptor<
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index 588cb50..6f8f380 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -77,6 +77,9 @@
using ::aidl::android::hardware::camera::device::StreamBufferRet;
using ::aidl::android::hardware::camera::device::StreamConfiguration;
using ::aidl::android::hardware::camera::device::StreamConfigurationMode;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
+using ::aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
using ::aidl::android::hardware::camera::provider::ICameraProvider;
@@ -205,10 +208,12 @@
bool* supportsPartialResults /*out*/, int32_t* partialResultCount /*out*/,
bool* useHalBufManager /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/,
uint32_t streamConfigCounter, bool maxResolution,
- aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
- prof = ::aidl::android::hardware::camera::metadata::
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProf =
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ RequestAvailableColorSpaceProfilesMap colorSpaceProf =
+ RequestAvailableColorSpaceProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
void configurePreviewStreams(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
@@ -376,8 +381,7 @@
static void get10BitDynamicRangeProfiles(
const camera_metadata_t* staticMeta,
- std::vector<aidl::android::hardware::camera::metadata::
- RequestAvailableDynamicRangeProfilesMap>* profiles);
+ std::vector<RequestAvailableDynamicRangeProfilesMap>* profiles);
static bool reportsColorSpaces(const camera_metadata_t* staticMeta);
@@ -387,17 +391,13 @@
RequestAvailableColorSpaceProfilesMap>* profiles);
static bool isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
- const camera_metadata_t* staticMeta,
- aidl::android::hardware::camera::metadata::
- RequestAvailableColorSpaceProfilesMap colorSpace,
- aidl::android::hardware::camera::metadata::
+ const camera_metadata_t* staticMeta, RequestAvailableColorSpaceProfilesMap colorSpace,
RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile,
aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
- static const char* getColorSpaceProfileString(aidl::android::hardware::camera::metadata::
- RequestAvailableColorSpaceProfilesMap colorSpace);
+ static const char* getColorSpaceProfileString(RequestAvailableColorSpaceProfilesMap colorSpace);
- static const char* getDynamicRangeProfileString(aidl::android::hardware::camera::metadata::
+ static const char* getDynamicRangeProfileString(
RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
static int32_t halFormatToPublicFormat(
@@ -408,10 +408,8 @@
static Size getMinSize(Size a, Size b);
- void processColorSpaceRequest(aidl::android::hardware::camera::metadata::
- RequestAvailableColorSpaceProfilesMap colorSpace,
- aidl::android::hardware::camera::metadata::
- RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
+ void processColorSpaceRequest(RequestAvailableColorSpaceProfilesMap colorSpace,
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
void processZoomSettingsOverrideRequests(
int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
@@ -571,10 +569,8 @@
static bool matchDeviceName(const std::string& deviceName, const std::string& providerType,
std::string* deviceVersion, std::string* cameraId);
- static void verify10BitMetadata(
- HandleImporter& importer, const InFlightRequest& request,
- aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
- profile);
+ static void verify10BitMetadata(HandleImporter& importer, const InFlightRequest& request,
+ RequestAvailableDynamicRangeProfilesMap profile);
static void waitForReleaseFence(
std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers);
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index da31888..872099a 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -566,6 +566,14 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.threadnetwork</name>
+ <version>1</version>
+ <interface>
+ <name>IThreadChip</name>
+ <instance>chip0</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.tv.hdmi.cec</name>
<version>1</version>
<interface>
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index b047220..269abd1 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -129,33 +129,20 @@
return {false, graphicBuffer};
}
- uint64_t getStableDisplayId(int64_t display) {
- const auto& [status, identification] =
- mComposerClient->getDisplayIdentificationData(display);
- EXPECT_TRUE(status.isOk());
-
- if (const auto info = ::android::parseDisplayIdentificationData(
- static_cast<uint8_t>(identification.port), identification.data)) {
- return info->id.value;
- }
-
- return ::android::PhysicalDisplayId::fromPort(static_cast<uint8_t>(identification.port))
- .value;
- }
-
// Gets the per-display XML config
std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXml(int64_t display) {
- std::stringstream pathBuilder;
- pathBuilder << "/vendor/etc/displayconfig/display_id_" << getStableDisplayId(display)
- << ".xml";
- const std::string path = pathBuilder.str();
- auto document = std::make_unique<tinyxml2::XMLDocument>();
- const tinyxml2::XMLError error = document->LoadFile(path.c_str());
- if (error == tinyxml2::XML_SUCCESS) {
+
+ if (auto document = getDisplayConfigXmlByStableId(getStableDisplayId(display));
+ document != nullptr) {
return document;
- } else {
- return nullptr;
}
+
+ // Fallback to looking up a per-port config if no config exists for the full ID
+ if (auto document = getDisplayConfigXmlByPort(getPort(display)); document != nullptr) {
+ return document;
+ }
+
+ return nullptr;
}
// Gets the max display brightness for this display.
@@ -256,6 +243,53 @@
}
}
}
+
+ uint8_t getPort(int64_t display) {
+ const auto& [status, identification] =
+ mComposerClient->getDisplayIdentificationData(display);
+ EXPECT_TRUE(status.isOk());
+ return static_cast<uint8_t>(identification.port);
+ }
+
+ uint64_t getStableDisplayId(int64_t display) {
+ const auto& [status, identification] =
+ mComposerClient->getDisplayIdentificationData(display);
+ EXPECT_TRUE(status.isOk());
+
+ if (const auto info = ::android::parseDisplayIdentificationData(
+ static_cast<uint8_t>(identification.port), identification.data)) {
+ return info->id.value;
+ }
+
+ return ::android::PhysicalDisplayId::fromPort(static_cast<uint8_t>(identification.port))
+ .value;
+ }
+
+ std::unique_ptr<tinyxml2::XMLDocument> loadXml(const std::string& path) {
+ auto document = std::make_unique<tinyxml2::XMLDocument>();
+ const tinyxml2::XMLError error = document->LoadFile(path.c_str());
+ if (error != tinyxml2::XML_SUCCESS) {
+ ALOGD("%s: Failed to load config file: %s", __func__, path.c_str());
+ return nullptr;
+ }
+
+ ALOGD("%s: Successfully loaded config file: %s", __func__, path.c_str());
+ return document;
+ }
+
+ std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXmlByPort(uint8_t port) {
+ std::stringstream pathBuilder;
+ pathBuilder << "/vendor/etc/displayconfig/display_port_" << static_cast<uint32_t>(port)
+ << ".xml";
+ return loadXml(pathBuilder.str());
+ }
+
+ std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXmlByStableId(uint64_t stableId) {
+ std::stringstream pathBuilder;
+ pathBuilder << "/vendor/etc/displayconfig/display_id_" << stableId
+ << ".xml";
+ return loadXml(pathBuilder.str());
+ }
};
class GraphicsCompositionTest : public GraphicsCompositionTestBase,
diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml
index e25249b..4a0be56 100644
--- a/radio/1.2/vts/functional/AndroidTest.xml
+++ b/radio/1.2/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
<option name="module-name" value="VtsHalRadioV1_2TargetTest" />
</test>
</configuration>
diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml
index 44b7419..a2cd791 100644
--- a/radio/1.3/vts/functional/AndroidTest.xml
+++ b/radio/1.3/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
<option name="module-name" value="VtsHalRadioV1_3TargetTest" />
</test>
</configuration>
diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml
index d0843e6..54051ed 100644
--- a/radio/1.4/vts/functional/AndroidTest.xml
+++ b/radio/1.4/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
<option name="module-name" value="VtsHalRadioV1_4TargetTest" />
</test>
</configuration>
diff --git a/radio/1.5/vts/functional/AndroidTest.xml b/radio/1.5/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..d3617c8
--- /dev/null
+++ b/radio/1.5/vts/functional/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<configuration description="Runs VtsHalRadioV1_5TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+ <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+
+ <!-- TODO: b/154638140, b/152655658: bad interactions -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_5TargetTest->/data/local/tmp/VtsHalRadioV1_5TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
+ <option name="module-name" value="VtsHalRadioV1_5TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.6/vts/functional/AndroidTest.xml b/radio/1.6/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c3ecdb0
--- /dev/null
+++ b/radio/1.6/vts/functional/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<configuration description="Runs VtsHalRadioV1_6TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+ <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+
+ <!-- TODO: b/154638140, b/152655658: bad interactions -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_6TargetTest->/data/local/tmp/VtsHalRadioV1_6TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
+ <option name="module-name" value="VtsHalRadioV1_6TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 2beb249..253ef82 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -106,7 +106,7 @@
RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
if (radioRsp_network->rspInfo.error == RadioError::NONE) {
// verify we get the value we set
- ASSERT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
+ EXPECT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
}
}
diff --git a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
index bebad7c..738e72c 100644
--- a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
@@ -76,18 +76,10 @@
void TearDown() override { stopWifiService(getInstanceName()); }
- // Used as a mechanism to inform the test about data/event callbacks.
- inline void notify() {
- std::unique_lock<std::mutex> lock(mtx_);
- count_++;
- cv_.notify_one();
- }
-
enum CallbackType {
- INVALID = -2,
- ANY_CALLBACK = -1,
+ INVALID = 0,
- NOTIFY_CAPABILITIES_RESPONSE = 0,
+ NOTIFY_CAPABILITIES_RESPONSE = 1,
NOTIFY_ENABLE_RESPONSE,
NOTIFY_CONFIG_RESPONSE,
NOTIFY_DISABLE_RESPONSE,
@@ -128,310 +120,278 @@
EVENT_SUSPENSION_MODE_CHANGE,
};
+ // Used as a mechanism to inform the test about data/event callbacks.
+ inline void notify(CallbackType callbackType) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ callback_event_bitmap_ |= (UINT64_C(0x1) << callbackType);
+ cv_.notify_one();
+ }
+
// Test code calls this function to wait for data/event callback.
- // Must set callbackType = INVALID before calling this function.
+ // Must set callback_event_bitmap_ to 0 before calling this function.
inline std::cv_status wait(CallbackType waitForCallbackType) {
std::unique_lock<std::mutex> lock(mtx_);
EXPECT_NE(INVALID, waitForCallbackType);
std::cv_status status = std::cv_status::no_timeout;
auto now = std::chrono::system_clock::now();
- while (count_ == 0) {
+ while (!(receivedCallback(waitForCallbackType))) {
status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
if (status == std::cv_status::timeout) return status;
- if (waitForCallbackType != ANY_CALLBACK && callback_type_ != INVALID &&
- callback_type_ != waitForCallbackType) {
- count_--;
- }
}
- count_--;
return status;
}
+ inline bool receivedCallback(CallbackType waitForCallbackType) {
+ return callback_event_bitmap_ & (UINT64_C(0x1) << waitForCallbackType);
+ }
+
class WifiNanIfaceEventCallback : public BnWifiNanIfaceEventCallback {
public:
WifiNanIfaceEventCallback(WifiNanIfaceAidlTest& parent) : parent_(parent){};
::ndk::ScopedAStatus eventClusterEvent(const NanClusterEventInd& event) override {
- parent_.callback_type_ = EVENT_CLUSTER_EVENT;
parent_.nan_cluster_event_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_CLUSTER_EVENT);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventDataPathConfirm(const NanDataPathConfirmInd& event) override {
- parent_.callback_type_ = EVENT_DATA_PATH_CONFIRM;
parent_.nan_data_path_confirm_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_DATA_PATH_CONFIRM);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventDataPathRequest(const NanDataPathRequestInd& event) override {
- parent_.callback_type_ = EVENT_DATA_PATH_REQUEST;
parent_.nan_data_path_request_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_DATA_PATH_REQUEST);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventDataPathScheduleUpdate(
const NanDataPathScheduleUpdateInd& event) override {
- parent_.callback_type_ = EVENT_DATA_PATH_SCHEDULE_UPDATE;
parent_.nan_data_path_schedule_update_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventDataPathTerminated(int32_t ndpInstanceId) override {
- parent_.callback_type_ = EVENT_DATA_PATH_TERMINATED;
parent_.ndp_instance_id_ = ndpInstanceId;
- parent_.notify();
+ parent_.notify(EVENT_DATA_PATH_TERMINATED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventDisabled(const NanStatus& status) override {
- parent_.callback_type_ = EVENT_DISABLED;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(EVENT_DISABLED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventFollowupReceived(const NanFollowupReceivedInd& event) override {
- parent_.callback_type_ = EVENT_FOLLOWUP_RECEIVED;
parent_.nan_followup_received_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_FOLLOWUP_RECEIVED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventMatch(const NanMatchInd& event) override {
- parent_.callback_type_ = EVENT_MATCH;
parent_.nan_match_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_MATCH);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventMatchExpired(int8_t discoverySessionId, int32_t peerId) override {
- parent_.callback_type_ = EVENT_MATCH_EXPIRED;
parent_.session_id_ = discoverySessionId;
parent_.peer_id_ = peerId;
- parent_.notify();
+ parent_.notify(EVENT_MATCH_EXPIRED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventPublishTerminated(int8_t sessionId,
const NanStatus& status) override {
- parent_.callback_type_ = EVENT_PUBLISH_TERMINATED;
parent_.session_id_ = sessionId;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(EVENT_PUBLISH_TERMINATED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventSubscribeTerminated(int8_t sessionId,
const NanStatus& status) override {
- parent_.callback_type_ = EVENT_SUBSCRIBE_TERMINATED;
parent_.session_id_ = sessionId;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(EVENT_SUBSCRIBE_TERMINATED);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventTransmitFollowup(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = EVENT_TRANSMIT_FOLLOWUP;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(EVENT_TRANSMIT_FOLLOWUP);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventPairingConfirm(const NanPairingConfirmInd& event) override {
- parent_.callback_type_ = EVENT_PAIRING_CONFIRM;
parent_.nan_pairing_confirm_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_PAIRING_CONFIRM);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventPairingRequest(const NanPairingRequestInd& event) override {
- parent_.callback_type_ = EVENT_PAIRING_REQUEST;
parent_.nan_pairing_request_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_PAIRING_REQUEST);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventBootstrappingConfirm(
const NanBootstrappingConfirmInd& event) override {
- parent_.callback_type_ = EVENT_BOOTSTRAPPING_CONFIRM;
parent_.nan_bootstrapping_confirm_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_BOOTSTRAPPING_CONFIRM);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventBootstrappingRequest(
const NanBootstrappingRequestInd& event) override {
- parent_.callback_type_ = EVENT_BOOTSTRAPPING_REQUEST;
parent_.nan_bootstrapping_request_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_BOOTSTRAPPING_REQUEST);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus eventSuspensionModeChanged(
const NanSuspensionModeChangeInd& event) override {
- parent_.callback_type_ = EVENT_SUSPENSION_MODE_CHANGE;
parent_.nan_suspension_mode_change_ind_ = event;
- parent_.notify();
+ parent_.notify(EVENT_SUSPENSION_MODE_CHANGE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyCapabilitiesResponse(
char16_t id, const NanStatus& status,
const NanCapabilities& capabilities) override {
- parent_.callback_type_ = NOTIFY_CAPABILITIES_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.capabilities_ = capabilities;
- parent_.notify();
+ parent_.notify(NOTIFY_CAPABILITIES_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyConfigResponse(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_CONFIG_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_CONFIG_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyCreateDataInterfaceResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_CREATE_DATA_INTERFACE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyDeleteDataInterfaceResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_DELETE_DATA_INTERFACE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyDisableResponse(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_DISABLE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_DISABLE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyEnableResponse(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_ENABLE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_ENABLE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyInitiateDataPathResponse(char16_t id, const NanStatus& status,
int32_t ndpInstanceId) override {
- parent_.callback_type_ = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.ndp_instance_id_ = ndpInstanceId;
- parent_.notify();
+ parent_.notify(NOTIFY_INITIATE_DATA_PATH_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyRespondToDataPathIndicationResponse(
char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyStartPublishResponse(char16_t id, const NanStatus& status,
int8_t sessionId) override {
- parent_.callback_type_ = NOTIFY_START_PUBLISH_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.session_id_ = sessionId;
- parent_.notify();
+ parent_.notify(NOTIFY_START_PUBLISH_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyStartSubscribeResponse(char16_t id, const NanStatus& status,
int8_t sessionId) override {
- parent_.callback_type_ = NOTIFY_START_SUBSCRIBE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.session_id_ = sessionId;
- parent_.notify();
+ parent_.notify(NOTIFY_START_SUBSCRIBE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyStopPublishResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_STOP_PUBLISH_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_STOP_PUBLISH_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyStopSubscribeResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_STOP_SUBSCRIBE_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyTerminateDataPathResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_TERMINATE_DATA_PATH_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifySuspendResponse(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_SUSPEND_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_SUSPEND_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyResumeResponse(char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_RESUME_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_RESUME_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyTransmitFollowupResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyInitiatePairingResponse(char16_t id, const NanStatus& status,
int32_t pairingInstanceId) override {
- parent_.callback_type_ = NOTIFY_INITIATE_PAIRING_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.pairing_instance_id_ = pairingInstanceId;
- parent_.notify();
+ parent_.notify(NOTIFY_INITIATE_PAIRING_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyRespondToPairingIndicationResponse(
char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyInitiateBootstrappingResponse(
char16_t id, const NanStatus& status, int32_t bootstrapppingInstanceId) override {
- parent_.callback_type_ = NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
parent_.bootstrappping_instance_id_ = bootstrapppingInstanceId;
- parent_.notify();
+ parent_.notify(NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyRespondToBootstrappingIndicationResponse(
char16_t id, const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus notifyTerminatePairingResponse(char16_t id,
const NanStatus& status) override {
- parent_.callback_type_ = NOTIFY_TERMINATE_PAIRING_RESPONSE;
parent_.id_ = id;
parent_.status_ = status;
- parent_.notify();
+ parent_.notify(NOTIFY_TERMINATE_PAIRING_RESPONSE);
return ndk::ScopedAStatus::ok();
}
@@ -441,7 +401,7 @@
protected:
std::shared_ptr<IWifiNanIface> wifi_nan_iface_;
- CallbackType callback_type_;
+ uint64_t callback_event_bitmap_;
uint16_t id_;
uint8_t session_id_;
uint32_t ndp_instance_id_;
@@ -468,7 +428,6 @@
// synchronization objects
std::mutex mtx_;
std::condition_variable cv_;
- int count_ = 0;
};
/*
@@ -488,7 +447,7 @@
*/
TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidArgs) {
uint16_t inputCmdId = 10;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
NanEnableRequest nanEnableRequest = {};
NanConfigRequestSupplemental nanConfigRequestSupp = {};
auto status =
@@ -498,7 +457,7 @@
// Wait for a callback.
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
- ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
+ ASSERT_TRUE(receivedCallback(NOTIFY_ENABLE_RESPONSE));
ASSERT_EQ(id_, inputCmdId);
ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
}
@@ -509,7 +468,7 @@
*/
TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidArgs) {
uint16_t inputCmdId = 10;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
NanConfigRequest nanConfigRequest = {};
NanConfigRequestSupplemental nanConfigRequestSupp = {};
auto status =
@@ -520,7 +479,7 @@
// Wait for a callback.
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
- ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callback_type_);
+ ASSERT_TRUE(receivedCallback(NOTIFY_CONFIG_RESPONSE));
ASSERT_EQ(id_, inputCmdId);
ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
}
@@ -561,12 +520,12 @@
*/
TEST_P(WifiNanIfaceAidlTest, NotifyCapabilitiesResponse) {
uint16_t inputCmdId = 10;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
EXPECT_TRUE(wifi_nan_iface_->getCapabilitiesRequest(inputCmdId).isOk());
// Wait for a callback.
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
- ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callback_type_);
+ ASSERT_TRUE(receivedCallback(NOTIFY_CAPABILITIES_RESPONSE));
ASSERT_EQ(id_, inputCmdId);
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
@@ -654,14 +613,14 @@
nanConfigRequestSupp.numberOfSpatialStreamsInDiscovery = 0;
nanConfigRequestSupp.enableDiscoveryWindowEarlyTermination = false;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
auto status = wifi_nan_iface_->enableRequest(inputCmdId, req, nanConfigRequestSupp);
if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
ASSERT_TRUE(status.isOk());
// Wait for a callback.
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
- ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
+ ASSERT_TRUE(receivedCallback(NOTIFY_ENABLE_RESPONSE));
ASSERT_EQ(id_, inputCmdId);
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
}
@@ -688,7 +647,7 @@
// Wait for a callback.
ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
- ASSERT_EQ(NOTIFY_START_PUBLISH_RESPONSE, callback_type_);
+ ASSERT_TRUE(receivedCallback(NOTIFY_START_PUBLISH_RESPONSE));
ASSERT_EQ(id_, inputCmdId + 1);
ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
}
@@ -699,7 +658,7 @@
*/
TEST_P(WifiNanIfaceAidlTest, RespondToDataPathIndicationRequest_InvalidArgs) {
uint16_t inputCmdId = 10;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
NanRespondToDataPathIndicationRequest nanRespondToDataPathIndicationRequest = {};
nanRespondToDataPathIndicationRequest.ifaceName = "AwareInterfaceNameTooLong";
auto status = wifi_nan_iface_->respondToDataPathIndicationRequest(
@@ -716,7 +675,7 @@
*/
TEST_P(WifiNanIfaceAidlTest, InitiateDataPathRequest_InvalidArgs) {
uint16_t inputCmdId = 10;
- callback_type_ = INVALID;
+ callback_event_bitmap_ = 0;
NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
nanInitiateDataPathRequest.ifaceName = "AwareInterfaceNameTooLong";
auto status = wifi_nan_iface_->initiateDataPathRequest(inputCmdId, nanInitiateDataPathRequest);
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index f12d873..1ea1237 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cctype>
#include <vector>
#include <VtsCoreUtil.h>
@@ -68,6 +69,50 @@
std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
+ // Checks if the MdnsOffloadManagerService is installed.
+ bool isMdnsOffloadServicePresent() {
+ int status =
+ // --query-flags MATCH_SYSTEM_ONLY(1048576) will only return matched service
+ // installed on system or system_ext partition. The MdnsOffloadManagerService should
+ // be installed on system_ext partition.
+ // NOLINTNEXTLINE(cert-env33-c)
+ system("pm query-services --query-flags 1048576"
+ " com.android.tv.mdnsoffloadmanager/"
+ "com.android.tv.mdnsoffloadmanager.MdnsOffloadManagerService"
+ " | egrep -q mdnsoffloadmanager");
+ return status == 0;
+ }
+
+ // Detected panel TV device by using ro.oem.key1 property.
+ // https://docs.partner.android.com/tv/build/platform/props-vars/ro-oem-key1
+ bool isPanelTvDevice() {
+ const std::string oem_key1 = getPropertyString("ro.oem.key1");
+ if (oem_key1.size() < 9) {
+ return false;
+ }
+ if (oem_key1.substr(0, 3) != "ATV") {
+ return false;
+ }
+ const std::string psz_string = oem_key1.substr(6, 3);
+ // If PSZ string contains non digit, then it is not a panel TV device.
+ for (char ch : psz_string) {
+ if (!isdigit(ch)) {
+ return false;
+ }
+ }
+ // If PSZ is "000", then it is not a panel TV device.
+ if (psz_string == "000") {
+ return false;
+ }
+ return true;
+ }
+
+ std::string getPropertyString(const char* property_name) {
+ char property_string_raw_bytes[PROPERTY_VALUE_MAX] = {};
+ int len = property_get(property_name, property_string_raw_bytes, "");
+ return std::string(property_string_raw_bytes, len);
+ }
+
private:
const char* getInstanceName() { return GetParam().c_str(); }
};
@@ -99,6 +144,11 @@
*/
// @VsrTest = 5.3.12
TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
+ // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
+ // chipset does not have sufficient RAM to do so.
+ if (isPanelTvDevice() && isMdnsOffloadServicePresent()) {
+ GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
+ }
int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
// Before VSR 14, APF support is optional.
if (vendor_api_level < __ANDROID_API_U__) {