Add features for automotive usecases.
1. Add clock to metadata - If the CAR does not have a clock (no network
or bad clock) then Radio RDS could be used as a proxy.
2. Add support for emergency announcement - If the CAR wants to make an
emergency announcement.
2.1 Add support for callbacks.
Bug: b/24807501
Bug: b/22701655
Change-Id: Ie5ada889bb6dfc4a2c1b02fc1db2d48d6899bcde
(cherry picked from commit 5768372922fbdfa47afef5bb414c69d606e7c1d2)
diff --git a/modules/radio/radio_hw.c b/modules/radio/radio_hw.c
index 9c0f22c..bd9e324 100644
--- a/modules/radio/radio_hw.c
+++ b/modules/radio/radio_hw.c
@@ -58,6 +58,7 @@
.rds = RADIO_RDS_US,
.ta = false,
.af = false,
+ .ea = true,
}
},
{
@@ -74,6 +75,11 @@
}
};
+static const radio_metadata_clock_t hw_clock = {
+ .utc_seconds_since_epoch = 1234567890,
+ .timezone_offset_in_minutes = (-8 * 60),
+};
+
struct stub_radio_tuner {
struct radio_tuner interface;
struct stub_radio_device *dev;
@@ -103,6 +109,7 @@
CMD_TUNE,
CMD_CANCEL,
CMD_METADATA,
+ CMD_ANNOUNCEMENTS,
} thread_cmd_type_t;
struct thread_command {
@@ -215,6 +222,9 @@
ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ICON, BITMAP_FILE_PATH);
if (ret != 0)
goto exit;
+ ret = radio_metadata_add_clock(metadata, RADIO_METADATA_KEY_CLOCK, &hw_clock);
+ if (ret != 0)
+ goto exit;
} else {
ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ART, BITMAP_FILE_PATH);
if (ret != 0)
@@ -251,6 +261,10 @@
pthread_mutex_lock(&tuner->lock);
+ // Fields which are used to toggle the state of traffic announcements and
+ // ea announcements at random. They are access protected by tuner->lock.
+ bool ea_state = false;
+
while (true) {
struct thread_command *cmd = NULL;
struct listnode *item;
@@ -278,7 +292,8 @@
cmd = node_to_item(item, struct thread_command, node);
if (got_cancel && (cmd->type == CMD_STEP || cmd->type == CMD_SCAN ||
- cmd->type == CMD_TUNE || cmd->type == CMD_METADATA)) {
+ cmd->type == CMD_TUNE || cmd->type == CMD_METADATA ||
+ cmd->type == CMD_ANNOUNCEMENTS)) {
list_remove(item);
free(cmd);
continue;
@@ -309,9 +324,11 @@
__func__, tuner->config.type,
tuner->config.lower_limit, tuner->config.upper_limit);
if (tuner->config.type == RADIO_BAND_FM) {
- ALOGV(" - stereo %d\n - rds %d\n - ta %d\n - af %d",
+ ALOGV(" - stereo %d\n - rds %d\n - ta %d\n - af %d\n"
+ " - ea %d\n",
tuner->config.fm.stereo, tuner->config.fm.rds,
- tuner->config.fm.ta, tuner->config.fm.af);
+ tuner->config.fm.ta, tuner->config.fm.af,
+ tuner->config.fm.ea);
} else {
ALOGV(" - stereo %d", tuner->config.am.stereo);
}
@@ -377,7 +394,7 @@
if (tuner->program.tuned) {
prepare_metadata(tuner, &tuner->program.metadata, true);
- send_command_l(tuner, CMD_METADATA, 5000, NULL);
+ send_command_l(tuner, CMD_ANNOUNCEMENTS, 1000, NULL);
} else {
if (tuner->program.metadata != NULL)
radio_metadata_deallocate(tuner->program.metadata);
@@ -408,6 +425,28 @@
got_cancel = true;
} break;
+ // Fire emergency announcements if they are enabled in the config. Stub
+ // implementation simply fires an announcement for 5 second
+ // duration with a gap of 5 seconds.
+ case CMD_ANNOUNCEMENTS: {
+ ALOGV("In annoucements. %d %d %d\n",
+ ea_state, tuner->config.type, tuner->config.fm.ea);
+ if (tuner->config.type == RADIO_BAND_FM ||
+ tuner->config.type == RADIO_BAND_FM_HD) {
+ if (ea_state) {
+ ea_state = false;
+ event.type = RADIO_EVENT_EA;
+ } else if (tuner->config.fm.ea) {
+ ea_state = true;
+ event.type = RADIO_EVENT_EA;
+ }
+ event.on = ea_state;
+
+ if (tuner->config.fm.ea) {
+ send_command_l(tuner, CMD_ANNOUNCEMENTS, 5000, NULL);
+ }
+ }
+ } break;
}
if (event.type != RADIO_EVENT_HW_FAILURE && tuner->callback != NULL) {
pthread_mutex_unlock(&tuner->lock);
@@ -438,7 +477,7 @@
free(cmd);
}
}
- send_command_l(tuner, CMD_METADATA, 100, NULL);
+ send_command_l(tuner, CMD_METADATA, 1000, NULL);
}
}
@@ -472,7 +511,7 @@
}
static int tuner_get_configuration(const struct radio_tuner *tuner,
- radio_hal_band_config_t *config)
+ radio_hal_band_config_t *config)
{
struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;
int status = 0;