summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstenkinevgeniy <stenkinevgeniy@gmail.com>2018-05-08 12:02:35 +0000
committerBasil Gello <vasek.gello@gmail.com>2018-05-24 14:56:46 +0300
commite825e5b84b4b4ab87214d34d837d8e20801e8b86 (patch)
tree01b474babeadd4596e863c95623f4bc056dbe92b
parent54604e243ce9508073b951683a1d4745b55d2c25 (diff)
downloadandroid_hardware_samsung-e825e5b84b4b4ab87214d34d837d8e20801e8b86.tar.gz
android_hardware_samsung-e825e5b84b4b4ab87214d34d837d8e20801e8b86.tar.bz2
android_hardware_samsung-e825e5b84b4b4ab87214d34d837d8e20801e8b86.zip
Audio: check and route usecases
Add check_and_route_usecases - this function is to make sure that all the usecases that are active on the hardware codec backend are always routed to any one device that is handled by the hardware codec. Example: When voice call starting - we need earpice - hal enable earpice, but befor - we put call button - and hal enable speaker and play sound - "click" And now we have speaker and earpice enabled. Later when audioflinger send standby (default after 3 sec) to stream which use speaker - hal disable speaker while voice call active - and we have no sound in earpice. check_and_route_usecases will not allow such situations. Change-Id: Ibc534bb14c25e4a4ffb4f3487d1424e9e1ed6a67
-rw-r--r--audio/audio_hw.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index b017537..761d567 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -1000,6 +1000,67 @@ int disable_snd_device(struct audio_device *adev,
return 0;
}
+static void check_and_route_usecases(struct audio_device *adev,
+ struct audio_usecase *uc_info,
+ usecase_type_t type,
+ snd_device_t snd_device)
+{
+ struct listnode *node;
+ struct audio_usecase *usecase;
+ bool switch_device[AUDIO_USECASE_MAX], need_switch = false;
+ snd_device_t usecase_snd_device = SND_DEVICE_NONE;
+ int i;
+
+ /*
+ * This function is to make sure that all the usecases that are active on
+ * the hardware codec backend are always routed to any one device that is
+ * handled by the hardware codec.
+ * For example, if low-latency and deep-buffer usecases are currently active
+ * on speaker and out_set_parameters(headset) is received on low-latency
+ * output, then we have to make sure deep-buffer is also switched to headset or
+ * if audio-record and voice-call usecases are currently
+ * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
+ * is received for voice call then we have to make sure that audio-record
+ * usecase is also switched to earpiece i.e.
+ * because of the limitation that both the devices cannot be enabled
+ * at the same time as they share the same backend.
+ */
+ /* Disable all the usecases on the shared backend other than the
+ specified usecase */
+ for (i = 0; i < AUDIO_USECASE_MAX; i++)
+ switch_device[i] = false;
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, adev_list_node);
+ if (usecase->type != type || usecase == uc_info)
+ continue;
+ usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
+ usecase->in_snd_device;
+ if (usecase_snd_device != snd_device) {
+ ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
+ __func__, use_case_table[usecase->id],
+ get_snd_device_name(usecase_snd_device));
+ switch_device[usecase->id] = true;
+ need_switch = true;
+ }
+ }
+ if (need_switch) {
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, adev_list_node);
+ usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
+ usecase->in_snd_device;
+ if (switch_device[usecase->id]) {
+ disable_snd_device(adev, usecase, usecase_snd_device);
+ enable_snd_device(adev, usecase, snd_device);
+ if (type == PCM_PLAYBACK)
+ usecase->out_snd_device = snd_device;
+ else
+ usecase->in_snd_device = snd_device;
+ }
+ }
+ }
+}
+
static int select_devices(struct audio_device *adev,
audio_usecase_t uc_id)
{
@@ -1099,10 +1160,12 @@ static int select_devices(struct audio_device *adev,
set_voice_session_audio_path(adev->voice.session);
}
+ check_and_route_usecases(adev, usecase, PCM_PLAYBACK, out_snd_device);
enable_snd_device(adev, usecase, out_snd_device);
}
if (in_snd_device != SND_DEVICE_NONE) {
+ check_and_route_usecases(adev, usecase, PCM_CAPTURE, in_snd_device);
enable_snd_device(adev, usecase, in_snd_device);
}