Merge android14-tests-dev

Bug: 263910020
Merged-In: I770dc5620648df2eab608e030c5e76cf190f315d
Change-Id: If4fe726d538386d70061e8051299d8fb393ef5df
This commit is contained in:
Xin Li 2023-10-10 16:17:14 -07:00
commit 11ee4fea87
17 changed files with 659 additions and 421 deletions

View file

@ -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 @@ using ::testing::SaveArg;
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 @@ bool supportsFM(const AmFmRegionConfig& config) {
} // 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 @@ class BroadcastRadioHalTest : public testing::TestWithParam<string> {
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 @@ MATCHER_P(InfoHasId, id, string(negation ? "does not contain" : "contains") + "
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 @@ ScopedAStatus TunerCallbackMock::onCurrentProgramInfoChanged(const ProgramInfo&
}
}
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 @@ void BroadcastRadioHalTest::SetUp() {
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 @@ void BroadcastRadioHalTest::TearDown() {
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() {
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 @@ std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
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 @@ TEST_P(BroadcastRadioHalTest, TuneFailsWithoutTunerCallback) {
* - 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 @@ TEST_P(BroadcastRadioHalTest, TuneFailsWithNotSupported) {
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 @@ TEST_P(BroadcastRadioHalTest, TuneFailsWithInvalid) {
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 @@ TEST_P(BroadcastRadioHalTest, FmTune) {
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 @@ TEST_P(BroadcastRadioHalTest, FmTune) {
// 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 @@ TEST_P(BroadcastRadioHalTest, DabTune) {
}
// 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 @@ TEST_P(BroadcastRadioHalTest, DabTune) {
// 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 @@ TEST_P(BroadcastRadioHalTest, DabTune) {
*
* 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 @@ TEST_P(BroadcastRadioHalTest, Seek) {
}
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 @@ TEST_P(BroadcastRadioHalTest, SeekFailsWithoutTunerCallback) {
*
* 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 @@ TEST_P(BroadcastRadioHalTest, Step) {
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 @@ TEST_P(BroadcastRadioHalTest, SetConfigFlags) {
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 @@ TEST_P(BroadcastRadioHalTest, SetConfigFlags) {
*
* 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 @@ TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
*
* 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 @@ TEST_P(BroadcastRadioHalTest, GetProgramListFromAmFmFilter) {
*
* 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.

View file

@ -552,6 +552,11 @@ TEST_P(CameraAidlTest, configureStreamsAvailableOutputs) {
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;

View file

@ -45,8 +45,6 @@ using ::aidl::android::hardware::camera::common::TorchModeStatus;
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;
@ -122,7 +120,7 @@ void CameraAidlTest::SetUp() {
ABinderProcess_startThreadPool();
SpAIBinder cameraProviderBinder =
SpAIBinder(AServiceManager_getService(serviceDescriptor.c_str()));
SpAIBinder(AServiceManager_waitForService(serviceDescriptor.c_str()));
ASSERT_NE(cameraProviderBinder.get(), nullptr);
std::shared_ptr<ICameraProvider> cameraProvider =
@ -2321,21 +2319,26 @@ void CameraAidlTest::configureStreamUseCaseInternal(const AvailableStream &thres
}
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;
@ -2479,7 +2482,11 @@ void CameraAidlTest::configureSingleStream(
/*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;
@ -2810,21 +2817,26 @@ void CameraAidlTest::configurePreviewStreams(
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++;
}
@ -2883,7 +2895,8 @@ void CameraAidlTest::configureStreams(const std::string& name,
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);
@ -2965,7 +2978,9 @@ void CameraAidlTest::configureStreams(const std::string& name,
-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;
@ -3416,7 +3431,11 @@ void CameraAidlTest::configureOfflineStillStream(
/*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()};
@ -3531,15 +3550,12 @@ void CameraAidlTest::processColorSpaceRequest(
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<

View file

@ -77,6 +77,9 @@ using ::aidl::android::hardware::camera::device::StreamBuffer;
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 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
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,
@ -379,8 +384,7 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
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);
@ -390,17 +394,13 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
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(
@ -411,10 +411,8 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
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);
@ -574,10 +572,8 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
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);

View file

@ -54,7 +54,6 @@ cc_test {
"libgui",
"libhidlbase",
"libprocessgroup",
"libtinyxml2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@3.0",

View file

@ -31,12 +31,6 @@
#include "RenderEngineVts.h"
#include "VtsComposerClient.h"
// tinyxml2 does implicit conversions >:(
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#include <tinyxml2.h>
#pragma clang diagnostic pop
namespace aidl::android::hardware::graphics::composer3::vts {
namespace {
@ -129,76 +123,6 @@ class GraphicsCompositionTestBase : public ::testing::Test {
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) {
return document;
} else {
return nullptr;
}
}
// Gets the max display brightness for this display.
// If the display config xml does not exist, then assume that the display is not well-configured
// enough to provide a display brightness, so return nullopt.
std::optional<float> getMaxDisplayBrightnessNits(int64_t display) {
const auto document = getDisplayConfigXml(display);
if (!document) {
// Assume the device doesn't support display brightness
return std::nullopt;
}
const auto root = document->RootElement();
if (!root) {
// If there's somehow no root element, then this isn't a valid config
return std::nullopt;
}
const auto screenBrightnessMap = root->FirstChildElement("screenBrightnessMap");
if (!screenBrightnessMap) {
// A valid display config must have a screen brightness map
return std::nullopt;
}
auto point = screenBrightnessMap->FirstChildElement("point");
float maxNits = -1.f;
while (point != nullptr) {
const auto nits = point->FirstChildElement("nits");
if (nits) {
maxNits = std::max(maxNits, nits->FloatText(-1.f));
}
point = point->NextSiblingElement("point");
}
if (maxNits < 0.f) {
// If we got here, then there were no point elements containing a nit value, so this
// config isn't valid
return std::nullopt;
}
return maxNits;
}
void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
for (const auto& layer : layers) {
layer->write(*mWriter);
@ -957,32 +881,6 @@ TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
}
TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
const auto& [status, capabilities] =
mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
ASSERT_TRUE(status.isOk());
const bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
DisplayCapability::BRIGHTNESS) != capabilities.end();
if (!brightnessSupport) {
GTEST_SUCCEED() << "Cannot verify dimming behavior without brightness support";
return;
}
const std::optional<float> maxBrightnessNitsOptional =
getMaxDisplayBrightnessNits(getPrimaryDisplayId());
ASSERT_TRUE(maxBrightnessNitsOptional.has_value());
const float maxBrightnessNits = *maxBrightnessNitsOptional;
// Preconditions to successfully run are knowing the max brightness and successfully applying
// the max brightness
ASSERT_GT(maxBrightnessNits, 0.f);
mWriter->setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.f, maxBrightnessNits);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
for (ColorMode mode : mTestColorModes) {
EXPECT_TRUE(mComposerClient
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
@ -999,11 +897,14 @@ TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
const common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
const common::Rect dimmerRedRect = {0, getDisplayHeight() / 2, getDisplayWidth(),
getDisplayHeight()};
static constexpr float kMaxBrightnessNits = 300.f;
const auto redLayer =
std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
redLayer->setColor(RED);
redLayer->setDisplayFrame(redRect);
redLayer->setWhitePointNits(maxBrightnessNits);
redLayer->setWhitePointNits(kMaxBrightnessNits);
redLayer->setBrightness(1.f);
const auto dimmerRedLayer =
@ -1013,7 +914,7 @@ TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
// Intentionally use a small dimming ratio as some implementations may be more likely to
// kick into GPU composition to apply dithering when the dimming ratio is high.
static constexpr float kDimmingRatio = 0.9f;
dimmerRedLayer->setWhitePointNits(maxBrightnessNits * kDimmingRatio);
dimmerRedLayer->setWhitePointNits(kMaxBrightnessNits * kDimmingRatio);
dimmerRedLayer->setBrightness(kDimmingRatio);
const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};

View file

@ -214,7 +214,8 @@ TEST_P(RadioDataTest, setupDataCall_osAppId) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0) {
if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0 ||
!radioRsp_data->setupDataCallResult.trafficDescriptors[0].osAppId.has_value()) {
return;
}
EXPECT_EQ(trafficDescriptor.osAppId.value().osAppId,

View file

@ -119,7 +119,7 @@ TEST_P(RadioNetworkTest, setGetAllowedNetworkTypesBitmap) {
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);
}
}

View file

@ -76,18 +76,10 @@ class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
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 @@ class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
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 @@ class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
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 @@ class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
// synchronization objects
std::mutex mtx_;
std::condition_variable cv_;
int count_ = 0;
};
/*
@ -488,7 +447,7 @@ TEST_P(WifiNanIfaceAidlTest, FailOnIfaceInvalid) {
*/
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 @@ TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidArgs) {
// 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, EnableRequest_InvalidArgs) {
*/
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 @@ TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidArgs) {
// 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, ConfigRequest_InvalidShimArgs) {
*/
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 @@ TEST_P(WifiNanIfaceAidlTest, StartPublishRequest) {
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 @@ TEST_P(WifiNanIfaceAidlTest, StartPublishRequest) {
// 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, StartPublishRequest) {
*/
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, RespondToDataPathIndicationRequest_InvalidArgs) {
*/
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);

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <cctype>
#include <vector>
#include <VtsCoreUtil.h>
@ -68,6 +69,50 @@ class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
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 @@ TEST_P(WifiStaIfaceAidlTest, GetFeatureSet) {
*/
// @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__) {

View file

@ -41,10 +41,9 @@ using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::wifi_system::HostapdManager;
using ::android::wifi_system::SupplicantManager;
namespace {
// Helper function to initialize the driver and firmware to AP mode
// using the vendor HAL HIDL interface.
void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
if (getWifi(wifi_instance_name) != nullptr) {
sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
ChipModeId mode_id;
@ -57,21 +56,20 @@ void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
// Helper function to deinitialize the driver and firmware
// using the vendor HAL HIDL interface.
void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
if (getWifi(wifi_instance_name) != nullptr) {
stopWifi(wifi_instance_name);
} else {
LOG(WARNING) << __func__ << ": Vendor HAL not supported";
}
}
} // namespace
void stopSupplicantIfNeeded(const std::string& instance_name) {
SupplicantManager supplicant_manager;
if (supplicant_manager.IsSupplicantRunning()) {
LOG(INFO) << "Supplicant is running, stop supplicant first.";
ASSERT_TRUE(supplicant_manager.StopSupplicant());
deInitilializeDriverAndFirmware(instance_name);
deInitializeDriverAndFirmware(instance_name);
ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
}
}
@ -80,13 +78,13 @@ void stopHostapd(const std::string& instance_name) {
HostapdManager hostapd_manager;
ASSERT_TRUE(hostapd_manager.StopHostapd());
deInitilializeDriverAndFirmware(instance_name);
deInitializeDriverAndFirmware(instance_name);
}
void startHostapdAndWaitForHidlService(
const std::string& wifi_instance_name,
const std::string& hostapd_instance_name) {
initilializeDriverAndFirmware(wifi_instance_name);
initializeDriverAndFirmware(wifi_instance_name);
HostapdManager hostapd_manager;
ASSERT_TRUE(hostapd_manager.StartHostapd());

View file

@ -36,5 +36,9 @@ void startHostapdAndWaitForHidlService(
bool is_1_1(const android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd>&
hostapd);
// Used to initialize/deinitialize the driver and firmware at the
// beginning and end of each test.
void initializeDriverAndFirmware(const std::string& wifi_instance_name);
void deInitializeDriverAndFirmware(const std::string& wifi_instance_name);
#endif /* HOSTAPD_HIDL_TEST_UTILS_H */

View file

@ -37,6 +37,7 @@ cc_test {
"android.hardware.wifi@1.5",
"android.hardware.wifi@1.6",
"android.hardware.wifi-V1-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiTargetTestUtil",
],

View file

@ -32,6 +32,7 @@
#include <wifi_hidl_test_utils_1_5.h>
#include <wifi_hidl_test_utils_1_6.h>
#include "hostapd_test_utils.h"
#include "wifi_aidl_test_utils.h"
using aidl::android::hardware::wifi::hostapd::BandMask;
@ -56,10 +57,7 @@ const std::string kInvalidMaxPassphrase =
const int kIfaceChannel = 6;
const int kIfaceInvalidChannel = 567;
const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
const Ieee80211ReasonCode kTestDisconnectReasonCode =
Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
const std::string kWifiAidlInstanceNameStr = std::string() + IWifi::descriptor + "/default";
const char* kWifiAidlInstanceName = kWifiAidlInstanceNameStr.c_str();
const Ieee80211ReasonCode kTestDisconnectReasonCode = Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
inline BandMask operator|(BandMask a, BandMask b) {
return static_cast<BandMask>(static_cast<int32_t>(a) |
@ -70,10 +68,13 @@ inline BandMask operator|(BandMask a, BandMask b) {
class HostapdAidl : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
AServiceManager_waitForService(GetParam().c_str())));
disableHalsAndFramework();
initializeHostapdAndVendorHal(GetParam());
hostapd = getHostapd(GetParam());
ASSERT_NE(hostapd, nullptr);
EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
isAcsSupport = testing::checkSubstringInCommandOutput(
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_acs_supported");
@ -81,81 +82,23 @@ class HostapdAidl : public testing::TestWithParam<std::string> {
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_wpa3_sae_supported");
isBridgedSupport = testing::checkSubstringInCommandOutput(
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_bridged_ap_supported");
if (!isAidlServiceAvailable(kWifiAidlInstanceName)) {
const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
::android::hardware::wifi::V1_0::IWifi::descriptor);
EXPECT_NE(0, instances.size());
wifiHidlInstanceName = instances[0];
}
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_bridged_ap_supported");
}
virtual void TearDown() override {
stopVendorHal();
hostapd->terminate();
// Wait 3 seconds to allow terminate to complete
sleep(3);
stopHostapdAndVendorHal();
startWifiFramework();
}
std::shared_ptr<IHostapd> hostapd;
std::string wifiHidlInstanceName;
bool isAcsSupport;
bool isWpa3SaeSupport;
bool isBridgedSupport;
void stopVendorHal() {
if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
// HIDL and AIDL versions of getWifi() take different arguments
// i.e. const char* vs string
if (getWifi(kWifiAidlInstanceName) != nullptr) {
stopWifiService(kWifiAidlInstanceName);
}
} else {
if (getWifi(wifiHidlInstanceName) != nullptr) {
stopWifi(wifiHidlInstanceName);
}
}
}
std::string setupApIfaceAndGetName(bool isBridged) {
if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
return setupApIfaceAndGetNameAidl(isBridged);
} else {
return setupApIfaceAndGetNameHidl(isBridged);
}
}
std::string setupApIfaceAndGetNameAidl(bool isBridged) {
std::shared_ptr<IWifiApIface> wifi_ap_iface;
if (isBridged) {
wifi_ap_iface = getBridgedWifiApIface(kWifiAidlInstanceName);
} else {
wifi_ap_iface = getWifiApIface(kWifiAidlInstanceName);
}
EXPECT_NE(nullptr, wifi_ap_iface.get());
std::string ap_iface_name;
auto status = wifi_ap_iface->getName(&ap_iface_name);
EXPECT_TRUE(status.isOk());
return ap_iface_name;
}
std::string setupApIfaceAndGetNameHidl(bool isBridged) {
android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
if (isBridged) {
wifi_ap_iface = getBridgedWifiApIface_1_6(wifiHidlInstanceName);
} else {
wifi_ap_iface = getWifiApIface_1_5(wifiHidlInstanceName);
}
EXPECT_NE(nullptr, wifi_ap_iface.get());
const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
EXPECT_EQ(android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS,
status_and_name.first.code);
return status_and_name.second;
}
IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
IfaceParams iface_params;
ChannelParams channelParams;

View file

@ -0,0 +1,80 @@
/*
* 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.
*/
#pragma once
#include <aidl/android/hardware/wifi/IWifi.h>
#include <android-base/logging.h>
#include "wifi_aidl_test_utils.h"
namespace {
const std::string kWifiInstanceNameStr = std::string() + IWifi::descriptor + "/default";
const char* kWifiInstanceName = kWifiInstanceNameStr.c_str();
} // namespace
namespace HostapdAidlTestUtils {
bool useAidlService() {
return isAidlServiceAvailable(kWifiInstanceName);
}
void startAndConfigureVendorHal() {
if (getWifi(kWifiInstanceName) != nullptr) {
std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(kWifiInstanceName);
int mode_id;
EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::AP,
&mode_id));
} else {
LOG(ERROR) << "Unable to initialize Vendor HAL";
}
}
void stopVendorHal() {
if (getWifi(kWifiInstanceName) != nullptr) {
stopWifiService(kWifiInstanceName);
} else {
LOG(ERROR) << "Unable to stop Vendor HAL";
}
}
std::string setupApIfaceAndGetName(bool isBridged) {
std::shared_ptr<IWifiApIface> wifi_ap_iface;
if (isBridged) {
wifi_ap_iface = getBridgedWifiApIface(kWifiInstanceName);
} else {
wifi_ap_iface = getWifiApIface(kWifiInstanceName);
}
EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
if (!wifi_ap_iface.get()) {
LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
return "";
}
std::string ap_iface_name;
auto status = wifi_ap_iface->getName(&ap_iface_name);
EXPECT_TRUE(status.isOk());
if (!status.isOk()) {
LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
return "";
}
return ap_iface_name;
}
} // namespace HostapdAidlTestUtils

View file

@ -0,0 +1,71 @@
/*
* 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.
*/
#pragma once
#include <android-base/logging.h>
#include "hostapd_hidl_test_utils.h"
#include "wifi_hidl_test_utils.h"
using ::android::hardware::wifi::V1_0::WifiStatus;
namespace {
std::string getWifiInstanceName() {
const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
::android::hardware::wifi::V1_0::IWifi::descriptor);
EXPECT_NE(0, instances.size());
return instances.size() != 0 ? instances[0] : "";
}
} // namespace
namespace HostapdLegacyTestUtils {
void startAndConfigureVendorHal() {
initializeDriverAndFirmware(getWifiInstanceName());
}
void stopVendorHal() {
deInitializeDriverAndFirmware(getWifiInstanceName());
}
std::string setupApIfaceAndGetName(bool isBridged) {
android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
if (isBridged) {
wifi_ap_iface = getBridgedWifiApIface_1_6(getWifiInstanceName());
} else {
wifi_ap_iface = getWifiApIface_1_5(getWifiInstanceName());
}
EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
if (!wifi_ap_iface.get()) {
LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
return "";
}
const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
EXPECT_TRUE(status_and_name.first.code ==
android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS);
if (status_and_name.first.code != android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS) {
LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
return "";
}
return status_and_name.second;
}
} // namespace HostapdLegacyTestUtils

View file

@ -0,0 +1,122 @@
/*
* 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.
*/
#pragma once
#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
#include <android-base/logging.h>
#include <wifi_system/hostapd_manager.h>
#include <wifi_system/supplicant_manager.h>
#include "hostapd_aidl_test_utils.h"
#include "hostapd_legacy_test_utils.h"
using aidl::android::hardware::wifi::hostapd::IHostapd;
using android::wifi_system::HostapdManager;
using android::wifi_system::SupplicantManager;
namespace {
void startAndConfigureVendorHal() {
if (HostapdAidlTestUtils::useAidlService()) {
HostapdAidlTestUtils::startAndConfigureVendorHal();
} else {
HostapdLegacyTestUtils::startAndConfigureVendorHal();
}
}
void stopVendorHal() {
if (HostapdAidlTestUtils::useAidlService()) {
HostapdAidlTestUtils::stopVendorHal();
} else {
HostapdLegacyTestUtils::stopVendorHal();
}
}
void stopHostapd() {
HostapdManager hostapd_manager;
ASSERT_TRUE(hostapd_manager.StopHostapd());
}
void waitForSupplicantState(bool enable) {
SupplicantManager supplicant_manager;
int count = 50; // wait at most 5 seconds
while (count-- > 0) {
if (supplicant_manager.IsSupplicantRunning() == enable) {
return;
}
usleep(100000); // 100 ms
}
LOG(ERROR) << "Unable to " << (enable ? "start" : "stop") << " supplicant";
}
void toggleWifiFrameworkAndScan(bool enable) {
if (enable) {
std::system("svc wifi enable");
std::system("cmd wifi set-scan-always-available enabled");
waitForSupplicantState(true);
} else {
std::system("svc wifi disable");
std::system("cmd wifi set-scan-always-available disabled");
waitForSupplicantState(false);
}
}
} // namespace
std::shared_ptr<IHostapd> getHostapd(const std::string& hostapd_instance_name) {
return IHostapd::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(hostapd_instance_name.c_str())));
}
/**
* Disable the Wifi framework, hostapd, and vendor HAL.
*
* Note: The framework should be disabled to avoid having
* any other clients to the HALs during testing.
*/
void disableHalsAndFramework() {
toggleWifiFrameworkAndScan(false);
stopHostapd();
stopVendorHal();
// Wait for the services to stop.
sleep(3);
}
void initializeHostapdAndVendorHal(const std::string& hostapd_instance_name) {
startAndConfigureVendorHal();
HostapdManager hostapd_manager;
ASSERT_TRUE(hostapd_manager.StartHostapd());
getHostapd(hostapd_instance_name);
}
void stopHostapdAndVendorHal() {
stopHostapd();
stopVendorHal();
}
void startWifiFramework() {
toggleWifiFrameworkAndScan(true);
}
std::string setupApIfaceAndGetName(bool isBridged) {
if (HostapdAidlTestUtils::useAidlService()) {
return HostapdAidlTestUtils::setupApIfaceAndGetName(isBridged);
} else {
return HostapdLegacyTestUtils::setupApIfaceAndGetName(isBridged);
}
}