1213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk/* 2213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project 3213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * 4213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License"); 5213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * you may not use this file except in compliance with the License. 6213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * You may obtain a copy of the License at 7213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * 8213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * http://www.apache.org/licenses/LICENSE-2.0 9213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * 10213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software 11213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS, 12213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * See the License for the specific language governing permissions and 14213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk * limitations under the License. 15213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk */ 16213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#define LOG_TAG "BroadcastRadio" 17213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk//#define LOG_NDEBUG 0 18213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 19213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include <log/log.h> 20213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 21213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "BroadcastRadio.h" 22213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "Tuner.h" 23213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk#include "Utils.h" 24213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 25213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace android { 26213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace hardware { 27213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace broadcastradio { 28213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace V1_1 { 29213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyknamespace implementation { 30213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 31213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykusing ::android::sp; 32213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 33213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykBroadcastRadio::BroadcastRadio(Class classId) 34213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk : mStatus(Result::NOT_INITIALIZED), mClassId(classId), mHwDevice(NULL) 35213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 36213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 37213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 38213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykBroadcastRadio::~BroadcastRadio() 39213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 40213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (mHwDevice != NULL) { 41213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk radio_hw_device_close(mHwDevice); 42213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 43213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 44213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 45213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykvoid BroadcastRadio::onFirstRef() 46213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 47213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk const hw_module_t *mod; 48213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk int rc; 49213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGI("%s mClassId %d", __FUNCTION__, mClassId); 50213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 51213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk mHwDevice = NULL; 52213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk const char *classString = Utils::getClassString(mClassId); 53213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (classString == NULL) { 54213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGE("invalid class ID %d", mClassId); 55213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk mStatus = Result::INVALID_ARGUMENTS; 56213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return; 57213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 58213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 59213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s", 60213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk __FUNCTION__, RADIO_HARDWARE_MODULE_ID, classString); 61213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 62213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, classString, &mod); 63213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (rc != 0) { 64213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGE("couldn't load radio module %s.%s (%s)", 65213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk RADIO_HARDWARE_MODULE_ID, classString, strerror(-rc)); 66213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return; 67213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 68213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk rc = radio_hw_device_open(mod, &mHwDevice); 69213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (rc != 0) { 70213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGE("couldn't open radio hw device in %s.%s (%s)", 71213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc)); 72213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk mHwDevice = NULL; 73213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return; 74213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 75213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) { 76213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGE("wrong radio hw device version %04x", mHwDevice->common.version); 77213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk radio_hw_device_close(mHwDevice); 78213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk mHwDevice = NULL; 79213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } else { 80213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk mStatus = Result::OK; 81213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 82213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 83213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 84213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykint BroadcastRadio::closeHalTuner(const struct radio_tuner *halTuner) 85213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 86213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk ALOGV("%s", __FUNCTION__); 87213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (mHwDevice == NULL) { 88213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return -ENODEV; 89213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 90213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (halTuner == 0) { 91213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return -EINVAL; 92213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 93213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return mHwDevice->close_tuner(mHwDevice, halTuner); 94213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 95213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 96213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 97803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk// Methods from ::android::hardware::broadcastradio::V1_1::IBroadcastRadio follow. 98213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykReturn<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) 99213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 100213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk int rc; 101213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk radio_hal_properties_t halProperties; 102213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk Properties properties; 103213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 104213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (mHwDevice == NULL) { 105213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk rc = -ENODEV; 106213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk goto exit; 107213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 108213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk rc = mHwDevice->get_properties(mHwDevice, &halProperties); 109213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (rc == 0) { 110213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk Utils::convertPropertiesFromHal(&properties, &halProperties); 111213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 112213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 113213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczykexit: 114213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk _hidl_cb(Utils::convertHalResult(rc), properties); 115213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return Void(); 116213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 117213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 118803301a2ed397ee39c9e703c611703053aad594fTomasz WasilczykReturn<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb __unused) 119803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk{ 120803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION); 121803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk} 122803301a2ed397ee39c9e703c611703053aad594fTomasz Wasilczyk 123213170b663a91706420ade17239089cfa38f4a68Tomasz WasilczykReturn<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio, 124213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk const sp<V1_0::ITunerCallback>& callback, openTuner_cb _hidl_cb) 125213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk{ 126213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk sp<Tuner> tunerImpl = new Tuner(callback, this); 127213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 128213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk radio_hal_band_config_t halConfig; 129213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk const struct radio_tuner *halTuner; 130213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk Utils::convertBandConfigToHal(&halConfig, &config); 131213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk int rc = mHwDevice->open_tuner(mHwDevice, &halConfig, audio, Tuner::callback, 132213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk tunerImpl.get(), &halTuner); 133213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk if (rc == 0) { 134213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk tunerImpl->setHalTuner(halTuner); 135213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk } 136213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 137213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk _hidl_cb(Utils::convertHalResult(rc), tunerImpl); 138213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk return Void(); 139213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} 140213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk 141213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace implementation 142213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace V1_1 143213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace broadcastradio 144213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace hardware 145213170b663a91706420ade17239089cfa38f4a68Tomasz Wasilczyk} // namespace android 146