1566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/*
2566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Copyright (C) 2016 The Android Open Source Project
3566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
4566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * you may not use this file except in compliance with the License.
6566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * You may obtain a copy of the License at
7566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
8566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
10566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Unless required by applicable law or agreed to in writing, software
11566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * See the License for the specific language governing permissions and
14566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * limitations under the License.
15566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
16566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
17566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#define LOG_TAG "BroadcastRadioHidlHalTest"
18ed2bb4e8f851688c09f7639a9183b1285aa0967cYuexi Ma#include <VtsHalHidlTargetTestBase.h>
19566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <android-base/logging.h>
20566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <cutils/native_handle.h>
21566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <cutils/properties.h>
22028223775be7539c5b569a454524584a7ad8e152Martijn Coenen#include <hidl/HidlTransportSupport.h>
23566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <utils/threads.h>
24566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
25566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
26190548f558f3156356f6244c70733025da95598fZhuoyao Zhang#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
27566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <android/hardware/broadcastradio/1.0/ITuner.h>
28566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <android/hardware/broadcastradio/1.0/ITunerCallback.h>
29566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent#include <android/hardware/broadcastradio/1.0/types.h>
30190548f558f3156356f6244c70733025da95598fZhuoyao Zhang#include <broadcastradio-vts-utils/environment-utils.h>
31566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
32566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::sp;
33566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::Mutex;
34566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::Condition;
35566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::Return;
36566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::Void;
37566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
38566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::IBroadcastRadio;
39566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::ITuner;
40566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::ITunerCallback;
41566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::Result;
42566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::Class;
43566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::Properties;
44f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczykusing ::android::hardware::broadcastradio::V1_0::Band;
45566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::BandConfig;
46566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::Direction;
47566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::ProgramInfo;
48566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentusing ::android::hardware::broadcastradio::V1_0::MetaData;
49ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczykusing ::android::hardware::broadcastradio::V1_0::MetadataKey;
50ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczykusing ::android::hardware::broadcastradio::V1_0::MetadataType;
51190548f558f3156356f6244c70733025da95598fZhuoyao Zhangusing ::android::hardware::broadcastradio::vts::BroadcastRadioHidlEnvironment;
52566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
532f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk#define RETURN_IF_SKIPPED \
542f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    if (skipped) { \
552f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        std::cout << "[  SKIPPED ] This device class is not supported. " << std::endl; \
562f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        return; \
572f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    }
582f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
59190548f558f3156356f6244c70733025da95598fZhuoyao Zhangstatic BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>* gEnv = nullptr;
60213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk// The main test class for Broadcast Radio HIDL HAL.
612f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczykclass BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase,
622f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        public ::testing::WithParamInterface<Class> {
63566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent protected:
64566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    virtual void SetUp() override {
652f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        ASSERT_EQ(nullptr, mRadio.get());
662f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
672f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        radioClass = GetParam();
682f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        skipped = false;
692f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
70566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        sp<IBroadcastRadioFactory> factory =
71190548f558f3156356f6244c70733025da95598fZhuoyao Zhang            getService<IBroadcastRadioFactory>(gEnv->getServiceName<IBroadcastRadioFactory>());
722f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        ASSERT_NE(nullptr, factory.get());
732f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
742f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        Result connectResult;
752f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        factory->connectModule(radioClass, [&](Result ret, const sp<IBroadcastRadio>& radio) {
762f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk            connectResult = ret;
772f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk            mRadio = radio;
782f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk            onCallback_l();
792f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        });
802f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        EXPECT_EQ(true, waitForCallback(kConnectCallbacktimeoutNs));
812f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        mCallbackCalled = false;
822f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
832f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        if (connectResult == Result::INVALID_ARGUMENTS) {
842f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk            skipped = true;
852f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk            return;
86566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
872f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        ASSERT_EQ(connectResult, Result::OK);
882f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk
89566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mTunerCallback = new MyCallback(this);
90566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        ASSERT_NE(nullptr, mRadio.get());
91566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        ASSERT_NE(nullptr, mTunerCallback.get());
92566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
93566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
94566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    virtual void TearDown() override {
95566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mTuner.clear();
96566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mRadio.clear();
97566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
98566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
99566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    class MyCallback : public ITunerCallback {
100566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     public:
101566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
102566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        // ITunerCallback methods (see doc in ITunerCallback.hal)
103566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> hardwareFailure() {
104566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s", __FUNCTION__);
105566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            mParentTest->onHwFailureCallback();
106566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
107566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
108566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
109f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        virtual Return<void> configChange(Result result, const BandConfig& config) {
110566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s result %d", __FUNCTION__, result);
111f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk            mParentTest->onConfigChangeCallback(result, config);
112566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
113566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
114566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
115f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        virtual Return<void> tuneComplete(Result result, const ProgramInfo& info) {
116566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s result %d", __FUNCTION__, result);
117f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk            mParentTest->onTuneCompleteCallback(result, info);
118566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
119566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
120566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
121566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> afSwitch(const ProgramInfo& info __unused) {
122566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
123566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
124566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
125566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> antennaStateChange(bool connected) {
126566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s connected %d", __FUNCTION__, connected);
127566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
128566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
129566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
130566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> trafficAnnouncement(bool active) {
131566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s active %d", __FUNCTION__, active);
132566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
133566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
134566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
135566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> emergencyAnnouncement(bool active) {
136566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s active %d", __FUNCTION__, active);
137566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
138566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
139566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
140566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        virtual Return<void> newMetadata(uint32_t channel __unused, uint32_t subChannel __unused,
141566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                           const ::android::hardware::hidl_vec<MetaData>& metadata __unused) {
142566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            ALOGI("%s", __FUNCTION__);
143566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            return Void();
144566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
145566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
146566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                MyCallback(BroadcastRadioHidlTest *parentTest) : mParentTest(parentTest) {}
147566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
148566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     private:
149566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        // BroadcastRadioHidlTest instance to which callbacks will be notified.
150566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        BroadcastRadioHidlTest *mParentTest;
151566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    };
152566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
153566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
154566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    /**
155566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     * Method called by MyCallback when a callback with no status or boolean value is received
156566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     */
157566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    void onCallback() {
158566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Mutex::Autolock _l(mLock);
159566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        onCallback_l();
160566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
161566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
162566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    /**
163566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     * Method called by MyCallback when hardwareFailure() callback is received
164566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     */
165566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    void onHwFailureCallback() {
166566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Mutex::Autolock _l(mLock);
167566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mHwFailure = true;
168566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        onCallback_l();
169566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
170566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
171566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    /**
172f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk     * Method called by MyCallback when configChange() callback is received.
173566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     */
174f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    void onConfigChangeCallback(Result result, const BandConfig& config) {
175566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Mutex::Autolock _l(mLock);
176566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mResultCallbackData = result;
177f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        mBandConfigCallbackData = config;
178f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        onCallback_l();
179f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    }
180f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk
181f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    /**
182f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk     * Method called by MyCallback when tuneComplete() callback is received.
183f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk     */
184f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    void onTuneCompleteCallback(Result result, const ProgramInfo& info) {
185f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        Mutex::Autolock _l(mLock);
186f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        mResultCallbackData = result;
187f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        mProgramInfoCallbackData = info;
188566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        onCallback_l();
189566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
190566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
191566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    /**
192566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     * Method called by MyCallback when a boolean indication is received
193566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent     */
194566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    void onBoolCallback(bool result) {
195566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Mutex::Autolock _l(mLock);
196566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        mBoolCallbackData = result;
197566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        onCallback_l();
198566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
199566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
200566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
2012f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    BroadcastRadioHidlTest()
2022f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        : mCallbackCalled(false), mBoolCallbackData(false), mResultCallbackData(Result::OK),
2032f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        mHwFailure(false) {}
204566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
205566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    void onCallback_l() {
206566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        if (!mCallbackCalled) {
207566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            mCallbackCalled = true;
208566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            mCallbackCond.broadcast();
209566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
210566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
211566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
212566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
213566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool waitForCallback(nsecs_t reltime = 0) {
214566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Mutex::Autolock _l(mLock);
215566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        nsecs_t endTime = systemTime() + reltime;
216566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        while (!mCallbackCalled) {
217566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            if (reltime == 0) {
218566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                mCallbackCond.wait(mLock);
219566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            } else {
220566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                nsecs_t now = systemTime();
221566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                if (now > endTime) {
222566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                    return false;
223566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                }
224566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                mCallbackCond.waitRelative(mLock, endTime - now);
225566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            }
226566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        }
227566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        return true;
228566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
229566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
230566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool getProperties();
231566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool openTuner();
232566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool checkAntenna();
233394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk
234394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk    /**
235394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * Retrieves AM/FM band configuration from module properties.
236394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     *
237394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * The configuration may not exist: if radio type is other than AM/FM
238394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * or provided index is out of bounds.
239394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * In such case, empty configuration is returned.
240394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     *
241394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * @param idx Band index to retrieve.
242394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     * @return Band configuration reference.
243394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk     */
244394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk    const BandConfig& getBand(unsigned idx);
245566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
2462f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    static const nsecs_t kConnectCallbacktimeoutNs = seconds_to_nanoseconds(1);
247566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    static const nsecs_t kConfigCallbacktimeoutNs = seconds_to_nanoseconds(10);
248566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    static const nsecs_t kTuneCallbacktimeoutNs = seconds_to_nanoseconds(30);
249566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
2502f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    Class radioClass;
2512f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    bool skipped;
252566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    sp<IBroadcastRadio> mRadio;
253566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Properties mHalProperties;
254da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    bool mHalPropertiesInitialized = false;
255566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    sp<ITuner> mTuner;
256566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    sp<MyCallback> mTunerCallback;
257566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Mutex mLock;
258566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Condition mCallbackCond;
259566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool mCallbackCalled;
260566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool mBoolCallbackData;
261566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Result mResultCallbackData;
262f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    ProgramInfo mProgramInfoCallbackData;
263f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    BandConfig mBandConfigCallbackData;
264566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    bool mHwFailure;
265566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent};
266566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
267f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyknamespace android {
268f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyknamespace hardware {
269f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyknamespace broadcastradio {
270f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyknamespace V1_0 {
271f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk
272f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk/**
273f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk * Compares two BandConfig objects for testing purposes.
274f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk */
275f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczykstatic bool operator==(const BandConfig& l, const BandConfig& r) {
276f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.type != r.type) return false;
277f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.antennaConnected != r.antennaConnected) return false;
278f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.lowerLimit != r.lowerLimit) return false;
279f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.upperLimit != r.upperLimit) return false;
280f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.spacings != r.spacings) return false;
281f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    if (l.type == Band::AM || l.type == Band::AM_HD) {
282f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        return l.ext.am == r.ext.am;
283f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    } else if (l.type == Band::FM || l.type == Band::FM_HD) {
284f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        return l.ext.fm == r.ext.fm;
285f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    } else {
286f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        // unsupported type
287f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk        return false;
288f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    }
289f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk}
290f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk
291f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk}  // V1_0
292f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk}  // broadcastradio
293f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk}  // hardware
294f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk}  // android
295f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk
296566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentbool BroadcastRadioHidlTest::getProperties()
297566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent{
298da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (mHalPropertiesInitialized) return true;
299566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
300da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    Result halResult = Result::NOT_INITIALIZED;
301da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    auto hidlReturn = mRadio->getProperties([&](Result result, const Properties& properties) {
302da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        halResult = result;
303da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        if (result == Result::OK) {
304da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            mHalProperties = properties;
305da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        }
306da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    });
307da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk
308da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_TRUE(hidlReturn.isOk());
309da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_EQ(Result::OK, halResult);
310da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_EQ(radioClass, mHalProperties.classId);
311da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_GT(mHalProperties.numTuners, 0u);
312da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass == Class::AM_FM) {
313566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        EXPECT_GT(mHalProperties.bands.size(), 0u);
314566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
315da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk
316da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (hidlReturn.isOk() && halResult == Result::OK) {
317da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        mHalPropertiesInitialized = true;
318da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        return true;
319da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    }
320da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    return false;
321566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
322566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
323566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentbool BroadcastRadioHidlTest::openTuner()
324566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent{
325566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    if (!getProperties()) {
326566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        return false;
327566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
328566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    if (mTuner.get() == nullptr) {
329566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        Result halResult = Result::NOT_INITIALIZED;
330da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        auto openCb = [&](Result result, const sp<ITuner>& tuner) {
331da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            halResult = result;
332da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            if (result == Result::OK) {
333da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk                mTuner = tuner;
334da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            }
335da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        };
336da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb);
337b6438421923590b765905efe151e26129dce4094Steven Moreland        EXPECT_TRUE(hidlReturn.isOk());
338566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        EXPECT_EQ(Result::OK, halResult);
339da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        if (radioClass == Class::AM_FM) {
340da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
341da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        }
342566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
343566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_NE(nullptr, mTuner.get());
344566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    return nullptr != mTuner.get();
345566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
346566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
347566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentbool BroadcastRadioHidlTest::checkAntenna()
348566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent{
349da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) return true;
350da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk
351566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    BandConfig halConfig;
352566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Result halResult = Result::NOT_INITIALIZED;
353566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Return<void> hidlReturn =
354566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            mTuner->getConfiguration([&](Result result, const BandConfig& config) {
355566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                halResult = result;
356566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                if (result == Result::OK) {
357566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                    halConfig = config;
358566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                }
359566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            });
360566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
361566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    return ((halResult == Result::OK) && (halConfig.antennaConnected == true));
362566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
363566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
364394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczykconst BandConfig& BroadcastRadioHidlTest::getBand(unsigned idx) {
365da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    static BandConfig dummyBandConfig = {};
366da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass == Class::AM_FM) {
367da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        EXPECT_GT(mHalProperties.bands.size(), idx);
368da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        if (mHalProperties.bands.size() > idx) {
369da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            return mHalProperties.bands[idx];
370da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        } else {
371da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk            return dummyBandConfig;
372da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        }
373da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    } else {
374da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk        return dummyBandConfig;
375da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    }
376da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk}
377566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
378566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
379566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test IBroadcastRadio::getProperties() method
380566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
381566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
382566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements the method
383566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the method returns 0 (no error)
384da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk *  - the implementation class is radioClass
385566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the implementation supports at least one tuner
386566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the implementation supports at one band
387566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
3882f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, GetProperties) {
3892f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
390566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, getProperties());
391566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
392566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
393566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
394566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test IBroadcastRadio::openTuner() method
395566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
396566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
397566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements the method
398566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the method returns 0 (no error) and a valid ITuner interface
399566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
4002f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, OpenTuner) {
4012f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
402566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, openTuner());
403566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
404566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
405566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
406be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk * Test IBroadcastRadio::openTuner() after ITuner disposal.
407be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk *
408be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk * Verifies that:
409be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk *  - ITuner destruction gets propagated through HAL
410be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk *  - the openTuner method works well when called for the second time
411be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk */
4122f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, ReopenTuner) {
4132f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
414be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    EXPECT_TRUE(openTuner());
415be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    mTuner.clear();
416be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    EXPECT_TRUE(openTuner());
417be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk}
418be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk
419be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk/**
420be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk * Test IBroadcastRadio::openTuner() method called twice.
421be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk *
422be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk * Verifies that:
423da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk *  - the openTuner method fails with INVALID_STATE or succeeds when called for the second time
424da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk *    without deleting previous ITuner instance
425be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk */
4262f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, OpenTunerTwice) {
4272f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
428be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    EXPECT_TRUE(openTuner());
429be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk
430be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    Result halResult = Result::NOT_INITIALIZED;
431da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    auto openCb = [&](Result result, const sp<ITuner>&) { halResult = result; };
432da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    auto hidlReturn = mRadio->openTuner(getBand(0), true, mTunerCallback, openCb);
433be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk    EXPECT_TRUE(hidlReturn.isOk());
434394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk    if (halResult == Result::OK) {
435394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk        if (radioClass == Class::AM_FM) {
436394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk            EXPECT_TRUE(waitForCallback(kConfigCallbacktimeoutNs));
437394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk        }
438394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk    } else {
439394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk        EXPECT_EQ(Result::INVALID_STATE, halResult);
440da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    }
441be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk}
442be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk
443be71e9c5bac644073c7ac29fc914361e65482ce9Tomasz Wasilczyk/**
444566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test ITuner::setConfiguration() and getConfiguration methods
445566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
446566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
447566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements both methods
448566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the methods return 0 (no error)
449566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the configuration callback is received within kConfigCallbacktimeoutNs ns
450566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the configuration read back from HAl has the same class Id
451394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk *
452394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * Skipped for other radio classes than AM/FM, because setConfiguration
453394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * applies only for these bands.
454566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
4552f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, SetAndGetConfiguration) {
456da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) skipped = true;
4572f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
458566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_EQ(true, openTuner());
459566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test setConfiguration
460566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
461da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    Return<Result> hidlResult = mTuner->setConfiguration(getBand(1));
462b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
463566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
464566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
465566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, mResultCallbackData);
466da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_EQ(getBand(1), mBandConfigCallbackData);
467566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
468566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test getConfiguration
469566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    BandConfig halConfig;
470566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Result halResult;
471566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Return<void> hidlReturn =
472566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            mTuner->getConfiguration([&](Result result, const BandConfig& config) {
473566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                halResult = result;
474566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                if (result == Result::OK) {
475566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                    halConfig = config;
476566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent                }
477566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            });
478b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlReturn.isOk());
479566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, halResult);
480da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    EXPECT_EQ(getBand(1), halConfig);
481566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
482566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
483566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
48410877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk * Test ITuner::setConfiguration() with invalid arguments.
48510877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk *
48610877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk * Verifies that:
48710877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk *  - the methods returns INVALID_ARGUMENTS on invalid arguments
48810877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk *  - the method recovers and succeeds after passing correct arguments
489394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk *
490394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * Skipped for other radio classes than AM/FM, because setConfiguration
491394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * applies only for these bands.
49210877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk */
4932f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, SetConfigurationFails) {
494da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) skipped = true;
4952f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
49610877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    ASSERT_EQ(true, openTuner());
49710877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk
49810877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    // Let's define a config that's bad for sure.
49910877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    BandConfig badConfig = {};
50010877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    badConfig.type = Band::FM;
50110877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    badConfig.lowerLimit = 0xFFFFFFFF;
50210877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    badConfig.upperLimit = 0;
50310877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    badConfig.spacings = (std::vector<uint32_t>){ 0 };
50410877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk
50510877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    // Test setConfiguration failing on bad data.
50610877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    mCallbackCalled = false;
50710877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    auto setResult = mTuner->setConfiguration(badConfig);
50810877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_TRUE(setResult.isOk());
50910877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_EQ(Result::INVALID_ARGUMENTS, setResult);
51010877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk
51110877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    // Test setConfiguration recovering after passing good data.
51210877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    mCallbackCalled = false;
513da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    setResult = mTuner->setConfiguration(getBand(0));
51410877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_TRUE(setResult.isOk());
51510877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_EQ(Result::OK, setResult);
51610877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_EQ(true, waitForCallback(kConfigCallbacktimeoutNs));
51710877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk    EXPECT_EQ(Result::OK, mResultCallbackData);
51810877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk}
51910877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk
52010877cd2e8ade1fef3c5de5edc469bc107043fa8Tomasz Wasilczyk/**
521566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test ITuner::scan
522566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
523566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
524566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements the method
525566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the method returns 0 (no error)
526566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
527a8dec0f907cb42708e1b178d8bda4879fca157d4Tomasz Wasilczyk *  - skipping sub-channel or not does not fail the call
528566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
5292f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, Scan) {
5302f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
531566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_EQ(true, openTuner());
532566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_TRUE(checkAntenna());
533566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test scan UP
534566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
535566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Return<Result> hidlResult = mTuner->scan(Direction::UP, true);
536b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
537566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
538566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
539566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
540566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test scan DOWN
541566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
542a8dec0f907cb42708e1b178d8bda4879fca157d4Tomasz Wasilczyk    hidlResult = mTuner->scan(Direction::DOWN, false);
543b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
544566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
545566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
546566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
547566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
548566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
549566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test ITuner::step
550566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
551566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
552566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements the method
553566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the method returns 0 (no error)
554566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the tuned callback is received within kTuneCallbacktimeoutNs ns
555a8dec0f907cb42708e1b178d8bda4879fca157d4Tomasz Wasilczyk *  - skipping sub-channel or not does not fail the call
556394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk *
557394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * Skipped for other radio classes than AM/FM, because step is not possible
558394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * on DAB nor satellite.
559566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
5602f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, Step) {
561da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) skipped = true;
5622f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
563566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_EQ(true, openTuner());
564566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_TRUE(checkAntenna());
565566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test step UP
566566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
567a8dec0f907cb42708e1b178d8bda4879fca157d4Tomasz Wasilczyk    Return<Result> hidlResult = mTuner->step(Direction::UP, false);
568b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
569566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
570566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
571566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
572566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test step DOWN
573566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
574566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    hidlResult = mTuner->step(Direction::DOWN, true);
575b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
576566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
577566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
578566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
579566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
580566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent/**
581566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Test ITuner::tune,  getProgramInformation and cancel methods
582566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *
583566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent * Verifies that:
584566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the HAL implements the methods
585566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the methods return 0 (no error)
586566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent *  - the tuned callback is received within kTuneCallbacktimeoutNs ns after tune()
587394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk *
588394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * Skipped for other radio classes than AM/FM, because tune to frequency
589394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * is not possible on DAB nor satellite.
590566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent */
5912f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, TuneAndGetProgramInformationAndCancel) {
592da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) skipped = true;
5932f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
594566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_EQ(true, openTuner());
595566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ASSERT_TRUE(checkAntenna());
596566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
597da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    auto& band = getBand(0);
598da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk
599566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test tune
600da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    ASSERT_GT(band.spacings.size(), 0u);
601da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    ASSERT_GT(band.upperLimit, band.lowerLimit);
602566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
603566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test scan UP
604da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    uint32_t lowerLimit = band.lowerLimit;
605da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    uint32_t upperLimit = band.upperLimit;
606da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    uint32_t spacing = band.spacings[0];
607566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
608566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    uint32_t channel =
609566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent            lowerLimit + (((upperLimit - lowerLimit) / 2 + spacing - 1) / spacing) * spacing;
610566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mCallbackCalled = false;
611566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mResultCallbackData = Result::NOT_INITIALIZED;
612566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Return<Result> hidlResult = mTuner->tune(channel, 0);
613b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
614566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
615566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
616f3c036d7d60db0db3e21d6ea3c5cd41b57f259daTomasz Wasilczyk    EXPECT_EQ(channel, mProgramInfoCallbackData.channel);
617566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
618566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test getProgramInformation
619566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    ProgramInfo halInfo;
620566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Result halResult = Result::NOT_INITIALIZED;
621566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    Return<void> hidlReturn = mTuner->getProgramInformation(
6225cc9d866d2d7aeb05f05dcaa1296e28a7caeed19Tomasz Wasilczyk        [&](Result result, const ProgramInfo& info) {
6235cc9d866d2d7aeb05f05dcaa1296e28a7caeed19Tomasz Wasilczyk            halResult = result;
6245cc9d866d2d7aeb05f05dcaa1296e28a7caeed19Tomasz Wasilczyk            if (result == Result::OK) {
6255cc9d866d2d7aeb05f05dcaa1296e28a7caeed19Tomasz Wasilczyk                halInfo = info;
6265cc9d866d2d7aeb05f05dcaa1296e28a7caeed19Tomasz Wasilczyk            }
627566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        });
628b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlReturn.isOk());
629566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, halResult);
630566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    if (mResultCallbackData == Result::OK) {
631566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        EXPECT_LE(halInfo.channel, upperLimit);
632566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent        EXPECT_GE(halInfo.channel, lowerLimit);
633566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    }
634566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
635566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    // test cancel
636566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    mTuner->tune(lowerLimit, 0);
637566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    hidlResult = mTuner->cancel();
638b6438421923590b765905efe151e26129dce4094Steven Moreland    EXPECT_TRUE(hidlResult.isOk());
639566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent    EXPECT_EQ(Result::OK, hidlResult);
640566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
641566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
64259d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk/**
64359d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk * Test ITuner::tune failing when channel out of the range is provided.
64459d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk *
64559d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk * Verifies that:
64659d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk *  - the method returns INVALID_ARGUMENTS when applicable
64759d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk *  - the method recovers and succeeds after passing correct arguments
648394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk *
649394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * Skipped for other radio classes than AM/FM, because tune to frequency
650394b343ae5a5348f7b2992ff341c7204d8d38cb5Tomasz Wasilczyk * is not possible on DAB nor satellite.
65159d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk */
6522f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykTEST_P(BroadcastRadioHidlTest, TuneFailsOutOfBounds) {
653da72d37770a9d250a82cc0e5482c0aa2e8f7087bTomasz Wasilczyk    if (radioClass != Class::AM_FM) skipped = true;
6542f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    RETURN_IF_SKIPPED;
65559d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    ASSERT_TRUE(openTuner());
65659d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    ASSERT_TRUE(checkAntenna());
65759d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk
65859d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    // get current channel bounds
65959d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    BandConfig halConfig;
66059d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    Result halResult;
66159d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    auto configResult = mTuner->getConfiguration([&](Result result, const BandConfig& config) {
66259d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk        halResult = result;
66359d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk        halConfig = config;
66459d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    });
66559d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    ASSERT_TRUE(configResult.isOk());
66659d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    ASSERT_EQ(Result::OK, halResult);
66759d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk
66859d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    // try to tune slightly above the limit and expect to fail
66959d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    auto badChannel = halConfig.upperLimit + halConfig.spacings[0];
67059d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    auto tuneResult = mTuner->tune(badChannel, 0);
67159d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_TRUE(tuneResult.isOk());
67259d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_EQ(Result::INVALID_ARGUMENTS, tuneResult);
67359d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
67459d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk
67559d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    // tuning exactly at the limit should succeed
67659d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    auto goodChannel = halConfig.upperLimit;
67759d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    tuneResult = mTuner->tune(goodChannel, 0);
67859d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_TRUE(tuneResult.isOk());
67959d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_EQ(Result::OK, tuneResult);
68059d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk    EXPECT_TRUE(waitForCallback(kTuneCallbacktimeoutNs));
68159d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk}
68259d985df881a24ff0a85517ff589ca708b5d23deTomasz Wasilczyk
683ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk/**
684ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk * Test proper image format in metadata.
685ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk *
686ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk * Verifies that:
687ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk * - all images in metadata are provided in-band (as a binary blob, not by id)
688ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk *
689ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk * This is a counter-test for OobImagesOnly from 1.1 VTS.
690ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk */
691ba3e254483c18238b25445b48d9d3592d40689a3Tomasz WasilczykTEST_P(BroadcastRadioHidlTest, IbImagesOnly) {
692ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    RETURN_IF_SKIPPED;
693ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    ASSERT_TRUE(openTuner());
694ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    ASSERT_TRUE(checkAntenna());
695ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk
696ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    bool firstScan = true;
697ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    uint32_t firstChannel, prevChannel;
698ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    while (true) {
699ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        mCallbackCalled = false;
700ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        auto hidlResult = mTuner->scan(Direction::UP, true);
701ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        ASSERT_TRUE(hidlResult.isOk());
702ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        if (hidlResult == Result::TIMEOUT) {
703ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            ALOGI("Got timeout on scan operation");
704ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            break;
705ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        }
706ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        ASSERT_EQ(Result::OK, hidlResult);
707ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        ASSERT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
708ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk
709ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        if (firstScan) {
710ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            firstScan = false;
711ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            firstChannel = mProgramInfoCallbackData.channel;
712ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        } else {
713ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            // scanned the whole band
714ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            if (mProgramInfoCallbackData.channel >= firstChannel && prevChannel <= firstChannel) {
715ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk                break;
716ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            }
717ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        }
718ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        prevChannel = mProgramInfoCallbackData.channel;
719ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk
720ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        for (auto&& entry : mProgramInfoCallbackData.metadata) {
721ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            if (entry.key != MetadataKey::ICON && entry.key != MetadataKey::ART) continue;
722ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            EXPECT_EQ(MetadataType::RAW, entry.type);
723ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            EXPECT_EQ(0, entry.intValue);
724ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk            EXPECT_GT(entry.rawValue.size(), 0u);
725ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk        }
726ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk    }
727ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk}
728ba3e254483c18238b25445b48d9d3592d40689a3Tomasz Wasilczyk
7292f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz WasilczykINSTANTIATE_TEST_CASE_P(
7302f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    BroadcastRadioHidlTestCases,
7312f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    BroadcastRadioHidlTest,
7322f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk    ::testing::Values(Class::AM_FM, Class::SAT, Class::DT));
733566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent
734566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurentint main(int argc, char** argv) {
735190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    gEnv = new BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>;
736190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    ::testing::AddGlobalTestEnvironment(gEnv);
737190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    ::testing::InitGoogleTest(&argc, argv);
738190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    gEnv->init(&argc, argv);
739190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    int status = RUN_ALL_TESTS();
740190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    ALOGI("Test result = %d", status);
741190548f558f3156356f6244c70733025da95598fZhuoyao Zhang    return status;
742566fcdabaad557bb7cc447c3b3ef63de6b93babeEric Laurent}
743