2 * Copyright (C) 2017 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define LOG_TAG "BroadcastRadioHidlHalTest"
18 #include <VtsHalHidlTargetTestBase.h>
19 #include <android-base/logging.h>
20 #include <cutils/native_handle.h>
21 #include <cutils/properties.h>
22 #include <hidl/HidlTransportSupport.h>
23 #include <utils/threads.h>
25 #include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
26 #include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
27 #include <android/hardware/broadcastradio/1.1/ITuner.h>
28 #include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
29 #include <android/hardware/broadcastradio/1.1/types.h>
32 namespace V1_0 = ::android::hardware::broadcastradio::V1_0;
35 using ::android::Mutex;
36 using ::android::Condition;
37 using ::android::hardware::Return;
38 using ::android::hardware::Void;
39 using ::android::hardware::broadcastradio::V1_0::BandConfig;
40 using ::android::hardware::broadcastradio::V1_0::Class;
41 using ::android::hardware::broadcastradio::V1_0::Direction;
42 using ::android::hardware::broadcastradio::V1_0::IBroadcastRadio;
43 using ::android::hardware::broadcastradio::V1_0::MetaData;
44 using ::android::hardware::broadcastradio::V1_0::Properties;
45 using ::android::hardware::broadcastradio::V1_1::IBroadcastRadioFactory;
46 using ::android::hardware::broadcastradio::V1_1::ITuner;
47 using ::android::hardware::broadcastradio::V1_1::ITunerCallback;
48 using ::android::hardware::broadcastradio::V1_1::ProgramInfo;
49 using ::android::hardware::broadcastradio::V1_1::Result;
50 using ::android::hardware::broadcastradio::V1_1::ProgramListResult;
53 // The main test class for Broadcast Radio HIDL HAL.
55 class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
57 virtual void SetUp() override {
58 auto factory = ::testing::VtsHalHidlTargetTestBase::getService<IBroadcastRadioFactory>();
60 factory->connectModule(Class::AM_FM,
61 [&](Result retval, const ::android::sp<IBroadcastRadio>& result) {
62 if (retval == Result::OK) {
63 mRadio = IBroadcastRadio::castFrom(result);
67 mTunerCallback = new MyCallback(this);
68 ASSERT_NE(nullptr, mRadio.get());
69 ASSERT_NE(nullptr, mTunerCallback.get());
72 virtual void TearDown() override {
77 class MyCallback : public ITunerCallback {
80 // ITunerCallback methods (see doc in ITunerCallback.hal)
81 virtual Return<void> hardwareFailure() {
82 ALOGI("%s", __FUNCTION__);
83 mParentTest->onHwFailureCallback();
87 virtual Return<void> configChange(Result result, const BandConfig& config __unused) {
88 ALOGI("%s result %d", __FUNCTION__, result);
89 mParentTest->onResultCallback(result);
93 virtual Return<void> tuneComplete(Result result __unused, const V1_0::ProgramInfo& info __unused) {
97 virtual Return<void> tuneComplete_1_1(Result result, const ProgramInfo& info __unused) {
98 ALOGI("%s result %d", __FUNCTION__, result);
99 mParentTest->onResultCallback(result);
103 virtual Return<void> afSwitch(const V1_0::ProgramInfo& info __unused) {
107 virtual Return<void> afSwitch_1_1(const ProgramInfo& info __unused) {
111 virtual Return<void> antennaStateChange(bool connected) {
112 ALOGI("%s connected %d", __FUNCTION__, connected);
116 virtual Return<void> trafficAnnouncement(bool active) {
117 ALOGI("%s active %d", __FUNCTION__, active);
121 virtual Return<void> emergencyAnnouncement(bool active) {
122 ALOGI("%s active %d", __FUNCTION__, active);
126 virtual Return<void> newMetadata(uint32_t channel __unused, uint32_t subChannel __unused,
127 const ::android::hardware::hidl_vec<MetaData>& metadata __unused) {
128 ALOGI("%s", __FUNCTION__);
132 virtual Return<void> backgroundScanAvailable(bool isAvailable __unused) {
136 virtual Return<void> backgroundScanComplete(ProgramListResult result __unused) {
140 virtual Return<void> programListChanged() {
144 MyCallback(BroadcastRadioHidlTest *parentTest) : mParentTest(parentTest) {}
147 // BroadcastRadioHidlTest instance to which callbacks will be notified.
148 BroadcastRadioHidlTest *mParentTest;
153 * Method called by MyCallback when a callback with no status or boolean value is received
156 Mutex::Autolock _l(mLock);
161 * Method called by MyCallback when hardwareFailure() callback is received
163 void onHwFailureCallback() {
164 Mutex::Autolock _l(mLock);
170 * Method called by MyCallback when a callback with status is received
172 void onResultCallback(Result result) {
173 Mutex::Autolock _l(mLock);
174 mResultCallbackData = result;
179 * Method called by MyCallback when a boolean indication is received
181 void onBoolCallback(bool result) {
182 Mutex::Autolock _l(mLock);
183 mBoolCallbackData = result;
188 BroadcastRadioHidlTest() :
189 mCallbackCalled(false), mBoolCallbackData(false),
190 mResultCallbackData(Result::OK), mHwFailure(false) {}
192 void onCallback_l() {
193 if (!mCallbackCalled) {
194 mCallbackCalled = true;
195 mCallbackCond.broadcast();
200 bool waitForCallback(nsecs_t reltime = 0) {
201 Mutex::Autolock _l(mLock);
202 nsecs_t endTime = systemTime() + reltime;
203 while (!mCallbackCalled) {
205 mCallbackCond.wait(mLock);
207 nsecs_t now = systemTime();
211 mCallbackCond.waitRelative(mLock, endTime - now);
217 bool getProperties();
221 static const nsecs_t kConfigCallbacktimeoutNs = seconds_to_nanoseconds(10);
222 static const nsecs_t kTuneCallbacktimeoutNs = seconds_to_nanoseconds(30);
224 sp<IBroadcastRadio> mRadio;
225 Properties mHalProperties;
227 sp<MyCallback> mTunerCallback;
229 Condition mCallbackCond;
230 bool mCallbackCalled;
231 bool mBoolCallbackData;
232 Result mResultCallbackData;
236 // A class for test environment setup (kept since this file is a template).
237 class BroadcastRadioHidlEnvironment : public ::testing::Environment {
239 virtual void SetUp() {}
240 virtual void TearDown() {}
243 bool BroadcastRadioHidlTest::getProperties()
245 if (mHalProperties.bands.size() == 0) {
246 Result halResult = Result::NOT_INITIALIZED;
247 Return<void> hidlReturn =
248 mRadio->getProperties([&](Result result, const Properties& properties) {
250 if (result == Result::OK) {
251 mHalProperties = properties;
255 EXPECT_TRUE(hidlReturn.isOk());
256 EXPECT_EQ(Result::OK, halResult);
257 EXPECT_EQ(Class::AM_FM, mHalProperties.classId);
258 EXPECT_GT(mHalProperties.numTuners, 0u);
259 EXPECT_GT(mHalProperties.bands.size(), 0u);
261 return mHalProperties.bands.size() > 0;
264 bool BroadcastRadioHidlTest::openTuner()
266 if (!getProperties()) {
269 if (mTuner.get() == nullptr) {
270 Result halResult = Result::NOT_INITIALIZED;
271 auto hidlReturn = mRadio->openTuner(mHalProperties.bands[0], true, mTunerCallback,
272 [&](Result result, const sp<V1_0::ITuner>& tuner) {
274 if (result == Result::OK) {
275 mTuner = ITuner::castFrom(tuner);
278 EXPECT_TRUE(hidlReturn.isOk());
279 EXPECT_EQ(Result::OK, halResult);
280 EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
282 EXPECT_NE(nullptr, mTuner.get());
283 return nullptr != mTuner.get();
286 bool BroadcastRadioHidlTest::checkAntenna()
288 BandConfig halConfig;
289 Result halResult = Result::NOT_INITIALIZED;
290 Return<void> hidlReturn =
291 mTuner->getConfiguration([&](Result result, const BandConfig& config) {
293 if (result == Result::OK) {
298 return ((halResult == Result::OK) && (halConfig.antennaConnected == true));
303 * Test IBroadcastRadio::getProperties() method
306 * - the HAL implements the method
307 * - the method returns 0 (no error)
308 * - the implementation class is AM_FM
309 * - the implementation supports at least one tuner
310 * - the implementation supports at one band
312 TEST_F(BroadcastRadioHidlTest, GetProperties) {
313 EXPECT_TRUE(getProperties());
317 * Test IBroadcastRadio::openTuner() method
320 * - the HAL implements the method
321 * - the method returns 0 (no error) and a valid ITuner interface
323 TEST_F(BroadcastRadioHidlTest, OpenTuner) {
324 EXPECT_TRUE(openTuner());
328 * Test ITuner::setConfiguration() and getConfiguration methods
331 * - the HAL implements both methods
332 * - the methods return 0 (no error)
333 * - the configuration callback is received within kConfigCallbacktimeoutNs ns
334 * - the configuration read back from HAl has the same class Id
336 TEST_F(BroadcastRadioHidlTest, SetAndGetConfiguration) {
337 ASSERT_TRUE(openTuner());
338 // test setConfiguration
339 mCallbackCalled = false;
340 Return<Result> hidlResult = mTuner->setConfiguration(mHalProperties.bands[0]);
341 EXPECT_TRUE(hidlResult.isOk());
342 EXPECT_EQ(Result::OK, hidlResult);
343 EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
344 EXPECT_EQ(Result::OK, mResultCallbackData);
346 // test getConfiguration
347 BandConfig halConfig;
349 Return<void> hidlReturn =
350 mTuner->getConfiguration([&](Result result, const BandConfig& config) {
352 if (result == Result::OK) {
356 EXPECT_TRUE(hidlReturn.isOk());
357 EXPECT_EQ(Result::OK, halResult);
358 EXPECT_EQ(mHalProperties.bands[0].type, halConfig.type);
365 * - the HAL implements the method
366 * - the method returns 0 (no error)
367 * - the tuned callback is received within kTuneCallbacktimeoutNs ns
369 TEST_F(BroadcastRadioHidlTest, Scan) {
370 ASSERT_TRUE(openTuner());
371 ASSERT_TRUE(checkAntenna());
373 mCallbackCalled = false;
374 Return<Result> hidlResult = mTuner->scan(Direction::UP, true);
375 EXPECT_TRUE(hidlResult.isOk());
376 EXPECT_EQ(Result::OK, hidlResult);
377 EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
380 mCallbackCalled = false;
381 hidlResult = mTuner->scan(Direction::DOWN, true);
382 EXPECT_TRUE(hidlResult.isOk());
383 EXPECT_EQ(Result::OK, hidlResult);
384 EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
391 * - the HAL implements the method
392 * - the method returns 0 (no error)
393 * - the tuned callback is received within kTuneCallbacktimeoutNs ns
395 TEST_F(BroadcastRadioHidlTest, Step) {
396 ASSERT_TRUE(openTuner());
397 ASSERT_TRUE(checkAntenna());
399 mCallbackCalled = false;
400 Return<Result> hidlResult = mTuner->step(Direction::UP, true);
401 EXPECT_TRUE(hidlResult.isOk());
402 EXPECT_EQ(Result::OK, hidlResult);
403 EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
406 mCallbackCalled = false;
407 hidlResult = mTuner->step(Direction::DOWN, true);
408 EXPECT_TRUE(hidlResult.isOk());
409 EXPECT_EQ(Result::OK, hidlResult);
410 EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
414 * Test ITuner::tune, getProgramInformation and cancel methods
417 * - the HAL implements the methods
418 * - the methods return 0 (no error)
419 * - the tuned callback is received within kTuneCallbacktimeoutNs ns after tune()
421 TEST_F(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
422 ASSERT_TRUE(openTuner());
423 ASSERT_TRUE(checkAntenna());
426 ASSERT_GT(mHalProperties.bands[0].spacings.size(), 0u);
427 ASSERT_GT(mHalProperties.bands[0].upperLimit, mHalProperties.bands[0].lowerLimit);
430 uint32_t lowerLimit = mHalProperties.bands[0].lowerLimit;
431 uint32_t upperLimit = mHalProperties.bands[0].upperLimit;
432 uint32_t spacing = mHalProperties.bands[0].spacings[0];
435 lowerLimit + (((upperLimit - lowerLimit) / 2 + spacing - 1) / spacing) * spacing;
436 mCallbackCalled = false;
437 mResultCallbackData = Result::NOT_INITIALIZED;
438 Return<Result> hidlResult = mTuner->tune(channel, 0);
439 EXPECT_TRUE(hidlResult.isOk());
440 EXPECT_EQ(Result::OK, hidlResult);
441 EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
443 // test getProgramInformation
445 Result halResult = Result::NOT_INITIALIZED;
446 Return<void> hidlReturn = mTuner->getProgramInformation_1_1(
447 [&](Result result, const ProgramInfo& info) {
449 if (result == Result::OK) {
453 EXPECT_TRUE(hidlReturn.isOk());
454 EXPECT_EQ(Result::OK, halResult);
455 auto &halInfo_1_1 = halInfo.base;
456 if (mResultCallbackData == Result::OK) {
457 EXPECT_TRUE(halInfo_1_1.tuned);
458 EXPECT_LE(halInfo_1_1.channel, upperLimit);
459 EXPECT_GE(halInfo_1_1.channel, lowerLimit);
461 EXPECT_EQ(false, halInfo_1_1.tuned);
465 mTuner->tune(lowerLimit, 0);
466 hidlResult = mTuner->cancel();
467 EXPECT_TRUE(hidlResult.isOk());
468 EXPECT_EQ(Result::OK, hidlResult);
472 int main(int argc, char** argv) {
473 ::testing::AddGlobalTestEnvironment(new BroadcastRadioHidlEnvironment);
474 ::testing::InitGoogleTest(&argc, argv);
475 int status = RUN_ALL_TESTS();
476 ALOGI("Test result = %d", status);