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
tirimbino
stenkinevgeniy 7 years ago committed by Jan Altensen
parent 8b57320848
commit b81e05fb36
No known key found for this signature in database
GPG Key ID: 3E45BB95F7AD33DA
  1. 63
      audio/audio_hw.c

@ -985,6 +985,67 @@ int disable_snd_device(struct audio_device *adev,
return 0; 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, static int select_devices(struct audio_device *adev,
audio_usecase_t uc_id) audio_usecase_t uc_id)
{ {
@ -1084,10 +1145,12 @@ static int select_devices(struct audio_device *adev,
set_voice_session_audio_path(adev->voice.session); 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); enable_snd_device(adev, usecase, out_snd_device);
} }
if (in_snd_device != SND_DEVICE_NONE) { 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); enable_snd_device(adev, usecase, in_snd_device);
} }

Loading…
Cancel
Save