Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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" |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 18 | #include <android-base/logging.h> |
| 19 | #include <cutils/native_handle.h> |
| 20 | #include <cutils/properties.h> |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 21 | #include <gtest/gtest.h> |
| 22 | #include <hidl/GtestPrinter.h> |
Martijn Coenen | 0282237 | 2016-12-29 14:03:41 +0100 | [diff] [blame] | 23 | #include <hidl/HidlTransportSupport.h> |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 24 | #include <hidl/ServiceManagement.h> |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 25 | #include <utils/threads.h> |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 26 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 27 | #include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h> |
Zhuoyao Zhang | 190548f | 2018-02-08 20:40:23 -0800 | [diff] [blame] | 28 | #include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h> |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 29 | #include <android/hardware/broadcastradio/1.0/ITuner.h> |
| 30 | #include <android/hardware/broadcastradio/1.0/ITunerCallback.h> |
| 31 | #include <android/hardware/broadcastradio/1.0/types.h> |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 32 | #include <broadcastradio-vts-utils/hal-1.x-enum-utils.h> |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 33 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 34 | using ::android::Condition; |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 35 | using ::android::Mutex; |
| 36 | using ::android::sp; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 37 | using ::android::hardware::Return; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 38 | using ::android::hardware::Void; |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 39 | using ::android::hardware::broadcastradio::V1_0::Band; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 40 | using ::android::hardware::broadcastradio::V1_0::BandConfig; |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 41 | using ::android::hardware::broadcastradio::V1_0::Class; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 42 | using ::android::hardware::broadcastradio::V1_0::Direction; |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 43 | using ::android::hardware::broadcastradio::V1_0::IBroadcastRadio; |
| 44 | using ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory; |
| 45 | using ::android::hardware::broadcastradio::V1_0::ITuner; |
| 46 | using ::android::hardware::broadcastradio::V1_0::ITunerCallback; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 47 | using ::android::hardware::broadcastradio::V1_0::MetaData; |
Tomasz Wasilczyk | ba3e254 | 2017-07-17 13:59:21 -0700 | [diff] [blame] | 48 | using ::android::hardware::broadcastradio::V1_0::MetadataKey; |
| 49 | using ::android::hardware::broadcastradio::V1_0::MetadataType; |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 50 | using ::android::hardware::broadcastradio::V1_0::ProgramInfo; |
| 51 | using ::android::hardware::broadcastradio::V1_0::Properties; |
| 52 | using ::android::hardware::broadcastradio::V1_0::Result; |
| 53 | using ::android::hardware::broadcastradio::V1_0::vts::RadioClassFromString; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 54 | |
V,Anilkumar | 86f31e7 | 2022-07-05 23:39:38 +0530 | [diff] [blame^] | 55 | #define RETURN_IF_SKIPPED \ |
| 56 | if (skipped) { \ |
| 57 | GTEST_SKIP() << "This device class is not supported."; \ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 58 | } |
| 59 | |
Tomasz Wasilczyk | 213170b | 2017-02-07 17:38:21 -0800 | [diff] [blame] | 60 | // The main test class for Broadcast Radio HIDL HAL. |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 61 | class BroadcastRadioHidlTest |
| 62 | : public ::testing::TestWithParam<std::tuple<std::string, std::string>> { |
| 63 | protected: |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 64 | virtual void SetUp() override { |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 65 | ASSERT_EQ(nullptr, mRadio.get()); |
| 66 | |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 67 | radioClass = RadioClassFromString(std::get<1>(GetParam())); |
| 68 | |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 69 | skipped = false; |
| 70 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 71 | sp<IBroadcastRadioFactory> factory = |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 72 | IBroadcastRadioFactory::getService(std::get<0>(GetParam())); |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 73 | ASSERT_NE(nullptr, factory.get()); |
| 74 | |
| 75 | Result connectResult; |
| 76 | factory->connectModule(radioClass, [&](Result ret, const sp<IBroadcastRadio>& radio) { |
| 77 | connectResult = ret; |
| 78 | mRadio = radio; |
| 79 | onCallback_l(); |
| 80 | }); |
| 81 | EXPECT_EQ(true, waitForCallback(kConnectCallbacktimeoutNs)); |
| 82 | mCallbackCalled = false; |
| 83 | |
| 84 | if (connectResult == Result::INVALID_ARGUMENTS) { |
| 85 | skipped = true; |
| 86 | return; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 87 | } |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 88 | ASSERT_EQ(connectResult, Result::OK); |
| 89 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 90 | mTunerCallback = new MyCallback(this); |
| 91 | ASSERT_NE(nullptr, mRadio.get()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 92 | ASSERT_NE(nullptr, mTunerCallback.get()); |
| 93 | } |
| 94 | |
| 95 | virtual void TearDown() override { |
| 96 | mTuner.clear(); |
| 97 | mRadio.clear(); |
| 98 | } |
| 99 | |
| 100 | class MyCallback : public ITunerCallback { |
| 101 | public: |
| 102 | |
| 103 | // ITunerCallback methods (see doc in ITunerCallback.hal) |
| 104 | virtual Return<void> hardwareFailure() { |
| 105 | ALOGI("%s", __FUNCTION__); |
| 106 | mParentTest->onHwFailureCallback(); |
| 107 | return Void(); |
| 108 | } |
| 109 | |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 110 | virtual Return<void> configChange(Result result, const BandConfig& config) { |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 111 | ALOGI("%s result %d", __FUNCTION__, result); |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 112 | mParentTest->onConfigChangeCallback(result, config); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 113 | return Void(); |
| 114 | } |
| 115 | |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 116 | virtual Return<void> tuneComplete(Result result, const ProgramInfo& info) { |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 117 | ALOGI("%s result %d", __FUNCTION__, result); |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 118 | mParentTest->onTuneCompleteCallback(result, info); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 119 | return Void(); |
| 120 | } |
| 121 | |
| 122 | virtual Return<void> afSwitch(const ProgramInfo& info __unused) { |
| 123 | return Void(); |
| 124 | } |
| 125 | |
| 126 | virtual Return<void> antennaStateChange(bool connected) { |
| 127 | ALOGI("%s connected %d", __FUNCTION__, connected); |
| 128 | return Void(); |
| 129 | } |
| 130 | |
| 131 | virtual Return<void> trafficAnnouncement(bool active) { |
| 132 | ALOGI("%s active %d", __FUNCTION__, active); |
| 133 | return Void(); |
| 134 | } |
| 135 | |
| 136 | virtual Return<void> emergencyAnnouncement(bool active) { |
| 137 | ALOGI("%s active %d", __FUNCTION__, active); |
| 138 | return Void(); |
| 139 | } |
| 140 | |
| 141 | virtual Return<void> newMetadata(uint32_t channel __unused, uint32_t subChannel __unused, |
| 142 | const ::android::hardware::hidl_vec<MetaData>& metadata __unused) { |
| 143 | ALOGI("%s", __FUNCTION__); |
| 144 | return Void(); |
| 145 | } |
| 146 | |
| 147 | MyCallback(BroadcastRadioHidlTest *parentTest) : mParentTest(parentTest) {} |
| 148 | |
| 149 | private: |
| 150 | // BroadcastRadioHidlTest instance to which callbacks will be notified. |
| 151 | BroadcastRadioHidlTest *mParentTest; |
| 152 | }; |
| 153 | |
| 154 | |
| 155 | /** |
| 156 | * Method called by MyCallback when a callback with no status or boolean value is received |
| 157 | */ |
| 158 | void onCallback() { |
| 159 | Mutex::Autolock _l(mLock); |
| 160 | onCallback_l(); |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * Method called by MyCallback when hardwareFailure() callback is received |
| 165 | */ |
| 166 | void onHwFailureCallback() { |
| 167 | Mutex::Autolock _l(mLock); |
| 168 | mHwFailure = true; |
| 169 | onCallback_l(); |
| 170 | } |
| 171 | |
| 172 | /** |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 173 | * Method called by MyCallback when configChange() callback is received. |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 174 | */ |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 175 | void onConfigChangeCallback(Result result, const BandConfig& config) { |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 176 | Mutex::Autolock _l(mLock); |
| 177 | mResultCallbackData = result; |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 178 | mBandConfigCallbackData = config; |
| 179 | onCallback_l(); |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * Method called by MyCallback when tuneComplete() callback is received. |
| 184 | */ |
| 185 | void onTuneCompleteCallback(Result result, const ProgramInfo& info) { |
| 186 | Mutex::Autolock _l(mLock); |
| 187 | mResultCallbackData = result; |
| 188 | mProgramInfoCallbackData = info; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 189 | onCallback_l(); |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * Method called by MyCallback when a boolean indication is received |
| 194 | */ |
| 195 | void onBoolCallback(bool result) { |
| 196 | Mutex::Autolock _l(mLock); |
| 197 | mBoolCallbackData = result; |
| 198 | onCallback_l(); |
| 199 | } |
| 200 | |
| 201 | |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 202 | BroadcastRadioHidlTest() |
| 203 | : mCallbackCalled(false), mBoolCallbackData(false), mResultCallbackData(Result::OK), |
| 204 | mHwFailure(false) {} |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 205 | |
| 206 | void onCallback_l() { |
| 207 | if (!mCallbackCalled) { |
| 208 | mCallbackCalled = true; |
| 209 | mCallbackCond.broadcast(); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | |
| 214 | bool waitForCallback(nsecs_t reltime = 0) { |
| 215 | Mutex::Autolock _l(mLock); |
| 216 | nsecs_t endTime = systemTime() + reltime; |
| 217 | while (!mCallbackCalled) { |
| 218 | if (reltime == 0) { |
| 219 | mCallbackCond.wait(mLock); |
| 220 | } else { |
| 221 | nsecs_t now = systemTime(); |
| 222 | if (now > endTime) { |
| 223 | return false; |
| 224 | } |
| 225 | mCallbackCond.waitRelative(mLock, endTime - now); |
| 226 | } |
| 227 | } |
| 228 | return true; |
| 229 | } |
| 230 | |
| 231 | bool getProperties(); |
| 232 | bool openTuner(); |
| 233 | bool checkAntenna(); |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 234 | |
| 235 | /** |
| 236 | * Retrieves AM/FM band configuration from module properties. |
| 237 | * |
| 238 | * The configuration may not exist: if radio type is other than AM/FM |
| 239 | * or provided index is out of bounds. |
| 240 | * In such case, empty configuration is returned. |
| 241 | * |
| 242 | * @param idx Band index to retrieve. |
| 243 | * @return Band configuration reference. |
| 244 | */ |
| 245 | const BandConfig& getBand(unsigned idx); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 246 | |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 247 | static const nsecs_t kConnectCallbacktimeoutNs = seconds_to_nanoseconds(1); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 248 | static const nsecs_t kConfigCallbacktimeoutNs = seconds_to_nanoseconds(10); |
| 249 | static const nsecs_t kTuneCallbacktimeoutNs = seconds_to_nanoseconds(30); |
| 250 | |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 251 | Class radioClass; |
| 252 | bool skipped; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 253 | sp<IBroadcastRadio> mRadio; |
| 254 | Properties mHalProperties; |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 255 | bool mHalPropertiesInitialized = false; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 256 | sp<ITuner> mTuner; |
| 257 | sp<MyCallback> mTunerCallback; |
| 258 | Mutex mLock; |
| 259 | Condition mCallbackCond; |
| 260 | bool mCallbackCalled; |
| 261 | bool mBoolCallbackData; |
| 262 | Result mResultCallbackData; |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 263 | ProgramInfo mProgramInfoCallbackData; |
| 264 | BandConfig mBandConfigCallbackData; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 265 | bool mHwFailure; |
| 266 | }; |
| 267 | |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 268 | namespace android { |
| 269 | namespace hardware { |
| 270 | namespace broadcastradio { |
| 271 | namespace V1_0 { |
| 272 | |
| 273 | /** |
| 274 | * Compares two BandConfig objects for testing purposes. |
| 275 | */ |
| 276 | static bool operator==(const BandConfig& l, const BandConfig& r) { |
| 277 | if (l.type != r.type) return false; |
| 278 | if (l.antennaConnected != r.antennaConnected) return false; |
| 279 | if (l.lowerLimit != r.lowerLimit) return false; |
| 280 | if (l.upperLimit != r.upperLimit) return false; |
| 281 | if (l.spacings != r.spacings) return false; |
| 282 | if (l.type == Band::AM || l.type == Band::AM_HD) { |
| 283 | return l.ext.am == r.ext.am; |
| 284 | } else if (l.type == Band::FM || l.type == Band::FM_HD) { |
| 285 | return l.ext.fm == r.ext.fm; |
| 286 | } else { |
| 287 | // unsupported type |
| 288 | return false; |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | } // V1_0 |
| 293 | } // broadcastradio |
| 294 | } // hardware |
| 295 | } // android |
| 296 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 297 | bool BroadcastRadioHidlTest::getProperties() |
| 298 | { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 299 | if (mHalPropertiesInitialized) return true; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 300 | |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 301 | Result halResult = Result::NOT_INITIALIZED; |
| 302 | auto hidlReturn = mRadio->getProperties([&](Result result, const Properties& properties) { |
| 303 | halResult = result; |
| 304 | if (result == Result::OK) { |
| 305 | mHalProperties = properties; |
| 306 | } |
| 307 | }); |
| 308 | |
| 309 | EXPECT_TRUE(hidlReturn.isOk()); |
| 310 | EXPECT_EQ(Result::OK, halResult); |
| 311 | EXPECT_EQ(radioClass, mHalProperties.classId); |
| 312 | EXPECT_GT(mHalProperties.numTuners, 0u); |
| 313 | if (radioClass == Class::AM_FM) { |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 314 | EXPECT_GT(mHalProperties.bands.size(), 0u); |
| 315 | } |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 316 | |
| 317 | if (hidlReturn.isOk() && halResult == Result::OK) { |
| 318 | mHalPropertiesInitialized = true; |
| 319 | return true; |
| 320 | } |
| 321 | return false; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | bool BroadcastRadioHidlTest::openTuner() |
| 325 | { |
| 326 | if (!getProperties()) { |
| 327 | return false; |
| 328 | } |
| 329 | if (mTuner.get() == nullptr) { |
| 330 | Result halResult = Result::NOT_INITIALIZED; |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 331 | auto openCb = [&](Result result, const sp<ITuner>& tuner) { |
| 332 | halResult = result; |
| 333 | if (result == Result::OK) { |
| 334 | mTuner = tuner; |
| 335 | } |
| 336 | }; |
| 337 | auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 338 | EXPECT_TRUE(hidlReturn.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 339 | EXPECT_EQ(Result::OK, halResult); |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 340 | if (radioClass == Class::AM_FM) { |
| 341 | EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs)); |
| 342 | } |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 343 | } |
| 344 | EXPECT_NE(nullptr, mTuner.get()); |
| 345 | return nullptr != mTuner.get(); |
| 346 | } |
| 347 | |
| 348 | bool BroadcastRadioHidlTest::checkAntenna() |
| 349 | { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 350 | if (radioClass != Class::AM_FM) return true; |
| 351 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 352 | BandConfig halConfig; |
| 353 | Result halResult = Result::NOT_INITIALIZED; |
| 354 | Return<void> hidlReturn = |
| 355 | mTuner->getConfiguration([&](Result result, const BandConfig& config) { |
| 356 | halResult = result; |
| 357 | if (result == Result::OK) { |
| 358 | halConfig = config; |
| 359 | } |
| 360 | }); |
| 361 | |
| 362 | return ((halResult == Result::OK) && (halConfig.antennaConnected == true)); |
| 363 | } |
| 364 | |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 365 | const BandConfig& BroadcastRadioHidlTest::getBand(unsigned idx) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 366 | static BandConfig dummyBandConfig = {}; |
| 367 | if (radioClass == Class::AM_FM) { |
| 368 | EXPECT_GT(mHalProperties.bands.size(), idx); |
| 369 | if (mHalProperties.bands.size() > idx) { |
| 370 | return mHalProperties.bands[idx]; |
| 371 | } else { |
| 372 | return dummyBandConfig; |
| 373 | } |
| 374 | } else { |
| 375 | return dummyBandConfig; |
| 376 | } |
| 377 | } |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 378 | |
| 379 | /** |
| 380 | * Test IBroadcastRadio::getProperties() method |
| 381 | * |
| 382 | * Verifies that: |
| 383 | * - the HAL implements the method |
| 384 | * - the method returns 0 (no error) |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 385 | * - the implementation class is radioClass |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 386 | * - the implementation supports at least one tuner |
| 387 | * - the implementation supports at one band |
| 388 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 389 | TEST_P(BroadcastRadioHidlTest, GetProperties) { |
| 390 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 391 | EXPECT_EQ(true, getProperties()); |
| 392 | } |
| 393 | |
| 394 | /** |
| 395 | * Test IBroadcastRadio::openTuner() method |
| 396 | * |
| 397 | * Verifies that: |
| 398 | * - the HAL implements the method |
| 399 | * - the method returns 0 (no error) and a valid ITuner interface |
| 400 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 401 | TEST_P(BroadcastRadioHidlTest, OpenTuner) { |
| 402 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 403 | EXPECT_EQ(true, openTuner()); |
| 404 | } |
| 405 | |
| 406 | /** |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 407 | * Test IBroadcastRadio::openTuner() after ITuner disposal. |
| 408 | * |
| 409 | * Verifies that: |
| 410 | * - ITuner destruction gets propagated through HAL |
| 411 | * - the openTuner method works well when called for the second time |
| 412 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 413 | TEST_P(BroadcastRadioHidlTest, ReopenTuner) { |
| 414 | RETURN_IF_SKIPPED; |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 415 | EXPECT_TRUE(openTuner()); |
| 416 | mTuner.clear(); |
| 417 | EXPECT_TRUE(openTuner()); |
| 418 | } |
| 419 | |
| 420 | /** |
| 421 | * Test IBroadcastRadio::openTuner() method called twice. |
| 422 | * |
| 423 | * Verifies that: |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 424 | * - the openTuner method fails with INVALID_STATE or succeeds when called for the second time |
| 425 | * without deleting previous ITuner instance |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 426 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 427 | TEST_P(BroadcastRadioHidlTest, OpenTunerTwice) { |
| 428 | RETURN_IF_SKIPPED; |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 429 | EXPECT_TRUE(openTuner()); |
| 430 | |
| 431 | Result halResult = Result::NOT_INITIALIZED; |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 432 | auto openCb = [&](Result result, const sp<ITuner>&) { halResult = result; }; |
| 433 | auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb); |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 434 | EXPECT_TRUE(hidlReturn.isOk()); |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 435 | if (halResult == Result::OK) { |
| 436 | if (radioClass == Class::AM_FM) { |
| 437 | EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs)); |
| 438 | } |
| 439 | } else { |
| 440 | EXPECT_EQ(Result::INVALID_STATE, halResult); |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 441 | } |
Tomasz Wasilczyk | be71e9c | 2016-12-22 11:49:17 -0800 | [diff] [blame] | 442 | } |
| 443 | |
| 444 | /** |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 445 | * Test ITuner::setConfiguration() and getConfiguration methods |
| 446 | * |
| 447 | * Verifies that: |
| 448 | * - the HAL implements both methods |
| 449 | * - the methods return 0 (no error) |
| 450 | * - the configuration callback is received within kConfigCallbacktimeoutNs ns |
| 451 | * - the configuration read back from HAl has the same class Id |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 452 | * |
| 453 | * Skipped for other radio classes than AM/FM, because setConfiguration |
| 454 | * applies only for these bands. |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 455 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 456 | TEST_P(BroadcastRadioHidlTest, SetAndGetConfiguration) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 457 | if (radioClass != Class::AM_FM) skipped = true; |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 458 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 459 | ASSERT_EQ(true, openTuner()); |
| 460 | // test setConfiguration |
| 461 | mCallbackCalled = false; |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 462 | Return<Result> hidlResult = mTuner->setConfiguration(getBand(1)); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 463 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 464 | EXPECT_EQ(Result::OK, hidlResult); |
| 465 | EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs)); |
| 466 | EXPECT_EQ(Result::OK, mResultCallbackData); |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 467 | EXPECT_EQ(getBand(1), mBandConfigCallbackData); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 468 | |
| 469 | // test getConfiguration |
| 470 | BandConfig halConfig; |
| 471 | Result halResult; |
| 472 | Return<void> hidlReturn = |
| 473 | mTuner->getConfiguration([&](Result result, const BandConfig& config) { |
| 474 | halResult = result; |
| 475 | if (result == Result::OK) { |
| 476 | halConfig = config; |
| 477 | } |
| 478 | }); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 479 | EXPECT_TRUE(hidlReturn.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 480 | EXPECT_EQ(Result::OK, halResult); |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 481 | EXPECT_EQ(getBand(1), halConfig); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 482 | } |
| 483 | |
| 484 | /** |
Tomasz Wasilczyk | 10877cd | 2017-03-07 17:04:26 -0800 | [diff] [blame] | 485 | * Test ITuner::setConfiguration() with invalid arguments. |
| 486 | * |
| 487 | * Verifies that: |
| 488 | * - the methods returns INVALID_ARGUMENTS on invalid arguments |
| 489 | * - the method recovers and succeeds after passing correct arguments |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 490 | * |
| 491 | * Skipped for other radio classes than AM/FM, because setConfiguration |
| 492 | * applies only for these bands. |
Tomasz Wasilczyk | 10877cd | 2017-03-07 17:04:26 -0800 | [diff] [blame] | 493 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 494 | TEST_P(BroadcastRadioHidlTest, SetConfigurationFails) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 495 | if (radioClass != Class::AM_FM) skipped = true; |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 496 | RETURN_IF_SKIPPED; |
Tomasz Wasilczyk | 10877cd | 2017-03-07 17:04:26 -0800 | [diff] [blame] | 497 | ASSERT_EQ(true, openTuner()); |
| 498 | |
| 499 | // Let's define a config that's bad for sure. |
| 500 | BandConfig badConfig = {}; |
| 501 | badConfig.type = Band::FM; |
| 502 | badConfig.lowerLimit = 0xFFFFFFFF; |
| 503 | badConfig.upperLimit = 0; |
| 504 | badConfig.spacings = (std::vector<uint32_t>){ 0 }; |
| 505 | |
| 506 | // Test setConfiguration failing on bad data. |
| 507 | mCallbackCalled = false; |
| 508 | auto setResult = mTuner->setConfiguration(badConfig); |
| 509 | EXPECT_TRUE(setResult.isOk()); |
| 510 | EXPECT_EQ(Result::INVALID_ARGUMENTS, setResult); |
| 511 | |
| 512 | // Test setConfiguration recovering after passing good data. |
| 513 | mCallbackCalled = false; |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 514 | setResult = mTuner->setConfiguration(getBand(0)); |
Tomasz Wasilczyk | 10877cd | 2017-03-07 17:04:26 -0800 | [diff] [blame] | 515 | EXPECT_TRUE(setResult.isOk()); |
| 516 | EXPECT_EQ(Result::OK, setResult); |
| 517 | EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs)); |
| 518 | EXPECT_EQ(Result::OK, mResultCallbackData); |
| 519 | } |
| 520 | |
| 521 | /** |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 522 | * Test ITuner::scan |
| 523 | * |
| 524 | * Verifies that: |
| 525 | * - the HAL implements the method |
| 526 | * - the method returns 0 (no error) |
| 527 | * - the tuned callback is received within kTuneCallbacktimeoutNs ns |
Tomasz Wasilczyk | a8dec0f | 2017-03-14 10:20:53 -0700 | [diff] [blame] | 528 | * - skipping sub-channel or not does not fail the call |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 529 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 530 | TEST_P(BroadcastRadioHidlTest, Scan) { |
| 531 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 532 | ASSERT_EQ(true, openTuner()); |
| 533 | ASSERT_TRUE(checkAntenna()); |
| 534 | // test scan UP |
| 535 | mCallbackCalled = false; |
| 536 | Return<Result> hidlResult = mTuner->scan(Direction::UP, true); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 537 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 538 | EXPECT_EQ(Result::OK, hidlResult); |
| 539 | EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
| 540 | |
| 541 | // test scan DOWN |
| 542 | mCallbackCalled = false; |
Tomasz Wasilczyk | a8dec0f | 2017-03-14 10:20:53 -0700 | [diff] [blame] | 543 | hidlResult = mTuner->scan(Direction::DOWN, false); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 544 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 545 | EXPECT_EQ(Result::OK, hidlResult); |
| 546 | EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
| 547 | } |
| 548 | |
| 549 | /** |
| 550 | * Test ITuner::step |
| 551 | * |
| 552 | * Verifies that: |
| 553 | * - the HAL implements the method |
| 554 | * - the method returns 0 (no error) |
| 555 | * - the tuned callback is received within kTuneCallbacktimeoutNs ns |
Tomasz Wasilczyk | a8dec0f | 2017-03-14 10:20:53 -0700 | [diff] [blame] | 556 | * - skipping sub-channel or not does not fail the call |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 557 | * |
| 558 | * Skipped for other radio classes than AM/FM, because step is not possible |
| 559 | * on DAB nor satellite. |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 560 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 561 | TEST_P(BroadcastRadioHidlTest, Step) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 562 | if (radioClass != Class::AM_FM) skipped = true; |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 563 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 564 | ASSERT_EQ(true, openTuner()); |
| 565 | ASSERT_TRUE(checkAntenna()); |
| 566 | // test step UP |
| 567 | mCallbackCalled = false; |
Tomasz Wasilczyk | a8dec0f | 2017-03-14 10:20:53 -0700 | [diff] [blame] | 568 | Return<Result> hidlResult = mTuner->step(Direction::UP, false); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 569 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 570 | EXPECT_EQ(Result::OK, hidlResult); |
| 571 | EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
| 572 | |
| 573 | // test step DOWN |
| 574 | mCallbackCalled = false; |
| 575 | hidlResult = mTuner->step(Direction::DOWN, true); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 576 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 577 | EXPECT_EQ(Result::OK, hidlResult); |
| 578 | EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
| 579 | } |
| 580 | |
| 581 | /** |
| 582 | * Test ITuner::tune, getProgramInformation and cancel methods |
| 583 | * |
| 584 | * Verifies that: |
| 585 | * - the HAL implements the methods |
| 586 | * - the methods return 0 (no error) |
| 587 | * - the tuned callback is received within kTuneCallbacktimeoutNs ns after tune() |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 588 | * |
| 589 | * Skipped for other radio classes than AM/FM, because tune to frequency |
| 590 | * is not possible on DAB nor satellite. |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 591 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 592 | TEST_P(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 593 | if (radioClass != Class::AM_FM) skipped = true; |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 594 | RETURN_IF_SKIPPED; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 595 | ASSERT_EQ(true, openTuner()); |
| 596 | ASSERT_TRUE(checkAntenna()); |
| 597 | |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 598 | auto& band = getBand(0); |
| 599 | |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 600 | // test tune |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 601 | ASSERT_GT(band.spacings.size(), 0u); |
| 602 | ASSERT_GT(band.upperLimit, band.lowerLimit); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 603 | |
| 604 | // test scan UP |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 605 | uint32_t lowerLimit = band.lowerLimit; |
| 606 | uint32_t upperLimit = band.upperLimit; |
| 607 | uint32_t spacing = band.spacings[0]; |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 608 | |
| 609 | uint32_t channel = |
| 610 | lowerLimit + (((upperLimit - lowerLimit) / 2 + spacing - 1) / spacing) * spacing; |
| 611 | mCallbackCalled = false; |
| 612 | mResultCallbackData = Result::NOT_INITIALIZED; |
| 613 | Return<Result> hidlResult = mTuner->tune(channel, 0); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 614 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 615 | EXPECT_EQ(Result::OK, hidlResult); |
| 616 | EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
Tomasz Wasilczyk | f3c036d | 2017-03-03 15:07:50 -0800 | [diff] [blame] | 617 | EXPECT_EQ(channel, mProgramInfoCallbackData.channel); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 618 | |
| 619 | // test getProgramInformation |
| 620 | ProgramInfo halInfo; |
| 621 | Result halResult = Result::NOT_INITIALIZED; |
| 622 | Return<void> hidlReturn = mTuner->getProgramInformation( |
Tomasz Wasilczyk | 5cc9d86 | 2017-01-06 14:19:11 -0800 | [diff] [blame] | 623 | [&](Result result, const ProgramInfo& info) { |
| 624 | halResult = result; |
| 625 | if (result == Result::OK) { |
| 626 | halInfo = info; |
| 627 | } |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 628 | }); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 629 | EXPECT_TRUE(hidlReturn.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 630 | EXPECT_EQ(Result::OK, halResult); |
| 631 | if (mResultCallbackData == Result::OK) { |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 632 | EXPECT_LE(halInfo.channel, upperLimit); |
| 633 | EXPECT_GE(halInfo.channel, lowerLimit); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 634 | } |
| 635 | |
| 636 | // test cancel |
| 637 | mTuner->tune(lowerLimit, 0); |
| 638 | hidlResult = mTuner->cancel(); |
Steven Moreland | b643842 | 2017-01-03 17:06:57 -0800 | [diff] [blame] | 639 | EXPECT_TRUE(hidlResult.isOk()); |
Eric Laurent | 566fcda | 2016-11-23 10:36:36 -0800 | [diff] [blame] | 640 | EXPECT_EQ(Result::OK, hidlResult); |
| 641 | } |
| 642 | |
Tomasz Wasilczyk | 59d985d | 2017-03-03 13:02:15 -0800 | [diff] [blame] | 643 | /** |
| 644 | * Test ITuner::tune failing when channel out of the range is provided. |
| 645 | * |
| 646 | * Verifies that: |
| 647 | * - the method returns INVALID_ARGUMENTS when applicable |
| 648 | * - the method recovers and succeeds after passing correct arguments |
Tomasz Wasilczyk | 394b343 | 2017-08-07 18:00:28 -0700 | [diff] [blame] | 649 | * |
| 650 | * Skipped for other radio classes than AM/FM, because tune to frequency |
| 651 | * is not possible on DAB nor satellite. |
Tomasz Wasilczyk | 59d985d | 2017-03-03 13:02:15 -0800 | [diff] [blame] | 652 | */ |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 653 | TEST_P(BroadcastRadioHidlTest, TuneFailsOutOfBounds) { |
Tomasz Wasilczyk | da72d37 | 2017-06-26 16:08:51 -0700 | [diff] [blame] | 654 | if (radioClass != Class::AM_FM) skipped = true; |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 655 | RETURN_IF_SKIPPED; |
Tomasz Wasilczyk | 59d985d | 2017-03-03 13:02:15 -0800 | [diff] [blame] | 656 | ASSERT_TRUE(openTuner()); |
| 657 | ASSERT_TRUE(checkAntenna()); |
| 658 | |
| 659 | // get current channel bounds |
| 660 | BandConfig halConfig; |
| 661 | Result halResult; |
| 662 | auto configResult = mTuner->getConfiguration([&](Result result, const BandConfig& config) { |
| 663 | halResult = result; |
| 664 | halConfig = config; |
| 665 | }); |
| 666 | ASSERT_TRUE(configResult.isOk()); |
| 667 | ASSERT_EQ(Result::OK, halResult); |
| 668 | |
| 669 | // try to tune slightly above the limit and expect to fail |
| 670 | auto badChannel = halConfig.upperLimit + halConfig.spacings[0]; |
| 671 | auto tuneResult = mTuner->tune(badChannel, 0); |
| 672 | EXPECT_TRUE(tuneResult.isOk()); |
| 673 | EXPECT_EQ(Result::INVALID_ARGUMENTS, tuneResult); |
| 674 | EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs)); |
| 675 | |
| 676 | // tuning exactly at the limit should succeed |
| 677 | auto goodChannel = halConfig.upperLimit; |
| 678 | tuneResult = mTuner->tune(goodChannel, 0); |
| 679 | EXPECT_TRUE(tuneResult.isOk()); |
| 680 | EXPECT_EQ(Result::OK, tuneResult); |
| 681 | EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs)); |
| 682 | } |
| 683 | |
Tomasz Wasilczyk | ba3e254 | 2017-07-17 13:59:21 -0700 | [diff] [blame] | 684 | /** |
| 685 | * Test proper image format in metadata. |
| 686 | * |
| 687 | * Verifies that: |
| 688 | * - all images in metadata are provided in-band (as a binary blob, not by id) |
| 689 | * |
| 690 | * This is a counter-test for OobImagesOnly from 1.1 VTS. |
| 691 | */ |
| 692 | TEST_P(BroadcastRadioHidlTest, IbImagesOnly) { |
| 693 | RETURN_IF_SKIPPED; |
| 694 | ASSERT_TRUE(openTuner()); |
| 695 | ASSERT_TRUE(checkAntenna()); |
| 696 | |
| 697 | bool firstScan = true; |
| 698 | uint32_t firstChannel, prevChannel; |
| 699 | while (true) { |
| 700 | mCallbackCalled = false; |
| 701 | auto hidlResult = mTuner->scan(Direction::UP, true); |
| 702 | ASSERT_TRUE(hidlResult.isOk()); |
| 703 | if (hidlResult == Result::TIMEOUT) { |
| 704 | ALOGI("Got timeout on scan operation"); |
| 705 | break; |
| 706 | } |
| 707 | ASSERT_EQ(Result::OK, hidlResult); |
| 708 | ASSERT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs)); |
| 709 | |
| 710 | if (firstScan) { |
| 711 | firstScan = false; |
| 712 | firstChannel = mProgramInfoCallbackData.channel; |
| 713 | } else { |
| 714 | // scanned the whole band |
| 715 | if (mProgramInfoCallbackData.channel >= firstChannel && prevChannel <= firstChannel) { |
| 716 | break; |
| 717 | } |
| 718 | } |
| 719 | prevChannel = mProgramInfoCallbackData.channel; |
| 720 | |
| 721 | for (auto&& entry : mProgramInfoCallbackData.metadata) { |
| 722 | if (entry.key != MetadataKey::ICON && entry.key != MetadataKey::ART) continue; |
| 723 | EXPECT_EQ(MetadataType::RAW, entry.type); |
| 724 | EXPECT_EQ(0, entry.intValue); |
| 725 | EXPECT_GT(entry.rawValue.size(), 0u); |
| 726 | } |
| 727 | } |
| 728 | } |
| 729 | |
Dan Shi | ac9cf44 | 2020-09-08 10:42:38 -0700 | [diff] [blame] | 730 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BroadcastRadioHidlTest); |
Tomasz Wasilczyk | 2f46101 | 2017-03-14 11:19:15 -0700 | [diff] [blame] | 731 | INSTANTIATE_TEST_CASE_P( |
Dan Shi | 170a445 | 2020-04-04 00:59:41 -0700 | [diff] [blame] | 732 | PerInstance, BroadcastRadioHidlTest, |
| 733 | testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( |
| 734 | IBroadcastRadioFactory::descriptor)), |
| 735 | ::testing::Values("AM_FM", "SAT", "DT")), |
V,Anilkumar | 86f31e7 | 2022-07-05 23:39:38 +0530 | [diff] [blame^] | 736 | android::hardware::PrintInstanceTupleNameToString<>); |