173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent/*
273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * Copyright (C) 2016 The Android Open Source Project
373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent *
473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * you may not use this file except in compliance with the License.
673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * You may obtain a copy of the License at
773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent *
873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent *
1073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * Unless required by applicable law or agreed to in writing, software
1173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
1273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * See the License for the specific language governing permissions and
1473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent * limitations under the License.
1573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent */
1673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
1773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#define LOG_TAG "RadioHalHidl"
1873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent//#define LOG_NDEBUG 0
1973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
20d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov#include <media/audiohal/hidl/HalDeathHandler.h>
2173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#include <utils/Log.h>
2273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#include <utils/misc.h>
23a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk#include <system/RadioMetadataWrapper.h>
2473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
2573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
2673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#include "RadioHalHidl.h"
2773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent#include "HidlUtils.h"
2873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
2973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentnamespace android {
3073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
3173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentusing android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
3273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentusing android::hardware::broadcastradio::V1_0::Class;
3373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentusing android::hardware::broadcastradio::V1_0::Direction;
3473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentusing android::hardware::broadcastradio::V1_0::Properties;
3573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
3673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
3773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent/* static */
3873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentsp<RadioInterface> RadioInterface::connectModule(radio_class_t classId)
3973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
4073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return new RadioHalHidl(classId);
4173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
4273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
4373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::getProperties(radio_hal_properties_t *properties)
4473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
4573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
4673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<IBroadcastRadio> module = getService();
4773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (module == 0) {
4873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
4973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
5073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Properties halProperties;
51e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    Result halResult = Result::NOT_INITIALIZED;
5273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<void> hidlReturn =
5373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            module->getProperties([&](Result result, const Properties& properties) {
5473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    halResult = result;
5573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    if (result == Result::OK) {
5673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                        halProperties = properties;
5773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    }
5873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                });
5973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
6073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (halResult == Result::OK) {
6173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        HidlUtils::convertPropertiesFromHal(properties, &halProperties);
6273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
6373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(halResult);
6473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
6573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
6673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::openTuner(const radio_hal_band_config_t *config,
6773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                            bool audio,
6873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                            sp<TunerCallbackInterface> callback,
6973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                            sp<TunerInterface>& tuner)
7073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
7173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<IBroadcastRadio> module = getService();
7273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (module == 0) {
7373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
7473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
7573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<Tuner> tunerImpl = new Tuner(callback, this);
7673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
7773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    BandConfig halConfig;
78e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    Result halResult = Result::NOT_INITIALIZED;
7973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<ITuner> halTuner;
8073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
8173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    HidlUtils::convertBandConfigToHal(&halConfig, config);
8273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<void> hidlReturn =
8373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            module->openTuner(halConfig, audio, tunerImpl,
8473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                              [&](Result result, const sp<ITuner>& tuner) {
8573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    halResult = result;
8673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    if (result == Result::OK) {
8773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                        halTuner = tuner;
8873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    }
8973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                });
9073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
9173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (halResult == Result::OK) {
9273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        tunerImpl->setHalTuner(halTuner);
9373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        tuner = tunerImpl;
9473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
9573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
9673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(halResult);
9773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
9873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
9973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::closeTuner(sp<TunerInterface>& tuner)
10073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
10173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<Tuner> tunerImpl = static_cast<Tuner *>(tuner.get());
10273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<ITuner> clearTuner;
10373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    tunerImpl->setHalTuner(clearTuner);
10473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return 0;
10573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
10673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
10773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentRadioHalHidl::RadioHalHidl(radio_class_t classId)
10873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    : mClassId(classId)
10973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
11073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
11173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
11273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentRadioHalHidl::~RadioHalHidl()
11373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
11473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
11573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
11673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentsp<IBroadcastRadio> RadioHalHidl::getService()
11773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
11873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalModule == 0) {
1199d82aea709d206093df5ba6eae407fbcca5b9f5bChris Phoenix        sp<IBroadcastRadioFactory> factory = IBroadcastRadioFactory::getService();
12073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        if (factory != 0) {
12173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            factory->connectModule(static_cast<Class>(mClassId),
12273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                               [&](Result retval, const ::android::sp<IBroadcastRadio>& result) {
12373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                if (retval == Result::OK) {
12473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    mHalModule = result;
12573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                }
12673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            });
12773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        }
12873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
12973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s OUT module %p", __FUNCTION__, mHalModule.get());
13073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return mHalModule;
13173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
13273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
13373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentvoid RadioHalHidl::clearService()
13473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
13573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN module %p", __FUNCTION__, mHalModule.get());
13673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    mHalModule.clear();
13773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
13873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
13973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
14073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::setConfiguration(const radio_hal_band_config_t *config)
14173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
14273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
14373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
14473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
14573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
14673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
14773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    BandConfig halConfig;
14873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    HidlUtils::convertBandConfigToHal(&halConfig, config);
14973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
15073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<Result> hidlResult = mHalTuner->setConfiguration(halConfig);
15173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(hidlResult);
15273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
15373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
15473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::getConfiguration(radio_hal_band_config_t *config)
15573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
15673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
15773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
15873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
15973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
16073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    BandConfig halConfig;
16173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Result halResult;
16273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<void> hidlReturn =
16373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            mHalTuner->getConfiguration([&](Result result, const BandConfig& config) {
16473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    halResult = result;
16573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    if (result == Result::OK) {
16673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                        halConfig = config;
16773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                    }
16873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                });
169e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    if (hidlReturn.isOk() && halResult == Result::OK) {
17073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        HidlUtils::convertBandConfigFromHal(config, &halConfig);
17173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
17273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(halResult);
17373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
17473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
17573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::scan(radio_direction_t direction, bool skip_sub_channel)
17673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
17773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
17873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
17973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
18073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
18173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<Result> hidlResult =
18273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            mHalTuner->scan(static_cast<Direction>(direction), skip_sub_channel);
18373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(hidlResult);
18473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
18573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
18673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::step(radio_direction_t direction, bool skip_sub_channel)
18773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
18873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
18973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
19073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
19173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
19273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<Result> hidlResult =
19373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            mHalTuner->step(static_cast<Direction>(direction), skip_sub_channel);
19473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(hidlResult);
19573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
19673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
19773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::tune(unsigned int channel, unsigned int sub_channel)
19873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
19973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
20073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
20173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
20273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
20373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<Result> hidlResult =
20473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent            mHalTuner->tune(channel, sub_channel);
20573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(hidlResult);
20673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
20773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
20873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::cancel()
20973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
21073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
21173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
21273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
21373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
21473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<Result> hidlResult = mHalTuner->cancel();
21573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(hidlResult);
21673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
21773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
21873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentint RadioHalHidl::Tuner::getProgramInformation(radio_program_info_t *info)
21973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
22073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN mHalTuner %p", __FUNCTION__, mHalTuner.get());
22173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mHalTuner == 0) {
22273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        return -ENODEV;
22373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
224049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk    if (info == nullptr || info->metadata == nullptr) {
225049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk        return BAD_VALUE;
226049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk    }
22773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ProgramInfo halInfo;
22873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Result halResult;
22973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    Return<void> hidlReturn = mHalTuner->getProgramInformation(
230049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk        [&](Result result, const ProgramInfo& info) {
231049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk            halResult = result;
232049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk            if (result == Result::OK) {
233049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk                halInfo = info;
234049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk            }
235049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk        });
236e83be8af690ef1ac820a63414d522e77ca9d4db6Steven Moreland    if (hidlReturn.isOk() && halResult == Result::OK) {
237049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk        HidlUtils::convertProgramInfoFromHal(info, &halInfo);
23873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
23973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return HidlUtils::convertHalResult(halResult);
24073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
24173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
24273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::hardwareFailure()
24373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
24473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
24573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    handleHwFailure();
24673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
24773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
24873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
24973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::configChange(Result result, const BandConfig& config)
25073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
25173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
25273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    radio_hal_event_t event;
25373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    memset(&event, 0, sizeof(radio_hal_event_t));
25473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_CONFIG;
25573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.status = HidlUtils::convertHalResult(result);
25673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    HidlUtils::convertBandConfigFromHal(&event.config, &config);
25773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
25873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
25973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
26073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
26173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::tuneComplete(Result result, const ProgramInfo& info)
26273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
26373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
264a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk    radio_hal_event_t event = {};
265a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk    RadioMetadataWrapper metadataWrapper(&event.info.metadata);
266a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk
26773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_TUNED;
26873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.status = HidlUtils::convertHalResult(result);
269049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk    HidlUtils::convertProgramInfoFromHal(&event.info, &info);
27073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
27173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
27273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
27373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
27473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::afSwitch(const ProgramInfo& info)
27573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
27673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
277a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk    radio_hal_event_t event = {};
278a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk    RadioMetadataWrapper metadataWrapper(&event.info.metadata);
279a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk
28073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_AF_SWITCH;
281049475c201d6801e0a15ce102a4f9c357de83b61Tomasz Wasilczyk    HidlUtils::convertProgramInfoFromHal(&event.info, &info);
28273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
28373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
28473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
28573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
28673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::antennaStateChange(bool connected)
28773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
28873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
28973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    radio_hal_event_t event;
29073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    memset(&event, 0, sizeof(radio_hal_event_t));
29173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_ANTENNA;
29273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.on = connected;
29373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
29473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
29573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
29673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::trafficAnnouncement(bool active)
29773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
29873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
29973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    radio_hal_event_t event;
30073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    memset(&event, 0, sizeof(radio_hal_event_t));
30173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_TA;
30273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.on = active;
30373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
30473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
30573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
30673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::emergencyAnnouncement(bool active)
30773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
30873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
30973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    radio_hal_event_t event;
31073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    memset(&event, 0, sizeof(radio_hal_event_t));
31173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_EA;
31273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.on = active;
31373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
31473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
31573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
31673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentReturn<void> RadioHalHidl::Tuner::newMetadata(uint32_t channel, uint32_t subChannel,
31773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent                                          const ::android::hardware::hidl_vec<MetaData>& metadata)
31873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
31973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
320a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk    radio_hal_event_t event = {};
321d0b096052c753f916cb25f9a67c84b69dc5a1293Tomasz Wasilczyk    RadioMetadataWrapper metadataWrapper(&event.metadata);
322a0ea70c5764131c44abeeb26867f1a9f0394ac2fTomasz Wasilczyk
32373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_METADATA;
32473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    HidlUtils::convertMetaDataFromHal(&event.metadata, metadata, channel, subChannel);
32573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
32673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    return Return<void>();
32773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
32873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
32973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
33073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentRadioHalHidl::Tuner::Tuner(sp<TunerCallbackInterface> callback, sp<RadioHalHidl> module)
33173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    : TunerInterface(), mHalTuner(NULL), mCallback(callback), mParentModule(module)
33273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
333d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    // Make sure the handler we are passing in only deals with const members,
334d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    // as it can be called on an arbitrary thread.
335d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    const auto& self = this;
336d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    HalDeathHandler::getInstance()->registerAtExitHandler(
337d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov            this, [&self]() { self->sendHwFailureEvent(); });
33873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
33973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
34073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
34173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric LaurentRadioHalHidl::Tuner::~Tuner()
34273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
343d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    HalDeathHandler::getInstance()->unregisterAtExitHandler(this);
344d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov}
345d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov
346d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganovvoid RadioHalHidl::Tuner::setHalTuner(sp<ITuner>& halTuner) {
347d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    if (mHalTuner != 0) {
348d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov        mHalTuner->unlinkToDeath(HalDeathHandler::getInstance());
349d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    }
350d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    mHalTuner = halTuner;
351d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    if (mHalTuner != 0) {
352d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov        mHalTuner->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
353d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    }
35473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
35573e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
35673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurentvoid RadioHalHidl::Tuner::handleHwFailure()
35773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
35873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    ALOGV("%s IN", __FUNCTION__);
35973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    sp<RadioHalHidl> parentModule = mParentModule.promote();
36073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (parentModule != 0) {
36173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        parentModule->clearService();
36273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
363d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    sendHwFailureEvent();
364d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov    mHalTuner.clear();
365d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov}
366d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov
367d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganovvoid RadioHalHidl::Tuner::sendHwFailureEvent() const
368d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganov{
36973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    radio_hal_event_t event;
37073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    memset(&event, 0, sizeof(radio_hal_event_t));
37173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    event.type = RADIO_EVENT_HW_FAILURE;
37273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    onCallback(&event);
37373e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
37473e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
375d621ac82e648c8ef395068edb1af2747f49b700aMikhail Naganovvoid RadioHalHidl::Tuner::onCallback(radio_hal_event_t *halEvent) const
37673e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent{
37773e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    if (mCallback != 0) {
37873e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent        mCallback->onEvent(halEvent);
37973e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent    }
38073e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent}
38173e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent
38273e17f219e9ebcf45d6bc471b00b981428a4bc62Eric Laurent} // namespace android
383