tune_1_1(ProgramSelector program) generates (Result result);
/**
+ * Cancels announcement.
+ *
+ * If it was traffic announcement, trafficAnnouncement(false) callback
+ * should be called (just like it was ended in a normal way). Similarly for
+ * emergency announcement. If there was no announcement, then no action
+ * should be taken.
+ *
+ * There is a race condition between calling cancelAnnouncement and the
+ * actual announcement being finished, so trafficAnnouncement /
+ * emergencyAnnouncement callback should be tracked with proper locking.
+ *
+ * @return result OK if successfully cancelled announcement or there was
+ * no announcement.
+ * NOT_INITIALIZED if another error occurs.
+ */
+ cancelAnnouncement() generates (Result result);
+
+ /**
* Retrieve current station information.
* @return result OK if scan successfully started
* NOT_INITIALIZED if another error occurs
/**
* Method called by the HAL when a tuning operation completes
* following a step(), scan() or tune() command.
+ *
+ * This callback supersedes V1_0::tuneComplete. For performance reasons,
+ * the 1.0 callback may not be called when HAL implementation detects 1.1
+ * client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
+ *
* @param result OK if tune succeeded or TIMEOUT in case of time out.
- * @param info A ProgramInfo structure describing the tuned station.
+ * @param selector A ProgramSelector structure describing the tuned station.
*/
- oneway tuneComplete_1_1(Result result, ProgramInfo info);
+ oneway tuneComplete_1_1(Result result, ProgramSelector selector);
/**
* Method called by the HAL when a frequency switch occurs.
- * @param info A ProgramInfo structure describing the new tuned station.
+ *
+ * This callback supersedes V1_0::afSwitch. For performance reasons,
+ * the 1.0 callback may not be called when HAL implementation detects 1.1
+ * client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
+ *
+ * @param selector A ProgramSelector structure describing the tuned station.
*/
- oneway afSwitch_1_1(ProgramInfo info);
+ oneway afSwitch_1_1(ProgramSelector selector);
/**
* Called by the HAL when background scan feature becomes available or not.
* Client may retrieve the actual list with ITuner::getProgramList.
*/
oneway programListChanged();
+
+ /**
+ * Method called by the HAL when current program information (including
+ * metadata) is updated.
+ *
+ * Client may retrieve the actual program info with
+ * ITuner::getProgramInformation_1_1.
+ *
+ * This may be called together with tuneComplete_1_1 or afSwitch_1_1.
+ *
+ * This callback supersedes V1_0::tuneComplete, V1_0::afSwitch and
+ * newMetadata. For performance reasons, these callbacks may not be called
+ * when HAL implementation detects 1.1 client (by casting
+ * V1_0::ITunerCallback to V1_1::ITunerCallback).
+ */
+ oneway programInfoChanged();
};
prop10.numAudioSources = 1;
prop10.supportsCapture = false;
prop11.supportsBackgroundScanning = false;
+ prop11.supportedProgramTypes = vector<uint32_t>({
+ static_cast<uint32_t>(ProgramType::AM), static_cast<uint32_t>(ProgramType::FM),
+ static_cast<uint32_t>(ProgramType::AM_HD), static_cast<uint32_t>(ProgramType::FM_HD),
+ });
+ prop11.supportedIdentifierTypes = vector<uint32_t>({
+ static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY),
+ static_cast<uint32_t>(IdentifierType::RDS_PI),
+ static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT),
+ static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL),
+ });
prop11.vendorExension = "dummy";
prop10.bands.resize(mConfig.amFmBands.size());
ProgramInfo info11 = {};
auto& info10 = info11.base;
- utils::getLegacyChannel(selector, info10.channel, info10.subChannel);
+ utils::getLegacyChannel(selector, &info10.channel, &info10.subChannel);
info11.selector = selector;
info11.flags |= ProgramInfoFlags::MUTED;
}
mIsTuneCompleted = true;
- mCallback->tuneComplete(Result::OK, mCurrentProgramInfo.base);
- if (mCallback1_1 != nullptr) {
- mCallback1_1->tuneComplete_1_1(Result::OK, mCurrentProgramInfo);
+ if (mCallback1_1 == nullptr) {
+ mCallback->tuneComplete(Result::OK, mCurrentProgramInfo.base);
+ } else {
+ mCallback1_1->tuneComplete_1_1(Result::OK, mCurrentProgramInfo.selector);
}
}
auto task = [this, direction]() {
ALOGI("Performing failed scan %s", toString(direction).c_str());
- mCallback->tuneComplete(Result::TIMEOUT, {});
- if (mCallback1_1 != nullptr) {
+ if (mCallback1_1 == nullptr) {
+ mCallback->tuneComplete(Result::TIMEOUT, {});
+ } else {
mCallback1_1->tuneComplete_1_1(Result::TIMEOUT, {});
}
};
return Result::OK;
}
+Return<Result> Tuner::cancelAnnouncement() {
+ ALOGV("%s", __func__);
+ return Result::OK;
+}
+
Return<void> Tuner::getProgramInformation(getProgramInformation_cb _hidl_cb) {
ALOGV("%s", __func__);
return getProgramInformation_1_1([&](Result result, const ProgramInfo& info) {
void forceClose();
// V1_1::ITuner methods
- Return<Result> setConfiguration(const V1_0::BandConfig& config) override;
- Return<void> getConfiguration(getConfiguration_cb _hidl_cb) override;
- Return<Result> scan(V1_0::Direction direction, bool skipSubChannel) override;
- Return<Result> step(V1_0::Direction direction, bool skipSubChannel) override;
- Return<Result> tune(uint32_t channel, uint32_t subChannel) override;
- Return<Result> tune_1_1(const ProgramSelector& program) override;
- Return<Result> cancel() override;
- Return<void> getProgramInformation(getProgramInformation_cb _hidl_cb) override;
- Return<void> getProgramInformation_1_1(getProgramInformation_1_1_cb _hidl_cb) override;
- Return<ProgramListResult> startBackgroundScan() override;
- Return<void> getProgramList(const hidl_string& filter, getProgramList_cb _hidl_cb) override;
- Return<void> isAnalogForced(isAnalogForced_cb _hidl_cb) override;
- Return<Result> setAnalogForced(bool isForced) override;
+ virtual Return<Result> setConfiguration(const V1_0::BandConfig& config) override;
+ virtual Return<void> getConfiguration(getConfiguration_cb _hidl_cb) override;
+ virtual Return<Result> scan(V1_0::Direction direction, bool skipSubChannel) override;
+ virtual Return<Result> step(V1_0::Direction direction, bool skipSubChannel) override;
+ virtual Return<Result> tune(uint32_t channel, uint32_t subChannel) override;
+ virtual Return<Result> tune_1_1(const ProgramSelector& program) override;
+ virtual Return<Result> cancel() override;
+ virtual Return<Result> cancelAnnouncement() override;
+ virtual Return<void> getProgramInformation(getProgramInformation_cb _hidl_cb) override;
+ virtual Return<void> getProgramInformation_1_1(getProgramInformation_1_1_cb _hidl_cb) override;
+ virtual Return<ProgramListResult> startBackgroundScan() override;
+ virtual Return<void> getProgramList(const hidl_string& filter,
+ getProgramList_cb _hidl_cb) override;
+ virtual Return<void> isAnalogForced(isAnalogForced_cb _hidl_cb) override;
+ virtual Return<Result> setAnalogForced(bool isForced) override;
private:
std::mutex mMut;
ProgramInfo info11 = {};
auto& info10 = info11.base;
- utils::getLegacyChannel(selector, info10.channel, info10.subChannel);
+ utils::getLegacyChannel(selector, &info10.channel, &info10.subChannel);
info11.selector = selector;
info10.tuned = true;
info10.stereo = true;
* increasing volume too much.
*/
MUTED = 1 << 1,
+
+ /**
+ * Station broadcasts traffic information regularly,
+ * but not necessarily right now.
+ */
+ TRAFFIC_PROGRAM = 1 << 2,
+
+ /**
+ * Station is broadcasting traffic information at the very moment.
+ */
+ TRAFFIC_ANNOUNCEMENT = 1 << 3,
};
struct Properties {
bool supportsBackgroundScanning;
/**
+ * A list of supported ProgramType values.
+ *
+ * If a program type is supported by radio module, it means it can tune
+ * to ProgramSelector of a given type.
+ *
+ * Support for VENDOR program type does not guarantee compatibility, as
+ * other module properties (implementor, product, version) must be checked.
+ */
+ vec<uint32_t> supportedProgramTypes;
+
+ /**
+ * A list of supported IdentifierType values.
+ *
+ * If an identifier is supported by radio module, it means it can use it for
+ * tuning to ProgramSelector with either primary or secondary Identifier of
+ * a given type.
+ *
+ * Support for VENDOR identifier type does not guarantee compatibility, as
+ * other module properties (implementor, product, version) must be checked.
+ */
+ vec<uint32_t> supportedIdentifierTypes;
+
+ /**
* Opaque vendor-specific string, to be passed to front-end without changes.
* Format of this string can vary across vendors.
*
/**
* Type of a radio technology.
*
+ * There are multiple VENDOR program types just to make vendor implementation
+ * easier with multiple properitary radio technologies. They are treated the
+ * same by the framework.
+ *
* All other values are reserved for future use.
*/
enum ProgramType : uint32_t {
DAB, // Digital audio broadcasting
DRMO, // Digital Radio Mondiale
SXM, // SiriusXM Satellite Radio
- VENDOR, // vendor-specific, not synced across devices
+ VENDOR1, // Vendor-specific, not synced across devices.
+ VENDOR2, // Vendor-specific, not synced across devices.
+ VENDOR3, // Vendor-specific, not synced across devices.
+ VENDOR4, // Vendor-specific, not synced across devices.
};
/**
* Primary identifier for vendor-specific radio technology.
* The value format is determined by a vendor.
*
- * It must not be used in any other programType than VENDOR.
+ * It must not be used in any other programType than VENDORx.
*/
- VENDOR_PRIMARY,
+ VENDOR1_PRIMARY,
+ VENDOR2_PRIMARY,
+ VENDOR3_PRIMARY,
+ VENDOR4_PRIMARY,
};
/**
cc_library_static {
name: "android.hardware.broadcastradio@1.1-utils-lib",
- vendor: true,
+ vendor_available: true,
relative_install_path: "hw",
cflags: [
"-Wall",
namespace hardware {
namespace broadcastradio {
namespace V1_1 {
-namespace implementation {
namespace utils {
using V1_0::Band;
return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID);
}
return haveEqualIds(a, b, IdentifierType::SXM_CHANNEL);
- case ProgramType::VENDOR:
+ case ProgramType::VENDOR1:
+ case ProgramType::VENDOR2:
+ case ProgramType::VENDOR3:
+ case ProgramType::VENDOR4:
default:
ALOGW("Unsupported program type: %s", toString(type).c_str());
return false;
sel.primaryId.type = static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY);
sel.primaryId.value = channel;
if (subChannel > 0) {
- // stating sub channel for AM/FM channel does not give any guarantees,
- // but we can't do much more without HD station ID
+ /* stating sub channel for AM/FM channel does not give any guarantees,
+ * but we can't do much more without HD station ID
+ *
+ * The legacy APIs had 1-based subChannels, while ProgramSelector is 0-based.
+ */
sel.secondaryIds = hidl_vec<ProgramIdentifier>{
- {static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL), subChannel},
+ {static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL), subChannel - 1},
};
}
return sel;
}
-bool getLegacyChannel(const ProgramSelector& sel, uint32_t& channelOut, uint32_t& subChannelOut) {
+bool getLegacyChannel(const ProgramSelector& sel, uint32_t* channelOut, uint32_t* subChannelOut) {
+ if (channelOut) *channelOut = 0;
+ if (subChannelOut) *subChannelOut = 0;
if (isAmFm(getType(sel))) {
- channelOut = getId(sel, IdentifierType::AMFM_FREQUENCY);
- subChannelOut = getId(sel, IdentifierType::HD_SUBCHANNEL, 0);
+ if (channelOut) *channelOut = getId(sel, IdentifierType::AMFM_FREQUENCY);
+ if (subChannelOut && hasId(sel, IdentifierType::HD_SUBCHANNEL)) {
+ // The legacy APIs had 1-based subChannels, while ProgramSelector is 0-based.
+ *subChannelOut = getId(sel, IdentifierType::HD_SUBCHANNEL) + 1;
+ }
return true;
- } else {
- channelOut = 0;
- subChannelOut = 0;
- return false;
}
+ return false;
}
bool isDigital(const ProgramSelector& sel) {
}
} // namespace utils
-} // namespace implementation
} // namespace V1_1
} // namespace broadcastradio
} // namespace hardware
namespace hardware {
namespace broadcastradio {
namespace V1_1 {
-namespace implementation {
namespace utils {
/**
ProgramSelector make_selector(V1_0::Band band, uint32_t channel, uint32_t subChannel = 0);
-bool getLegacyChannel(const ProgramSelector& sel, uint32_t& channelOut, uint32_t& subChannelOut);
+bool getLegacyChannel(const ProgramSelector& sel, uint32_t* channelOut, uint32_t* subChannelOut);
bool isDigital(const ProgramSelector& sel);
} // namespace utils
-} // namespace implementation
} // namespace V1_1
} // namespace broadcastradio
} // namespace hardware
using testing::AnyNumber;
using testing::ByMove;
using testing::DoAll;
+using testing::Invoke;
using testing::SaveArg;
using broadcastradio::vts::CallBarrier;
std::cout << "[ SKIPPED ] " << msg << std::endl;
}
-class TunerCallbackMock : public ITunerCallback {
- public:
+struct TunerCallbackMock : public ITunerCallback {
+ TunerCallbackMock() { EXPECT_CALL(*this, hardwareFailure()).Times(0); }
+
MOCK_METHOD0(hardwareFailure, Return<void>());
MOCK_TIMEOUT_METHOD2(configChange, Return<void>(Result, const BandConfig&));
MOCK_METHOD2(tuneComplete, Return<void>(Result, const V1_0::ProgramInfo&));
- MOCK_TIMEOUT_METHOD2(tuneComplete_1_1, Return<void>(Result, const ProgramInfo&));
+ MOCK_TIMEOUT_METHOD2(tuneComplete_1_1, Return<void>(Result, const ProgramSelector&));
MOCK_METHOD1(afSwitch, Return<void>(const V1_0::ProgramInfo&));
- MOCK_METHOD1(afSwitch_1_1, Return<void>(const ProgramInfo&));
+ MOCK_METHOD1(afSwitch_1_1, Return<void>(const ProgramSelector&));
MOCK_METHOD1(antennaStateChange, Return<void>(bool connected));
MOCK_METHOD1(trafficAnnouncement, Return<void>(bool active));
MOCK_METHOD1(emergencyAnnouncement, Return<void>(bool active));
MOCK_METHOD1(backgroundScanAvailable, Return<void>(bool));
MOCK_TIMEOUT_METHOD1(backgroundScanComplete, Return<void>(ProgramListResult));
MOCK_METHOD0(programListChanged, Return<void>());
+ MOCK_METHOD0(programInfoChanged, Return<void>());
};
class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase,
void BroadcastRadioHalTest::SetUp() {
radioClass = GetParam();
- // set general expectations for a callback
- EXPECT_CALL(*mCallback, hardwareFailure()).Times(0);
-
// lookup HIDL service
auto factory = getService<IBroadcastRadioFactory>();
ASSERT_NE(nullptr, factory.get());
ASSERT_TRUE(propResult.isOk());
EXPECT_EQ(radioClass, prop10.classId);
EXPECT_GT(prop10.numTuners, 0u);
+ EXPECT_GT(prop11.supportedProgramTypes.size(), 0u);
+ EXPECT_GT(prop11.supportedIdentifierTypes.size(), 0u);
if (radioClass == Class::AM_FM) {
EXPECT_GT(prop10.bands.size(), 0u);
}
return;
}
- ProgramInfo infoCb;
+ ProgramSelector selCb;
EXPECT_CALL(*mCallback, tuneComplete(_, _));
EXPECT_TIMEOUT_CALL(*mCallback, tuneComplete_1_1, Result::OK, _)
- .WillOnce(DoAll(SaveArg<1>(&infoCb), testing::Return(ByMove(Void()))));
+ .WillOnce(DoAll(SaveArg<1>(&selCb), testing::Return(ByMove(Void()))));
auto tuneResult = mTuner->tune_1_1(firstProgram.selector);
ASSERT_EQ(Result::OK, tuneResult);
EXPECT_TIMEOUT_CALL_WAIT(*mCallback, tuneComplete_1_1, kTuneTimeout);
- EXPECT_EQ(firstProgram.selector.primaryId, infoCb.selector.primaryId);
+ EXPECT_EQ(firstProgram.selector.primaryId, selCb.primaryId);
+}
+
+TEST_P(BroadcastRadioHalTest, CancelAnnouncement) {
+ if (skipped) return;
+ ASSERT_TRUE(openTuner(0));
+
+ auto hidlResult = mTuner->cancelAnnouncement();
+ EXPECT_EQ(Result::OK, hidlResult);
}
INSTANTIATE_TEST_CASE_P(BroadcastRadioHalTestCases, BroadcastRadioHalTest,
c3354ab0d381a236c12dc486ad4b6bec28c979d26748b4661f12ede36f392808 android.hardware.wifi.offload@1.0::IOffloadCallback
b18caefefcc765092412285d776234fcf213b73bdf07ae1b67a5f71b2d2464e3 android.hardware.wifi.offload@1.0::types
c26473e2e4a00af43e28a0ddf9002e5062a7d0940429e5efb6e5513a8abcb75c android.hardware.wifi@1.1::IWifi
-48adfb7259e3816a82a4c394ffaf56fb14628a542295b7a51f1311392d3f8769 android.hardware.wifi@1.1::IWifiChip
+bfcf4856c7b6c66ebc56785ed3e5d181b7be859c2add672497a843b024518737 android.hardware.wifi@1.1::IWifiChip
Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId) {
- mSharedBufferMap[bufferId] = mapMemory(base);
+ sp<IMemory> hidlMemory = mapMemory(base);
+ ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr");
+
+ // allow mapMemory to return nullptr
+ mSharedBufferMap[bufferId] = hidlMemory;
return Void();
}
AString detailMessage;
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
+ if (sourceBase == nullptr) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
+ return Void();
+ }
if (source.offset + offset + source.size > sourceBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
+ if (destBase == nullptr) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+ return Void();
+ }
+
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
drmFactory =
::testing::VtsHalHidlTargetTestBase::getService<IDrmFactory>();
- ASSERT_NE(drmFactory, nullptr);
+ ASSERT_NE(nullptr, drmFactory.get());
cryptoFactory =
::testing::VtsHalHidlTargetTestBase::getService<ICryptoFactory>();
- ASSERT_NE(cryptoFactory, nullptr);
+ ASSERT_NE(nullptr, cryptoFactory.get());
}
virtual void TearDown() override {}
kClearKeyUUID, packageName,
[&](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- EXPECT_NE(plugin, nullptr);
+ EXPECT_NE(nullptr, plugin.get());
});
EXPECT_OK(res);
}
kClearKeyUUID, initVec,
[&](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- EXPECT_NE(plugin, nullptr);
+ EXPECT_NE(nullptr, plugin.get());
});
EXPECT_OK(res);
}
kInvalidUUID, packageName,
[&](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
- EXPECT_EQ(plugin, nullptr);
+ EXPECT_EQ(nullptr, plugin.get());
});
EXPECT_OK(res);
}
kInvalidUUID, initVec,
[&](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
- EXPECT_EQ(plugin, nullptr);
+ EXPECT_EQ(nullptr, plugin.get());
});
EXPECT_OK(res);
}
// Create factories
DrmHalClearkeyFactoryTest::SetUp();
- ASSERT_NE(drmFactory, nullptr);
+ ASSERT_NE(nullptr, drmFactory.get());
hidl_string packageName("android.hardware.drm.test");
auto res = drmFactory->createPlugin(
kClearKeyUUID, packageName,
[this](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- ASSERT_NE(plugin, nullptr);
+ ASSERT_NE(nullptr, plugin.get());
drmPlugin = plugin;
});
ASSERT_OK(res);
kClearKeyUUID, initVec,
[this](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- ASSERT_NE(plugin, nullptr);
+ ASSERT_NE(nullptr, plugin.get());
cryptoPlugin = plugin;
});
ASSERT_OK(res);
sp<IMemory> DrmHalClearkeyPluginTest::getDecryptMemory(size_t size,
size_t index) {
sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
- EXPECT_NE(ashmemAllocator, nullptr);
+ EXPECT_NE(nullptr, ashmemAllocator.get());
hidl_memory hidlMemory;
auto res = ashmemAllocator->allocate(
EXPECT_OK(res);
sp<IMemory> mappedMemory = mapMemory(hidlMemory);
+ EXPECT_NE(nullptr, mappedMemory.get());
EXPECT_OK(cryptoPlugin->setSharedBufferBase(hidlMemory, index));
return mappedMemory;
}
test_info->test_case_name(), test_info->name(),
GetParam().c_str());
- ASSERT_NE(vendorModule, nullptr);
+ ASSERT_NE(nullptr, vendorModule.get());
// First try the binderized service name provided by the vendor module.
// If that fails, which it can on non-binderized devices, try the default
if (drmFactory == nullptr) {
drmFactory = VtsTestBase::getService<IDrmFactory>();
}
- ASSERT_NE(drmFactory, nullptr);
+ ASSERT_NE(nullptr, drmFactory.get());
// Do the same for the crypto factory
cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name);
if (cryptoFactory == nullptr) {
cryptoFactory = VtsTestBase::getService<ICryptoFactory>();
}
- ASSERT_NE(cryptoFactory, nullptr);
+ ASSERT_NE(nullptr, cryptoFactory.get());
// If drm scheme not installed skip subsequent tests
if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) {
getVendorUUID(), packageName,
[&](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- EXPECT_NE(plugin, nullptr);
+ EXPECT_NE(nullptr, plugin.get());
});
EXPECT_OK(res);
}
getVendorUUID(), initVec,
[&](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- EXPECT_NE(plugin, nullptr);
+ EXPECT_NE(nullptr, plugin.get());
});
EXPECT_OK(res);
}
kInvalidUUID, packageName,
[&](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
- EXPECT_EQ(plugin, nullptr);
+ EXPECT_EQ(nullptr, plugin.get());
});
EXPECT_OK(res);
}
kInvalidUUID, initVec,
[&](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
- EXPECT_EQ(plugin, nullptr);
+ EXPECT_EQ(nullptr, plugin.get());
});
EXPECT_OK(res);
}
getVendorUUID(), packageName,
[this](Status status, const sp<IDrmPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- ASSERT_NE(plugin, nullptr);
+ ASSERT_NE(nullptr, plugin.get());
drmPlugin = plugin;
});
ASSERT_OK(res);
getVendorUUID(), initVec,
[this](Status status, const sp<ICryptoPlugin>& plugin) {
EXPECT_EQ(Status::OK, status);
- ASSERT_NE(plugin, nullptr);
+ ASSERT_NE(nullptr, plugin.get());
cryptoPlugin = plugin;
});
ASSERT_OK(res);
sp<IMemory> DrmHalVendorPluginTest::getDecryptMemory(size_t size,
size_t index) {
sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
- EXPECT_NE(ashmemAllocator, nullptr);
+ EXPECT_NE(nullptr, ashmemAllocator.get());
hidl_memory hidlMemory;
auto res = ashmemAllocator->allocate(
EXPECT_OK(res);
sp<IMemory> mappedMemory = mapMemory(hidlMemory);
- EXPECT_NE(mappedMemory, nullptr);
+ EXPECT_NE(nullptr, mappedMemory.get());
res = cryptoPlugin->setSharedBufferBase(hidlMemory, index);
EXPECT_OK(res);
return mappedMemory;
AudioDecHidlTest::standardComp comp) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
- int timeOut = TIMEOUT_COUNTER;
+ int timeOut = TIMEOUT_COUNTER_Q;
while (timeOut--) {
size_t i = 0;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
EXPECT_EQ(msg.type, Message::Type::EVENT);
packedArgs audioArgs = {eEncoding, comp};
size_t index;
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
+ timeOut = TIMEOUT_COUNTER_Q;
}
- timeOut--;
}
}
frameID++;
}
- int timeOut = TIMEOUT_COUNTER;
- bool stall = false;
+ int timeOut = TIMEOUT_COUNTER_Q;
+ bool iQueued, oQueued;
while (1) {
+ iQueued = oQueued = false;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
// Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK &&
(*Info)[frameID].bytesCount, flags,
(*Info)[frameID].timestamp);
frameID++;
- stall = false;
- } else
- stall = true;
+ iQueued = true;
+ }
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
- stall = false;
- } else
- stall = true;
- if (stall)
- timeOut--;
+ oQueued = true;
+ }
+ if (iQueued || oQueued)
+ timeOut = TIMEOUT_COUNTER_Q;
else
- timeOut = TIMEOUT_COUNTER;
+ timeOut--;
if (timeOut == 0) {
EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
break;
decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0,
nFrames, compName, false);
- // Note: Assumes 200 ms is enough to end any decode call that started
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
- kPortIndexOutput, 200000);
+ kPortIndexOutput);
framesReceived = 0;
// Seek to next key frame and start decoding till the end
kPortIndexInput, kPortIndexOutput, eleStream, &Info,
index, Info.size() - index, compName, false);
}
- // Note: Assumes 200 ms is enough to end any decode call that started
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
- kPortIndexOutput, 200000);
+ kPortIndexOutput);
framesReceived = 0;
// set state to idle
android::Vector<BufferInfo>* oBuffer) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
- int timeOut = TIMEOUT_COUNTER;
+ int timeOut = TIMEOUT_COUNTER_Q;
while (timeOut--) {
size_t i = 0;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
EXPECT_EQ(status,
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
// status == TIMED_OUT, it could be due to process time being large
size_t index;
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
+ timeOut = TIMEOUT_COUNTER_Q;
}
- timeOut--;
}
}
nFrames--;
}
- int timeOut = TIMEOUT_COUNTER;
- bool stall = false;
+ int timeOut = TIMEOUT_COUNTER_Q;
+ bool iQueued, oQueued;
while (1) {
+ iQueued = oQueued = false;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK)
ASSERT_TRUE(false);
timestamp);
timestamp += timestampIncr;
nFrames--;
- stall = false;
- } else
- stall = true;
+ iQueued = true;
+ }
// Dispatch output buffer
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
- stall = false;
- } else
- stall = true;
- if (stall)
- timeOut--;
+ oQueued = true;
+ }
+ if (iQueued || oQueued)
+ timeOut = TIMEOUT_COUNTER_Q;
else
- timeOut = TIMEOUT_COUNTER;
+ timeOut--;
if (timeOut == 0) {
EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
break;
}
}
- int timeOut = TIMEOUT_COUNTER;
+ int timeOut = TIMEOUT_COUNTER_PE;
while (timeOut--) {
// Dispatch all client owned output buffers to recover remaining frames
while (1) {
// if dispatch is successful, perhaps there is a latency
// in the component. Dont be in a haste to leave. reset timeout
// counter
- timeOut = TIMEOUT_COUNTER;
+ timeOut = TIMEOUT_COUNTER_PE;
} else {
break;
}
}
Message msg;
- status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_PE, iBuffer,
+ oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
if (fptr) {
#include <media/openmax/OMX_AudioExt.h>
#include <media/openmax/OMX_VideoExt.h>
+/* TIME OUTS (Wait time in dequeueMessage()) */
+
+/* As component is switching states (loaded<->idle<->execute), dequeueMessage()
+ * expects the events to be received within this duration */
#define DEFAULT_TIMEOUT 100000
-#define TIMEOUT_COUNTER (10000000 / DEFAULT_TIMEOUT)
+/* Time interval between successive Input/Output enqueues */
+#define DEFAULT_TIMEOUT_Q 2000
+/* While the component is amidst a process call, asynchronous commands like
+ * flush, change states can get delayed (at max by process call time). Instead
+ * of waiting on DEFAULT_TIMEOUT, we give an additional leeway. */
+#define DEFAULT_TIMEOUT_PE 500000
+
+/* Breakout Timeout :: 5 sec*/
+#define TIMEOUT_COUNTER_Q (5000000 / DEFAULT_TIMEOUT_Q)
+#define TIMEOUT_COUNTER_PE (5000000 / DEFAULT_TIMEOUT_PE)
/*
* Random Index used for monkey testing while get/set parameters
void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
- OMX_U32 kPortIndexOutput, int64_t timeoutUs = DEFAULT_TIMEOUT);
+ OMX_U32 kPortIndexOutput,
+ int64_t timeoutUs = DEFAULT_TIMEOUT_PE);
typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
PortMode oPortMode) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
- int timeOut = TIMEOUT_COUNTER;
+ int timeOut = TIMEOUT_COUNTER_Q;
while (timeOut--) {
size_t i = 0;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
EXPECT_EQ(msg.type, Message::Type::EVENT);
portReconfiguration(omxNode, observer, iBuffer, oBuffer,
size_t index;
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
+ timeOut = TIMEOUT_COUNTER_Q;
}
- timeOut--;
}
}
frameID++;
}
- int timeOut = TIMEOUT_COUNTER;
- bool stall = false;
+ int timeOut = TIMEOUT_COUNTER_Q;
+ bool iQueued, oQueued;
while (1) {
+ iQueued = oQueued = false;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
// Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK &&
(*Info)[frameID].bytesCount, flags,
(*Info)[frameID].timestamp);
frameID++;
- stall = false;
- } else
- stall = true;
+ iQueued = true;
+ }
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
- stall = false;
- } else
- stall = true;
- if (stall)
- timeOut--;
+ oQueued = true;
+ }
+ if (iQueued || oQueued)
+ timeOut = TIMEOUT_COUNTER_Q;
else
- timeOut = TIMEOUT_COUNTER;
+ timeOut--;
if (timeOut == 0) {
EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
break;
decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1],
false);
- // Note: Assumes 200 ms is enough to end any decode call that started
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
- kPortIndexOutput, 200000);
+ kPortIndexOutput);
framesReceived = 0;
// Seek to next key frame and start decoding till the end
kPortIndexOutput, eleStream, &Info, index,
Info.size() - index, portMode[1], false);
}
- // Note: Assumes 200 ms is enough to end any decode call that started
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
- kPortIndexOutput, 200000);
+ kPortIndexOutput);
framesReceived = 0;
// set state to idle
sp<CodecProducerListener> listener = nullptr) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
- int timeOut = TIMEOUT_COUNTER;
+ int timeOut = TIMEOUT_COUNTER_Q;
while (timeOut--) {
size_t i = 0;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
EXPECT_EQ(status,
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
// status == TIMED_OUT, it could be due to process time being large
size_t index;
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
+ timeOut = TIMEOUT_COUNTER_Q;
}
}
}
}
}
- int timeOut = TIMEOUT_COUNTER;
- bool stall = false;
+ int timeOut = TIMEOUT_COUNTER_Q;
+ bool iQueued, oQueued;
while (1) {
+ iQueued = oQueued = false;
status =
- observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+ observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
ASSERT_EQ(msg.type, Message::Type::EVENT);
timestamp += timestampIncr;
nFrames--;
ipCount++;
- stall = false;
- } else {
- stall = true;
+ iQueued = true;
}
} else {
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
timestamp += timestampIncr;
nFrames--;
ipCount++;
- stall = false;
- } else {
- stall = true;
+ iQueued = true;
}
}
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
dispatchOutputBuffer(omxNode, oBuffer, index);
- stall = false;
- } else
- stall = true;
- if (stall)
- timeOut--;
+ oQueued = true;
+ }
+ if (iQueued || oQueued)
+ timeOut = TIMEOUT_COUNTER_Q;
else
- timeOut = TIMEOUT_COUNTER;
+ timeOut--;
if (timeOut == 0) {
EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
break;
#ifndef MEDIA_VIDEO_HIDL_TEST_COMMON_H
#define MEDIA_VIDEO_HIDL_TEST_COMMON_H
-
/*
* Common video utils
*/
name: "android.hardware.tests.bar@1.0-impl",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Bar.cpp",
"ImportTypes.cpp",
name: "android.hardware.tests.baz@1.0-impl",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Baz.cpp",
],
name: "android.hardware.tests.foo@1.0-impl",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Foo.cpp",
],
cc_library_shared {
name: "libfootest",
- vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"FooHelper.cpp"
cc_library_shared {
name: "android.hardware.tests.hash@1.0-impl",
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Hash.cpp",
],
name: "android.hardware.tests.inheritance@1.0-impl",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Fetcher.cpp",
"Parent.cpp",
cc_library_shared {
name: "android.hardware.tests.memory@1.0-impl",
defaults: ["hidl_defaults"],
- proprietary: true,
relative_install_path: "hw",
srcs: [
"MemoryTest.cpp",
name: "android.hardware.tests.pointer@1.0-impl",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
- proprietary: true,
srcs: [
"Graph.cpp",
"Pointer.cpp",
cc_library_shared {
name: "libpointertest",
- vendor: true,
defaults: ["hidl_defaults"],
srcs: [
"PointerHelper.cpp"
#include "wifi_hidl_test_utils.h"
+WifiHidlEnvironment* gEnv;
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+ gEnv = new WifiHidlEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ }
return status;
}
using ::android::hardware::wifi::V1_0::IWifiRttController;
using ::android::hardware::wifi::V1_0::IWifiStaIface;
+extern WifiHidlEnvironment* gEnv;
+
namespace {
constexpr WifiDebugRingBufferVerboseLevel kDebugRingBufferVerboseLvl =
WifiDebugRingBufferVerboseLevel::VERBOSE;
// to be first configured.
ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
ChipModeId mode_id;
- EXPECT_EQ(expectSuccess, configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
+ EXPECT_EQ(expectSuccess,
+ configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
return mode_id;
}
* succeeds. The 2nd iface creation should be rejected.
*/
TEST_F(WifiChipHidlTest, CreateNanIface) {
- configureChipForIfaceType(IfaceType::NAN, false);
+ configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+ if (!gEnv->isNanOn) return;
sp<IWifiNanIface> iface;
- ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&iface));
+ ASSERT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
+ EXPECT_NE(nullptr, iface.get());
+
+ EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&iface));
}
/*
* iface name is returned via the list.
*/
TEST_F(WifiChipHidlTest, GetNanIfaceNames) {
- configureChipForIfaceType(IfaceType::NAN, false);
+ configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+ if (!gEnv->isNanOn) return;
const auto& status_and_iface_names1 =
HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
ASSERT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code);
EXPECT_EQ(0u, status_and_iface_names1.second.size());
+
+ sp<IWifiNanIface> iface;
+ EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
+ EXPECT_NE(nullptr, iface.get());
+
+ std::string iface_name = getIfaceName(iface);
+ const auto& status_and_iface_names2 =
+ HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code);
+ EXPECT_EQ(1u, status_and_iface_names2.second.size());
+ EXPECT_EQ(iface_name, status_and_iface_names2.second[0]);
+
+ EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
+ const auto& status_and_iface_names3 =
+ HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code);
+ EXPECT_EQ(0u, status_and_iface_names3.second.size());
}
/*
* doesn't retrieve an iface object.
*/
TEST_F(WifiChipHidlTest, GetNanIface) {
- configureChipForIfaceType(IfaceType::NAN, false);
+ configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+ if (!gEnv->isNanOn) return;
sp<IWifiNanIface> nan_iface;
- ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&nan_iface));
+ EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
+ EXPECT_NE(nullptr, nan_iface.get());
+
+ std::string iface_name = getIfaceName(nan_iface);
+ const auto& status_and_iface1 =
+ HIDL_INVOKE(wifi_chip_, getNanIface, iface_name);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code);
+ EXPECT_NE(nullptr, status_and_iface1.second.get());
+
+ std::string invalid_name = iface_name + "0";
+ const auto& status_and_iface2 =
+ HIDL_INVOKE(wifi_chip_, getNanIface, invalid_name);
+ EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code);
+ EXPECT_EQ(nullptr, status_and_iface2.second.get());
}
/*
* doesn't remove the iface.
*/
TEST_F(WifiChipHidlTest, RemoveNanIface) {
- configureChipForIfaceType(IfaceType::NAN, false);
+ configureChipForIfaceType(IfaceType::NAN, gEnv->isNanOn);
+ if (!gEnv->isNanOn) return;
sp<IWifiNanIface> nan_iface;
- ASSERT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&nan_iface));
+ EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
+ EXPECT_NE(nullptr, nan_iface.get());
+
+ std::string iface_name = getIfaceName(nan_iface);
+ std::string invalid_name = iface_name + "0";
+ EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(invalid_name));
+
+ EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
+
+ // No such iface exists now. So, this should return failure.
+ EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name));
}
/*
#include <android/hardware/wifi/1.0/IWifiRttController.h>
#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+#include <getopt.h>
+
// Helper functions to obtain references to the various HIDL interface objects.
// Note: We only have a single instance of each of these objects currently.
// These helper functions should be modified to return vectors if we support
void stopWifi();
class WifiHidlEnvironment : public ::testing::Environment {
- public:
- virtual void SetUp() override {
- stopWifi();
- sleep(5);
- }
- virtual void TearDown() override {}
-};
\ No newline at end of file
+ protected:
+ virtual void SetUp() override {
+ stopWifi();
+ sleep(5);
+ }
+
+ public:
+ // Whether NaN feature is supported on the device.
+ bool isNanOn = false;
+
+ void usage(char* me, char* arg) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-N, --nan_on: Whether NAN feature is supported\n",
+ arg, me);
+ }
+
+ int initFromOptions(int argc, char** argv) {
+ static struct option options[] = {{"nan_on", no_argument, 0, 'N'},
+ {0, 0, 0, 0}};
+
+ int c;
+ while ((c = getopt_long(argc, argv, "N", options, NULL)) >= 0) {
+ switch (c) {
+ case 'N':
+ isNanOn = true;
+ break;
+ default:
+ usage(argv[0], argv[optind]);
+ return 2;
+ }
+ }
+
+ if (optind < argc) {
+ usage(argv[0], argv[optind]);
+ return 2;
+ }
+
+ return 0;
+ }
+};
/**
* Set/Reset Tx Power limits.
*/
- SET_TX_POWER_LIMIT = 1 << 8
+ SET_TX_POWER_LIMIT = 1 << 8,
+ /**
+ * Device to Device RTT.
+ */
+ D2D_RTT = 1 << 9,
+ /**
+ * Device to AP RTT.
+ */
+ D2AP_RTT = 1 << 10
};
/**
switch (feature) {
case WIFI_FEATURE_SET_TX_POWER_LIMIT:
return HidlChipCaps::SET_TX_POWER_LIMIT;
+ case WIFI_FEATURE_D2D_RTT:
+ return HidlChipCaps::D2D_RTT;
+ case WIFI_FEATURE_D2AP_RTT:
+ return HidlChipCaps::D2AP_RTT;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
*hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
}
}
- for (const auto feature : {WIFI_FEATURE_SET_TX_POWER_LIMIT}) {
+ for (const auto feature : {WIFI_FEATURE_SET_TX_POWER_LIMIT,
+ WIFI_FEATURE_D2D_RTT,
+ WIFI_FEATURE_D2AP_RTT}) {
if (feature & legacy_feature_set) {
*hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature);
}
#include "wifi_hidl_test_utils.h"
+WifiHidlEnvironment* gEnv;
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+ gEnv = new WifiHidlEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ }
return status;
}