Home | History | Annotate | Download | only in default
      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 #define LOG_TAG "BroadcastRadioHalUtils"
     17 //#define LOG_NDEBUG 0
     18 
     19 #include <log/log.h>
     20 #include <utils/misc.h>
     21 #include <system/radio_metadata.h>
     22 
     23 #include "Utils.h"
     24 
     25 namespace android {
     26 namespace hardware {
     27 namespace broadcastradio {
     28 namespace V1_0 {
     29 namespace implementation {
     30 
     31 const char *Utils::sClassModuleNames[] = {
     32     RADIO_HARDWARE_MODULE_ID_FM, /* corresponds to RADIO_CLASS_AM_FM */
     33     RADIO_HARDWARE_MODULE_ID_SAT,  /* corresponds to RADIO_CLASS_SAT */
     34     RADIO_HARDWARE_MODULE_ID_DT,   /* corresponds to RADIO_CLASS_DT */
     35 };
     36 
     37 // make sure HIDL enum values are aligned with legacy values
     38 static_assert(RADIO_CLASS_AM_FM == static_cast<int>(Class::AM_FM),
     39               "AM/FM class mismatch with legacy");
     40 static_assert(RADIO_CLASS_SAT == static_cast<int>(Class::SAT),
     41               "SAT class mismatch with legacy");
     42 static_assert(RADIO_CLASS_DT == static_cast<int>(Class::DT),
     43               "DT class mismatch with legacy");
     44 
     45 static_assert(RADIO_BAND_AM == static_cast<int>(Band::AM),
     46               "AM band mismatch with legacy");
     47 static_assert(RADIO_BAND_FM == static_cast<int>(Band::FM),
     48               "FM band mismatch with legacy");
     49 static_assert(RADIO_BAND_AM_HD == static_cast<int>(Band::AM_HD),
     50               "AM HD band mismatch with legacy");
     51 static_assert(RADIO_BAND_FM_HD == static_cast<int>(Band::FM_HD),
     52               "FM HD band mismatch with legacy");
     53 
     54 static_assert(RADIO_RDS_NONE == static_cast<int>(Rds::NONE),
     55               "RDS NONE mismatch with legacy");
     56 static_assert(RADIO_RDS_WORLD == static_cast<int>(Rds::WORLD),
     57               "RDS WORLD mismatch with legacy");
     58 static_assert(RADIO_RDS_US == static_cast<int>(Rds::US),
     59               "RDS US mismatch with legacy");
     60 
     61 static_assert(RADIO_DEEMPHASIS_50 == static_cast<int>(Deemphasis::D50),
     62               "De-emphasis 50 mismatch with legacy");
     63 static_assert(RADIO_DEEMPHASIS_75 == static_cast<int>(Deemphasis::D75),
     64               "De-emphasis 75 mismatch with legacy");
     65 
     66 static_assert(RADIO_DIRECTION_UP == static_cast<int>(Direction::UP),
     67               "Direction Up mismatch with legacy");
     68 static_assert(RADIO_DIRECTION_DOWN == static_cast<int>(Direction::DOWN),
     69               "Direction Up mismatch with legacy");
     70 
     71 static_assert(RADIO_METADATA_TYPE_INVALID == static_cast<int>(MetadataType::INVALID),
     72               "Metadata type INVALID mismatch with legacy");
     73 static_assert(RADIO_METADATA_TYPE_INT == static_cast<int>(MetadataType::INT),
     74               "Metadata type INT mismatch with legacy");
     75 static_assert(RADIO_METADATA_TYPE_TEXT == static_cast<int>(MetadataType::TEXT),
     76               "Metadata type TEXT mismatch with legacy");
     77 static_assert(RADIO_METADATA_TYPE_RAW == static_cast<int>(MetadataType::RAW),
     78               "Metadata type RAW mismatch with legacy");
     79 static_assert(RADIO_METADATA_TYPE_CLOCK == static_cast<int>(MetadataType::CLOCK),
     80               "Metadata type CLOCK mismatch with legacy");
     81 
     82 static_assert(RADIO_METADATA_KEY_INVALID == static_cast<int>(MetadataKey::INVALID),
     83               "Metadata key INVALID mismatch with legacy");
     84 static_assert(RADIO_METADATA_KEY_RDS_PI == static_cast<int>(MetadataKey::RDS_PI),
     85               "Metadata key RDS_PI mismatch with legacy");
     86 static_assert(RADIO_METADATA_KEY_RDS_PS == static_cast<int>(MetadataKey::RDS_PS),
     87               "Metadata key RDS_PS mismatch with legacy");
     88 static_assert(RADIO_METADATA_KEY_RDS_PTY == static_cast<int>(MetadataKey::RDS_PTY),
     89               "Metadata key RDS_PTY mismatch with legacy");
     90 static_assert(RADIO_METADATA_KEY_RBDS_PTY == static_cast<int>(MetadataKey::RBDS_PTY),
     91               "Metadata key RBDS_PTY mismatch with legacy");
     92 static_assert(RADIO_METADATA_KEY_RDS_RT == static_cast<int>(MetadataKey::RDS_RT),
     93               "Metadata key RDS_RT mismatch with legacy");
     94 static_assert(RADIO_METADATA_KEY_TITLE == static_cast<int>(MetadataKey::TITLE),
     95               "Metadata key TITLE mismatch with legacy");
     96 static_assert(RADIO_METADATA_KEY_ARTIST == static_cast<int>(MetadataKey::ARTIST),
     97               "Metadata key ARTIST mismatch with legacy");
     98 static_assert(RADIO_METADATA_KEY_ALBUM == static_cast<int>(MetadataKey::ALBUM),
     99               "Metadata key ALBUM mismatch with legacy");
    100 static_assert(RADIO_METADATA_KEY_GENRE == static_cast<int>(MetadataKey::GENRE),
    101               "Metadata key GENRE mismatch with legacy");
    102 static_assert(RADIO_METADATA_KEY_ICON == static_cast<int>(MetadataKey::ICON),
    103               "Metadata key ICON mismatch with legacy");
    104 static_assert(RADIO_METADATA_KEY_ART == static_cast<int>(MetadataKey::ART),
    105               "Metadata key ART mismatch with legacy");
    106 static_assert(RADIO_METADATA_KEY_CLOCK == static_cast<int>(MetadataKey::CLOCK),
    107               "Metadata key CLOCK mismatch with legacy");
    108 
    109 
    110 //static
    111 const char * Utils::getClassString(Class ClassId)
    112 {
    113     int id = static_cast<int>(ClassId);
    114 
    115     if ((id < 0) ||
    116             (id >= NELEM(sClassModuleNames))) {
    117         ALOGE("invalid class ID %d", id);
    118         return NULL;
    119     }
    120     return sClassModuleNames[id];
    121 }
    122 
    123 //static
    124 Result Utils::convertHalResult(int rc)
    125 {
    126     switch (rc) {
    127         case 0:
    128             return Result::OK;
    129         case -EINVAL:
    130             return Result::INVALID_ARGUMENTS;
    131         case -ENOSYS:
    132             return Result::INVALID_STATE;
    133         case -ETIMEDOUT:
    134             return Result::TIMEOUT;
    135         case -ENODEV:
    136         default:
    137             return Result::NOT_INITIALIZED;
    138     }
    139 }
    140 
    141 //static
    142 void Utils::convertBandConfigFromHal(
    143         BandConfig *config,
    144         const radio_hal_band_config_t *halConfig)
    145 {
    146 
    147     config->type = static_cast<Band>(halConfig->type);
    148     config->antennaConnected = halConfig->antenna_connected;
    149     config->lowerLimit = halConfig->lower_limit;
    150     config->upperLimit = halConfig->upper_limit;
    151     config->spacings.setToExternal(const_cast<unsigned int *>(&halConfig->spacings[0]),
    152                                        halConfig->num_spacings * sizeof(uint32_t));
    153     // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    154     config->spacings.resize(halConfig->num_spacings);
    155 
    156     if (config->type == Band::FM) {
    157         config->ext.fm.deemphasis = static_cast<Deemphasis>(halConfig->fm.deemphasis);
    158         config->ext.fm.stereo = halConfig->fm.stereo;
    159         config->ext.fm.rds = static_cast<Rds>(halConfig->fm.rds);
    160         config->ext.fm.ta = halConfig->fm.ta;
    161         config->ext.fm.af = halConfig->fm.af;
    162         config->ext.fm.ea = halConfig->fm.ea;
    163     } else {
    164         config->ext.am.stereo = halConfig->am.stereo;
    165     }
    166 }
    167 
    168 //static
    169 void Utils::convertPropertiesFromHal(
    170         Properties *properties,
    171         const radio_hal_properties_t *halProperties)
    172 {
    173     properties->classId = static_cast<Class>(halProperties->class_id);
    174     properties->implementor.setToExternal(halProperties->implementor, strlen(halProperties->implementor));
    175     properties->product.setToExternal(halProperties->product, strlen(halProperties->product));
    176     properties->version.setToExternal(halProperties->version, strlen(halProperties->version));
    177     properties->serial.setToExternal(halProperties->serial, strlen(halProperties->serial));
    178     properties->numTuners = halProperties->num_tuners;
    179     properties->numAudioSources = halProperties->num_audio_sources;
    180     properties->supportsCapture = halProperties->supports_capture;
    181 
    182     BandConfig *bands =
    183             new BandConfig[halProperties->num_bands];
    184     for (size_t i = 0; i < halProperties->num_bands; i++) {
    185         convertBandConfigFromHal(&bands[i], &halProperties->bands[i]);
    186     }
    187     properties->bands.setToExternal(bands, halProperties->num_bands);
    188     // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    189     properties->bands.resize(halProperties->num_bands);
    190     delete[] bands;
    191 }
    192 
    193 //static
    194 void Utils::convertBandConfigToHal(
    195         radio_hal_band_config_t *halConfig,
    196         const BandConfig *config)
    197 {
    198 
    199     halConfig->type = static_cast<radio_band_t>(config->type);
    200     halConfig->antenna_connected = config->antennaConnected;
    201     halConfig->lower_limit = config->lowerLimit;
    202     halConfig->upper_limit = config->upperLimit;
    203     halConfig->num_spacings = config->spacings.size();
    204     if (halConfig->num_spacings > RADIO_NUM_SPACINGS_MAX) {
    205         halConfig->num_spacings = RADIO_NUM_SPACINGS_MAX;
    206     }
    207     memcpy(halConfig->spacings, config->spacings.data(),
    208            sizeof(uint32_t) * halConfig->num_spacings);
    209 
    210     if (config->type == Band::FM) {
    211         halConfig->fm.deemphasis = static_cast<radio_deemphasis_t>(config->ext.fm.deemphasis);
    212         halConfig->fm.stereo = config->ext.fm.stereo;
    213         halConfig->fm.rds = static_cast<radio_rds_t>(config->ext.fm.rds);
    214         halConfig->fm.ta = config->ext.fm.ta;
    215         halConfig->fm.af = config->ext.fm.af;
    216         halConfig->fm.ea = config->ext.fm.ea;
    217     } else {
    218         halConfig->am.stereo = config->ext.am.stereo;
    219     }
    220 }
    221 
    222 
    223 //static
    224 void Utils::convertProgramInfoFromHal(ProgramInfo *info,
    225                                       radio_program_info_t *halInfo)
    226 {
    227     info->channel = halInfo->channel;
    228     info->subChannel = halInfo->sub_channel;
    229     info->tuned = halInfo->tuned;
    230     info->stereo = halInfo->stereo;
    231     info->digital = halInfo->digital;
    232     info->signalStrength = halInfo->signal_strength;
    233     convertMetaDataFromHal(info->metadata, halInfo->metadata);
    234 }
    235 
    236 //static
    237 int Utils::convertMetaDataFromHal(hidl_vec<MetaData>& metadata,
    238                                    radio_metadata_t *halMetadata)
    239 {
    240     if (halMetadata == NULL) {
    241         ALOGE("Invalid argument: halMetadata is NULL");
    242         return 0;
    243     }
    244 
    245     int count = radio_metadata_get_count(halMetadata);
    246     if (count <= 0) {
    247         return count;
    248     }
    249     MetaData *newMetadata =
    250             new MetaData[count];
    251     int outCount = 0;
    252     for (int i = 0; i < count; i++) {
    253         radio_metadata_key_t key;
    254         radio_metadata_type_t type;
    255         void *value;
    256         size_t size;
    257         if (radio_metadata_get_at_index(halMetadata, i , &key, &type, &value, &size) != 0 ||
    258                 size == 0) {
    259             continue;
    260         }
    261         switch (type) {
    262             case RADIO_METADATA_TYPE_INT: {
    263                 newMetadata[outCount].intValue = *(static_cast<int32_t *>(value));
    264             } break;
    265             case RADIO_METADATA_TYPE_TEXT: {
    266                 newMetadata[outCount].stringValue = static_cast<char *>(value);
    267             } break;
    268             case RADIO_METADATA_TYPE_RAW: {
    269                 newMetadata[outCount].rawValue.setToExternal(static_cast<uint8_t *>(value), size);
    270                 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    271                 newMetadata[outCount].rawValue.resize(size);
    272             } break;
    273             case RADIO_METADATA_TYPE_CLOCK: {
    274                   radio_metadata_clock_t *clock = static_cast<radio_metadata_clock_t *>(value);
    275                   newMetadata[outCount].clockValue.utcSecondsSinceEpoch =
    276                           clock->utc_seconds_since_epoch;
    277                   newMetadata[outCount].clockValue.timezoneOffsetInMinutes =
    278                           clock->timezone_offset_in_minutes;
    279             } break;
    280         }
    281         newMetadata[outCount].type = static_cast<MetadataType>(type);
    282         newMetadata[outCount].key = static_cast<MetadataKey>(key);
    283         outCount++;
    284     }
    285     metadata.setToExternal(newMetadata, outCount);
    286     // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    287     metadata.resize(outCount);
    288     return outCount;
    289 }
    290 
    291 } // namespace implementation
    292 }  // namespace V1_0
    293 }  // namespace broadcastradio
    294 }  // namespace hardware
    295 }  // namespace android
    296