1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Tuner" 18//#define LOG_NDEBUG 0 19 20#include <log/log.h> 21 22#include "BroadcastRadio.h" 23#include "Tuner.h" 24#include "Utils.h" 25#include <system/RadioMetadataWrapper.h> 26 27namespace android { 28namespace hardware { 29namespace broadcastradio { 30namespace V1_0 { 31namespace implementation { 32 33void Tuner::onCallback(radio_hal_event_t *halEvent) 34{ 35 BandConfig config; 36 ProgramInfo info; 37 hidl_vec<MetaData> metadata; 38 39 if (mCallback != 0) { 40 switch(halEvent->type) { 41 case RADIO_EVENT_CONFIG: 42 Utils::convertBandConfigFromHal(&config, &halEvent->config); 43 mCallback->configChange(Utils::convertHalResult(halEvent->status), config); 44 break; 45 case RADIO_EVENT_ANTENNA: 46 mCallback->antennaStateChange(halEvent->on); 47 break; 48 case RADIO_EVENT_TUNED: 49 Utils::convertProgramInfoFromHal(&info, &halEvent->info); 50 mCallback->tuneComplete(Utils::convertHalResult(halEvent->status), info); 51 break; 52 case RADIO_EVENT_METADATA: { 53 uint32_t channel; 54 uint32_t sub_channel; 55 if (radio_metadata_get_channel(halEvent->metadata, &channel, &sub_channel) == 0) { 56 Utils::convertMetaDataFromHal(metadata, halEvent->metadata); 57 mCallback->newMetadata(channel, sub_channel, metadata); 58 } 59 } break; 60 case RADIO_EVENT_TA: 61 mCallback->trafficAnnouncement(halEvent->on); 62 break; 63 case RADIO_EVENT_AF_SWITCH: 64 Utils::convertProgramInfoFromHal(&info, &halEvent->info); 65 mCallback->afSwitch(info); 66 break; 67 case RADIO_EVENT_EA: 68 mCallback->emergencyAnnouncement(halEvent->on); 69 break; 70 case RADIO_EVENT_HW_FAILURE: 71 default: 72 mCallback->hardwareFailure(); 73 break; 74 } 75 } 76} 77 78//static 79void Tuner::callback(radio_hal_event_t *halEvent, void *cookie) 80{ 81 wp<Tuner> weak(reinterpret_cast<Tuner*>(cookie)); 82 sp<Tuner> tuner = weak.promote(); 83 if (tuner == 0) return; 84 tuner->onCallback(halEvent); 85} 86 87Tuner::Tuner(const sp<ITunerCallback>& callback, const wp<BroadcastRadio>& parentDevice) 88 : mHalTuner(NULL), mCallback(callback), mParentDevice(parentDevice) 89{ 90 ALOGV("%s", __FUNCTION__); 91} 92 93 94Tuner::~Tuner() 95{ 96 ALOGV("%s", __FUNCTION__); 97 const sp<BroadcastRadio> parentDevice = mParentDevice.promote(); 98 if (parentDevice != 0) { 99 parentDevice->closeHalTuner(mHalTuner); 100 } 101} 102 103// Methods from ::android::hardware::broadcastradio::V1_0::ITuner follow. 104Return<Result> Tuner::setConfiguration(const BandConfig& config) { 105 ALOGV("%s", __FUNCTION__); 106 if (mHalTuner == NULL) { 107 return Utils::convertHalResult(-ENODEV); 108 } 109 radio_hal_band_config_t halConfig; 110 Utils::convertBandConfigToHal(&halConfig, &config); 111 int rc = mHalTuner->set_configuration(mHalTuner, &halConfig); 112 return Utils::convertHalResult(rc); 113} 114 115Return<void> Tuner::getConfiguration(getConfiguration_cb _hidl_cb) { 116 int rc; 117 radio_hal_band_config_t halConfig; 118 BandConfig config; 119 120 ALOGV("%s", __FUNCTION__); 121 if (mHalTuner == NULL) { 122 rc = -ENODEV; 123 goto exit; 124 } 125 rc = mHalTuner->get_configuration(mHalTuner, &halConfig); 126 if (rc == 0) { 127 Utils::convertBandConfigFromHal(&config, &halConfig); 128 } 129 130exit: 131 _hidl_cb(Utils::convertHalResult(rc), config); 132 return Void(); 133} 134 135Return<Result> Tuner::scan(Direction direction, bool skipSubChannel) { 136 if (mHalTuner == NULL) { 137 return Utils::convertHalResult(-ENODEV); 138 } 139 int rc = mHalTuner->scan(mHalTuner, static_cast<radio_direction_t>(direction), skipSubChannel); 140 return Utils::convertHalResult(rc); 141} 142 143Return<Result> Tuner::step(Direction direction, bool skipSubChannel) { 144 if (mHalTuner == NULL) { 145 return Utils::convertHalResult(-ENODEV); 146 } 147 int rc = mHalTuner->step(mHalTuner, static_cast<radio_direction_t>(direction), skipSubChannel); 148 return Utils::convertHalResult(rc); 149} 150 151Return<Result> Tuner::tune(uint32_t channel, uint32_t subChannel) { 152 if (mHalTuner == NULL) { 153 return Utils::convertHalResult(-ENODEV); 154 } 155 int rc = mHalTuner->tune(mHalTuner, channel, subChannel); 156 return Utils::convertHalResult(rc); 157} 158 159Return<Result> Tuner::cancel() { 160 if (mHalTuner == NULL) { 161 return Utils::convertHalResult(-ENODEV); 162 } 163 int rc = mHalTuner->cancel(mHalTuner); 164 return Utils::convertHalResult(rc); 165} 166 167Return<void> Tuner::getProgramInformation(getProgramInformation_cb _hidl_cb) { 168 int rc; 169 radio_program_info_t halInfo; 170 RadioMetadataWrapper metadataWrapper(&halInfo.metadata); 171 ProgramInfo info; 172 173 ALOGV("%s", __FUNCTION__); 174 if (mHalTuner == NULL) { 175 rc = -ENODEV; 176 goto exit; 177 } 178 179 rc = mHalTuner->get_program_information(mHalTuner, &halInfo); 180 if (rc == 0) { 181 Utils::convertProgramInfoFromHal(&info, &halInfo); 182 } 183 184exit: 185 _hidl_cb(Utils::convertHalResult(rc), info); 186 return Void(); 187} 188 189} // namespace implementation 190} // namespace V1_0 191} // namespace broadcastradio 192} // namespace hardware 193} // namespace android 194