OSDN Git Service

release-request-fbba21d1-17b5-4752-9864-95770e5db190-for-git_oc-mr1-release-4144771...
[android-x86/hardware-interfaces.git] / broadcastradio / 1.1 / vts / functional / VtsHalBroadcastradioV1_1TargetTest.cpp
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
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>
24
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>
30
31
32 namespace V1_0 = ::android::hardware::broadcastradio::V1_0;
33
34 using ::android::sp;
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;
51
52
53 // The main test class for Broadcast Radio HIDL HAL.
54
55 class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
56  protected:
57     virtual void SetUp() override {
58         auto factory = ::testing::VtsHalHidlTargetTestBase::getService<IBroadcastRadioFactory>();
59         if (factory != 0) {
60             factory->connectModule(Class::AM_FM,
61                              [&](Result retval, const ::android::sp<IBroadcastRadio>& result) {
62                 if (retval == Result::OK) {
63                   mRadio = IBroadcastRadio::castFrom(result);
64                 }
65             });
66         }
67         mTunerCallback = new MyCallback(this);
68         ASSERT_NE(nullptr, mRadio.get());
69         ASSERT_NE(nullptr, mTunerCallback.get());
70     }
71
72     virtual void TearDown() override {
73         mTuner.clear();
74         mRadio.clear();
75     }
76
77     class MyCallback : public ITunerCallback {
78      public:
79
80         // ITunerCallback methods (see doc in ITunerCallback.hal)
81         virtual Return<void> hardwareFailure() {
82             ALOGI("%s", __FUNCTION__);
83             mParentTest->onHwFailureCallback();
84             return Void();
85         }
86
87         virtual Return<void> configChange(Result result, const BandConfig& config __unused) {
88             ALOGI("%s result %d", __FUNCTION__, result);
89             mParentTest->onResultCallback(result);
90             return Void();
91         }
92
93         virtual Return<void> tuneComplete(Result result __unused, const V1_0::ProgramInfo& info __unused) {
94             return Void();
95         }
96
97         virtual Return<void> tuneComplete_1_1(Result result, const ProgramInfo& info __unused) {
98             ALOGI("%s result %d", __FUNCTION__, result);
99             mParentTest->onResultCallback(result);
100             return Void();
101         }
102
103         virtual Return<void> afSwitch(const V1_0::ProgramInfo& info __unused) {
104             return Void();
105         }
106
107         virtual Return<void> afSwitch_1_1(const ProgramInfo& info __unused) {
108             return Void();
109         }
110
111         virtual Return<void> antennaStateChange(bool connected) {
112             ALOGI("%s connected %d", __FUNCTION__, connected);
113             return Void();
114         }
115
116         virtual Return<void> trafficAnnouncement(bool active) {
117             ALOGI("%s active %d", __FUNCTION__, active);
118             return Void();
119         }
120
121         virtual Return<void> emergencyAnnouncement(bool active) {
122             ALOGI("%s active %d", __FUNCTION__, active);
123             return Void();
124         }
125
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__);
129             return Void();
130         }
131
132         virtual Return<void> backgroundScanAvailable(bool isAvailable __unused) {
133             return Void();
134         }
135
136         virtual Return<void> backgroundScanComplete(ProgramListResult result __unused) {
137             return Void();
138         }
139
140         virtual Return<void> programListChanged() {
141             return Void();
142         }
143
144                 MyCallback(BroadcastRadioHidlTest *parentTest) : mParentTest(parentTest) {}
145
146      private:
147         // BroadcastRadioHidlTest instance to which callbacks will be notified.
148         BroadcastRadioHidlTest *mParentTest;
149     };
150
151
152     /**
153      * Method called by MyCallback when a callback with no status or boolean value is received
154      */
155     void onCallback() {
156         Mutex::Autolock _l(mLock);
157         onCallback_l();
158     }
159
160     /**
161      * Method called by MyCallback when hardwareFailure() callback is received
162      */
163     void onHwFailureCallback() {
164         Mutex::Autolock _l(mLock);
165         mHwFailure = true;
166         onCallback_l();
167     }
168
169     /**
170      * Method called by MyCallback when a callback with status is received
171      */
172     void onResultCallback(Result result) {
173         Mutex::Autolock _l(mLock);
174         mResultCallbackData = result;
175         onCallback_l();
176     }
177
178     /**
179      * Method called by MyCallback when a boolean indication is received
180      */
181     void onBoolCallback(bool result) {
182         Mutex::Autolock _l(mLock);
183         mBoolCallbackData = result;
184         onCallback_l();
185     }
186
187
188         BroadcastRadioHidlTest() :
189             mCallbackCalled(false), mBoolCallbackData(false),
190             mResultCallbackData(Result::OK), mHwFailure(false) {}
191
192     void onCallback_l() {
193         if (!mCallbackCalled) {
194             mCallbackCalled = true;
195             mCallbackCond.broadcast();
196         }
197     }
198
199
200     bool waitForCallback(nsecs_t reltime = 0) {
201         Mutex::Autolock _l(mLock);
202         nsecs_t endTime = systemTime() + reltime;
203         while (!mCallbackCalled) {
204             if (reltime == 0) {
205                 mCallbackCond.wait(mLock);
206             } else {
207                 nsecs_t now = systemTime();
208                 if (now > endTime) {
209                     return false;
210                 }
211                 mCallbackCond.waitRelative(mLock, endTime - now);
212             }
213         }
214         return true;
215     }
216
217     bool getProperties();
218     bool openTuner();
219     bool checkAntenna();
220
221     static const nsecs_t kConfigCallbacktimeoutNs = seconds_to_nanoseconds(10);
222     static const nsecs_t kTuneCallbacktimeoutNs = seconds_to_nanoseconds(30);
223
224     sp<IBroadcastRadio> mRadio;
225     Properties mHalProperties;
226     sp<ITuner> mTuner;
227     sp<MyCallback> mTunerCallback;
228     Mutex mLock;
229     Condition mCallbackCond;
230     bool mCallbackCalled;
231     bool mBoolCallbackData;
232     Result mResultCallbackData;
233     bool mHwFailure;
234 };
235
236 // A class for test environment setup (kept since this file is a template).
237 class BroadcastRadioHidlEnvironment : public ::testing::Environment {
238  public:
239     virtual void SetUp() {}
240     virtual void TearDown() {}
241 };
242
243 bool BroadcastRadioHidlTest::getProperties()
244 {
245     if (mHalProperties.bands.size() == 0) {
246         Result halResult = Result::NOT_INITIALIZED;
247         Return<void> hidlReturn =
248                 mRadio->getProperties([&](Result result, const Properties& properties) {
249                         halResult = result;
250                         if (result == Result::OK) {
251                             mHalProperties = properties;
252                         }
253                     });
254
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);
260     }
261     return mHalProperties.bands.size() > 0;
262 }
263
264 bool BroadcastRadioHidlTest::openTuner()
265 {
266     if (!getProperties()) {
267         return false;
268     }
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) {
273                     halResult = result;
274                     if (result == Result::OK) {
275                         mTuner = ITuner::castFrom(tuner);
276                     }
277                 });
278         EXPECT_TRUE(hidlReturn.isOk());
279         EXPECT_EQ(Result::OK, halResult);
280         EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
281     }
282     EXPECT_NE(nullptr, mTuner.get());
283     return nullptr != mTuner.get();
284 }
285
286 bool BroadcastRadioHidlTest::checkAntenna()
287 {
288     BandConfig halConfig;
289     Result halResult = Result::NOT_INITIALIZED;
290     Return<void> hidlReturn =
291             mTuner->getConfiguration([&](Result result, const BandConfig& config) {
292                 halResult = result;
293                 if (result == Result::OK) {
294                     halConfig = config;
295                 }
296             });
297
298     return ((halResult == Result::OK) && (halConfig.antennaConnected == true));
299 }
300
301
302 /**
303  * Test IBroadcastRadio::getProperties() method
304  *
305  * Verifies that:
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
311  */
312 TEST_F(BroadcastRadioHidlTest, GetProperties) {
313     EXPECT_TRUE(getProperties());
314 }
315
316 /**
317  * Test IBroadcastRadio::openTuner() method
318  *
319  * Verifies that:
320  *  - the HAL implements the method
321  *  - the method returns 0 (no error) and a valid ITuner interface
322  */
323 TEST_F(BroadcastRadioHidlTest, OpenTuner) {
324     EXPECT_TRUE(openTuner());
325 }
326
327 /**
328  * Test ITuner::setConfiguration() and getConfiguration methods
329  *
330  * Verifies that:
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
335  */
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);
345
346     // test getConfiguration
347     BandConfig halConfig;
348     Result halResult;
349     Return<void> hidlReturn =
350             mTuner->getConfiguration([&](Result result, const BandConfig& config) {
351                 halResult = result;
352                 if (result == Result::OK) {
353                     halConfig = config;
354                 }
355             });
356     EXPECT_TRUE(hidlReturn.isOk());
357     EXPECT_EQ(Result::OK, halResult);
358     EXPECT_EQ(mHalProperties.bands[0].type, halConfig.type);
359 }
360
361 /**
362  * Test ITuner::scan
363  *
364  * Verifies that:
365  *  - the HAL implements the method
366  *  - the method returns 0 (no error)
367  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
368  */
369 TEST_F(BroadcastRadioHidlTest, Scan) {
370     ASSERT_TRUE(openTuner());
371     ASSERT_TRUE(checkAntenna());
372     // test scan UP
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));
378
379     // test scan DOWN
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));
385 }
386
387 /**
388  * Test ITuner::step
389  *
390  * Verifies that:
391  *  - the HAL implements the method
392  *  - the method returns 0 (no error)
393  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
394  */
395 TEST_F(BroadcastRadioHidlTest, Step) {
396     ASSERT_TRUE(openTuner());
397     ASSERT_TRUE(checkAntenna());
398     // test step UP
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));
404
405     // test step DOWN
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));
411 }
412
413 /**
414  * Test ITuner::tune,  getProgramInformation and cancel methods
415  *
416  * Verifies that:
417  *  - the HAL implements the methods
418  *  - the methods return 0 (no error)
419  *  - the tuned callback is received within kTuneCallbacktimeoutNs ns after tune()
420  */
421 TEST_F(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
422     ASSERT_TRUE(openTuner());
423     ASSERT_TRUE(checkAntenna());
424
425     // test tune
426     ASSERT_GT(mHalProperties.bands[0].spacings.size(), 0u);
427     ASSERT_GT(mHalProperties.bands[0].upperLimit, mHalProperties.bands[0].lowerLimit);
428
429     // test scan UP
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];
433
434     uint32_t channel =
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));
442
443     // test getProgramInformation
444     ProgramInfo halInfo;
445     Result halResult = Result::NOT_INITIALIZED;
446     Return<void> hidlReturn = mTuner->getProgramInformation_1_1(
447         [&](Result result, const ProgramInfo& info) {
448             halResult = result;
449             if (result == Result::OK) {
450                 halInfo = info;
451             }
452         });
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);
460     } else {
461         EXPECT_EQ(false, halInfo_1_1.tuned);
462     }
463
464     // test cancel
465     mTuner->tune(lowerLimit, 0);
466     hidlResult = mTuner->cancel();
467     EXPECT_TRUE(hidlResult.isOk());
468     EXPECT_EQ(Result::OK, hidlResult);
469 }
470
471
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);
477   return status;
478 }