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