QC audio HAL handles device rotation
Use the "speaker-reverse" configuration when the device rotation
requires it. Device rotation is received through a parameter to
parse.
Bug 9095903
Change-Id: Ie24a625a18e1fc1093f6f564ba0ff0f5cbb5cce0
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index c874aa8..7eef1f7 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -87,6 +87,7 @@
/* Playback sound devices */
[SND_DEVICE_OUT_HANDSET] = "handset",
[SND_DEVICE_OUT_SPEAKER] = "speaker",
+ [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
[SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
@@ -131,6 +132,7 @@
[SND_DEVICE_NONE] = -1,
[SND_DEVICE_OUT_HANDSET] = 7,
[SND_DEVICE_OUT_SPEAKER] = 14,
+ [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
@@ -568,7 +570,11 @@
devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_OUT_HEADPHONES;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
- snd_device = SND_DEVICE_OUT_SPEAKER;
+ if (adev->speaker_lr_swap) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
+ } else {
+ snd_device = SND_DEVICE_OUT_SPEAKER;
+ }
} else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
snd_device = SND_DEVICE_OUT_BT_SCO;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
@@ -1839,6 +1845,7 @@
struct str_parms *parms;
char *str;
char value[32];
+ int val;
int ret;
ALOGD("%s: enter: %s", __func__, kvpairs);
@@ -1888,6 +1895,40 @@
adev->screen_off = true;
}
+ ret = str_parms_get_int(parms, "rotation", &val);
+ if (ret >= 0) {
+ bool reverse_speakers = false;
+ switch(val) {
+ // FIXME: note that the code below assumes that the speakers are in the correct placement
+ // relative to the user when the device is rotated 90deg from its default rotation. This
+ // assumption is device-specific, not platform-specific like this code.
+ case 270:
+ reverse_speakers = true;
+ break;
+ case 0:
+ case 90:
+ case 180:
+ break;
+ default:
+ ALOGE("%s: unexpected rotation of %d", __func__, val);
+ }
+ pthread_mutex_lock(&adev->lock);
+ if (adev->speaker_lr_swap != reverse_speakers) {
+ adev->speaker_lr_swap = reverse_speakers;
+ // only update the selected device if there is active pcm playback
+ struct audio_usecase *usecase;
+ struct listnode *node;
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_PLAYBACK) {
+ select_devices(adev, usecase->id);
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&adev->lock);
+ }
+
str_parms_destroy(parms);
ALOGD("%s: exit with code(%d)", __func__, ret);
return ret;
@@ -2264,6 +2305,7 @@
adev->bluetooth_nrec = true;
adev->in_call = false;
adev->acdb_settings = TTY_MODE_OFF;
+ adev->speaker_lr_swap = false;
for (i = 0; i < SND_DEVICE_MAX; i++) {
adev->snd_dev_ref_cnt[i] = 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index cb2f817..08426de 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -51,6 +51,7 @@
SND_DEVICE_OUT_BEGIN = SND_DEVICE_MIN,
SND_DEVICE_OUT_HANDSET = SND_DEVICE_OUT_BEGIN,
SND_DEVICE_OUT_SPEAKER,
+ SND_DEVICE_OUT_SPEAKER_REVERSE,
SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_VOICE_SPEAKER,
@@ -253,6 +254,7 @@
struct listnode usecase_list;
struct audio_route *audio_route;
int acdb_settings;
+ bool speaker_lr_swap;
bool mic_type_analog;
bool fluence_in_spkr_mode;