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 "HidlUtils"
17 //#define LOG_NDEBUG 0
18
19 #include <utils/Log.h>
20 #include <utils/misc.h>
21 #include <system/radio_metadata.h>
22
23 #include "HidlUtils.h"
24
25 namespace android {
26
27 using android::hardware::broadcastradio::V1_0::MetadataType;
28 using android::hardware::broadcastradio::V1_0::Band;
29 using android::hardware::broadcastradio::V1_0::Deemphasis;
30 using android::hardware::broadcastradio::V1_0::Rds;
31
32 //static
convertHalResult(Result result)33 int HidlUtils::convertHalResult(Result result)
34 {
35 switch (result) {
36 case Result::OK:
37 return 0;
38 case Result::INVALID_ARGUMENTS:
39 return -EINVAL;
40 case Result::INVALID_STATE:
41 return -ENOSYS;
42 case Result::TIMEOUT:
43 return -ETIMEDOUT;
44 case Result::NOT_INITIALIZED:
45 default:
46 return -ENODEV;
47 }
48 }
49
50
51 //static
convertBandConfigToHal(BandConfig * halConfig,const radio_hal_band_config_t * config)52 void HidlUtils::convertBandConfigToHal(BandConfig *halConfig,
53 const radio_hal_band_config_t *config)
54 {
55 halConfig->type = static_cast<Band>(config->type);
56 halConfig->antennaConnected = config->antenna_connected;
57 halConfig->lowerLimit = config->lower_limit;
58 halConfig->upperLimit = config->upper_limit;
59 halConfig->spacings.setToExternal(const_cast<unsigned int *>(&config->spacings[0]),
60 config->num_spacings * sizeof(uint32_t));
61 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
62 halConfig->spacings.resize(config->num_spacings);
63
64 if (halConfig->type == Band::FM) {
65 halConfig->ext.fm.deemphasis = static_cast<Deemphasis>(config->fm.deemphasis);
66 halConfig->ext.fm.stereo = config->fm.stereo;
67 halConfig->ext.fm.rds = static_cast<Rds>(config->fm.rds);
68 halConfig->ext.fm.ta = config->fm.ta;
69 halConfig->ext.fm.af = config->fm.af;
70 halConfig->ext.fm.ea = config->fm.ea;
71 } else {
72 halConfig->ext.am.stereo = config->am.stereo;
73 }
74 }
75
76 //static
convertPropertiesFromHal(radio_hal_properties_t * properties,const Properties * halProperties)77 void HidlUtils::convertPropertiesFromHal(radio_hal_properties_t *properties,
78 const Properties *halProperties)
79 {
80 properties->class_id = static_cast<radio_class_t>(halProperties->classId);
81 strlcpy(properties->implementor, halProperties->implementor.c_str(), RADIO_STRING_LEN_MAX);
82 strlcpy(properties->product, halProperties->product.c_str(), RADIO_STRING_LEN_MAX);
83 strlcpy(properties->version, halProperties->version.c_str(), RADIO_STRING_LEN_MAX);
84 strlcpy(properties->serial, halProperties->serial.c_str(), RADIO_STRING_LEN_MAX);
85 properties->num_tuners = halProperties->numTuners;
86 properties->num_audio_sources = halProperties->numAudioSources;
87 properties->supports_capture = halProperties->supportsCapture;
88 properties->num_bands = halProperties->bands.size();
89
90 for (size_t i = 0; i < halProperties->bands.size(); i++) {
91 convertBandConfigFromHal(&properties->bands[i], &halProperties->bands[i]);
92 }
93 }
94
95 //static
convertBandConfigFromHal(radio_hal_band_config_t * config,const BandConfig * halConfig)96 void HidlUtils::convertBandConfigFromHal(radio_hal_band_config_t *config,
97 const BandConfig *halConfig)
98 {
99 config->type = static_cast<radio_band_t>(halConfig->type);
100 config->antenna_connected = halConfig->antennaConnected;
101 config->lower_limit = halConfig->lowerLimit;
102 config->upper_limit = halConfig->upperLimit;
103 config->num_spacings = halConfig->spacings.size();
104 if (config->num_spacings > RADIO_NUM_SPACINGS_MAX) {
105 config->num_spacings = RADIO_NUM_SPACINGS_MAX;
106 }
107 memcpy(config->spacings, halConfig->spacings.data(),
108 sizeof(uint32_t) * config->num_spacings);
109
110 if (halConfig->type == Band::FM) {
111 config->fm.deemphasis = static_cast<radio_deemphasis_t>(halConfig->ext.fm.deemphasis);
112 config->fm.stereo = halConfig->ext.fm.stereo;
113 config->fm.rds = static_cast<radio_rds_t>(halConfig->ext.fm.rds);
114 config->fm.ta = halConfig->ext.fm.ta;
115 config->fm.af = halConfig->ext.fm.af;
116 config->fm.ea = halConfig->ext.fm.ea;
117 } else {
118 config->am.stereo = halConfig->ext.am.stereo;
119 }
120 }
121
122
123 //static
convertProgramInfoFromHal(radio_program_info_t * info,const ProgramInfo * halInfo)124 void HidlUtils::convertProgramInfoFromHal(radio_program_info_t *info,
125 const ProgramInfo *halInfo)
126 {
127 info->channel = halInfo->channel;
128 info->sub_channel = halInfo->subChannel;
129 info->tuned = halInfo->tuned;
130 info->stereo = halInfo->stereo;
131 info->digital = halInfo->digital;
132 info->signal_strength = halInfo->signalStrength;
133 convertMetaDataFromHal(&info->metadata, halInfo->metadata,
134 halInfo->channel, halInfo->subChannel);
135 }
136
137 // TODO(twasilczyk): drop unnecessary channel info
138 //static
convertMetaDataFromHal(radio_metadata_t ** metadata,const hidl_vec<MetaData> & halMetadata,uint32_t channel __unused,uint32_t subChannel __unused)139 void HidlUtils::convertMetaDataFromHal(radio_metadata_t **metadata,
140 const hidl_vec<MetaData>& halMetadata,
141 uint32_t channel __unused,
142 uint32_t subChannel __unused)
143 {
144
145 if (metadata == nullptr || *metadata == nullptr) {
146 ALOGE("destination metadata buffer is a nullptr");
147 return;
148 }
149 for (size_t i = 0; i < halMetadata.size(); i++) {
150 radio_metadata_key_t key = static_cast<radio_metadata_key_t>(halMetadata[i].key);
151 radio_metadata_type_t type = static_cast<radio_metadata_key_t>(halMetadata[i].type);
152 radio_metadata_clock_t clock;
153
154 switch (type) {
155 case RADIO_METADATA_TYPE_INT:
156 radio_metadata_add_int(metadata, key, halMetadata[i].intValue);
157 break;
158 case RADIO_METADATA_TYPE_TEXT:
159 radio_metadata_add_text(metadata, key, halMetadata[i].stringValue.c_str());
160 break;
161 case RADIO_METADATA_TYPE_RAW:
162 radio_metadata_add_raw(metadata, key,
163 halMetadata[i].rawValue.data(),
164 halMetadata[i].rawValue.size());
165 break;
166 case RADIO_METADATA_TYPE_CLOCK:
167 clock.utc_seconds_since_epoch =
168 halMetadata[i].clockValue.utcSecondsSinceEpoch;
169 clock.timezone_offset_in_minutes =
170 halMetadata[i].clockValue.timezoneOffsetInMinutes;
171 radio_metadata_add_clock(metadata, key, &clock);
172 break;
173 default:
174 ALOGW("%s invalid metadata type %u",__FUNCTION__, halMetadata[i].type);
175 break;
176 }
177 }
178 }
179
180 } // namespace android
181