Revert "Revert "broadcast radio: initial support for HIDL HAL""
This reverts commit 9a24e9127481b222c338dcbecef8394eaf899d51.
diff --git a/services/radio/HidlUtils.cpp b/services/radio/HidlUtils.cpp
new file mode 100644
index 0000000..bfced7a
--- /dev/null
+++ b/services/radio/HidlUtils.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "HidlUtils"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/misc.h>
+#include <system/radio_metadata.h>
+
+#include "HidlUtils.h"
+
+namespace android {
+
+using android::hardware::broadcastradio::V1_0::MetadataType;
+using android::hardware::broadcastradio::V1_0::Band;
+using android::hardware::broadcastradio::V1_0::Deemphasis;
+using android::hardware::broadcastradio::V1_0::Rds;
+
+//static
+int HidlUtils::convertHalResult(Result result)
+{
+ switch (result) {
+ case Result::OK:
+ return 0;
+ case Result::INVALID_ARGUMENTS:
+ return -EINVAL;
+ case Result::INVALID_STATE:
+ return -ENOSYS;
+ case Result::TIMEOUT:
+ return -ETIMEDOUT;
+ case Result::NOT_INITIALIZED:
+ default:
+ return -ENODEV;
+ }
+}
+
+
+//static
+void HidlUtils::convertBandConfigToHal(BandConfig *halConfig,
+ const radio_hal_band_config_t *config)
+{
+ halConfig->type = static_cast<Band>(config->type);
+ halConfig->antennaConnected = config->antenna_connected;
+ halConfig->lowerLimit = config->lower_limit;
+ halConfig->upperLimit = config->upper_limit;
+ halConfig->spacings.setToExternal(const_cast<unsigned int *>(&config->spacings[0]),
+ config->num_spacings * sizeof(uint32_t));
+ // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
+ halConfig->spacings.resize(config->num_spacings);
+
+ if (halConfig->type == Band::FM) {
+ halConfig->ext.fm.deemphasis = static_cast<Deemphasis>(config->fm.deemphasis);
+ halConfig->ext.fm.stereo = config->fm.stereo;
+ halConfig->ext.fm.rds = static_cast<Rds>(config->fm.rds);
+ halConfig->ext.fm.ta = config->fm.ta;
+ halConfig->ext.fm.af = config->fm.af;
+ halConfig->ext.fm.ea = config->fm.ea;
+ } else {
+ halConfig->ext.am.stereo = config->am.stereo;
+ }
+}
+
+//static
+void HidlUtils::convertPropertiesFromHal(radio_hal_properties_t *properties,
+ const Properties *halProperties)
+{
+ properties->class_id = static_cast<radio_class_t>(halProperties->classId);
+ strlcpy(properties->implementor, halProperties->implementor.c_str(), RADIO_STRING_LEN_MAX);
+ strlcpy(properties->product, halProperties->product.c_str(), RADIO_STRING_LEN_MAX);
+ strlcpy(properties->version, halProperties->version.c_str(), RADIO_STRING_LEN_MAX);
+ strlcpy(properties->serial, halProperties->serial.c_str(), RADIO_STRING_LEN_MAX);
+ properties->num_tuners = halProperties->numTuners;
+ properties->num_audio_sources = halProperties->numAudioSources;
+ properties->supports_capture = halProperties->supportsCapture;
+ properties->num_bands = halProperties->bands.size();
+
+ for (size_t i = 0; i < halProperties->bands.size(); i++) {
+ convertBandConfigFromHal(&properties->bands[i], &halProperties->bands[i]);
+ }
+}
+
+//static
+void HidlUtils::convertBandConfigFromHal(radio_hal_band_config_t *config,
+ const BandConfig *halConfig)
+{
+ config->type = static_cast<radio_band_t>(halConfig->type);
+ config->antenna_connected = halConfig->antennaConnected;
+ config->lower_limit = halConfig->lowerLimit;
+ config->upper_limit = halConfig->upperLimit;
+ config->num_spacings = halConfig->spacings.size();
+ if (config->num_spacings > RADIO_NUM_SPACINGS_MAX) {
+ config->num_spacings = RADIO_NUM_SPACINGS_MAX;
+ }
+ memcpy(config->spacings, halConfig->spacings.data(),
+ sizeof(uint32_t) * config->num_spacings);
+
+ if (halConfig->type == Band::FM) {
+ config->fm.deemphasis = static_cast<radio_deemphasis_t>(halConfig->ext.fm.deemphasis);
+ config->fm.stereo = halConfig->ext.fm.stereo;
+ config->fm.rds = static_cast<radio_rds_t>(halConfig->ext.fm.rds);
+ config->fm.ta = halConfig->ext.fm.ta;
+ config->fm.af = halConfig->ext.fm.af;
+ config->fm.ea = halConfig->ext.fm.ea;
+ } else {
+ config->am.stereo = halConfig->ext.am.stereo;
+ }
+}
+
+
+//static
+void HidlUtils::convertProgramInfoFromHal(radio_program_info_t *info,
+ const ProgramInfo *halInfo,
+ bool withMetadata)
+{
+ info->channel = halInfo->channel;
+ info->sub_channel = halInfo->subChannel;
+ info->tuned = halInfo->tuned;
+ info->stereo = halInfo->stereo;
+ info->digital = halInfo->digital;
+ info->signal_strength = halInfo->signalStrength;
+ if (withMetadata && halInfo->metadata.size() != 0) {
+ convertMetaDataFromHal(&info->metadata, halInfo->metadata,
+ halInfo->channel, halInfo->subChannel);
+ }
+}
+
+//static
+void HidlUtils::convertMetaDataFromHal(radio_metadata_t **metadata,
+ const hidl_vec<MetaData>& halMetadata,
+ uint32_t channel,
+ uint32_t subChannel)
+{
+
+ radio_metadata_allocate(metadata, channel, subChannel);
+ for (size_t i = 0; i < halMetadata.size(); i++) {
+ radio_metadata_key_t key = static_cast<radio_metadata_key_t>(halMetadata[i].key);
+ radio_metadata_type_t type = static_cast<radio_metadata_key_t>(halMetadata[i].type);
+ radio_metadata_clock_t clock;
+
+ switch (type) {
+ case RADIO_METADATA_TYPE_INT:
+ radio_metadata_add_int(metadata, key, halMetadata[i].intValue);
+ break;
+ case RADIO_METADATA_TYPE_TEXT:
+ radio_metadata_add_text(metadata, key, halMetadata[i].stringValue.c_str());
+ break;
+ case RADIO_METADATA_TYPE_RAW:
+ radio_metadata_add_raw(metadata, key,
+ halMetadata[i].rawValue.data(),
+ halMetadata[i].rawValue.size());
+ break;
+ case RADIO_METADATA_TYPE_CLOCK:
+ clock.utc_seconds_since_epoch =
+ halMetadata[i].clockValue.utcSecondsSinceEpoch;
+ clock.timezone_offset_in_minutes =
+ halMetadata[i].clockValue.timezoneOffsetInMinutes;
+ radio_metadata_add_clock(metadata, key, &clock);
+ break;
+ default:
+ ALOGW("%s invalid metadata type %u",__FUNCTION__, halMetadata[i].type);
+ break;
+ }
+ }
+}
+
+} // namespace android