audio: select camcorder snd device according to camera orientation

Add audio parameter indicating use of front or back camera to select
proper input path tuning in camcorder mode.
Also take device orientation for stereo channel swaping.

Bug: 118022272

Test: verified with camera service patch sending camera facing parameter
Change-Id: If24b47d922aeedaaa144f4a5f4cacddce2c9eeaf
(cherry picked from commit 5f4ca9505df8177127c1f1a7d292d684ec30ff50)
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cc1276b..8e04bf8 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -4717,20 +4717,24 @@
             adev->screen_off = true;
     }
 
-#ifndef MAXXAUDIO_QDSP_ENABLED
     ret = str_parms_get_int(parms, "rotation", &val);
     if (ret >= 0) {
         bool reverse_speakers = false;
+        int camera_rotation = CAMERA_ROTATION_LANDSCAPE;
         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;
+            camera_rotation = CAMERA_ROTATION_INVERT_LANDSCAPE;
             break;
         case 0:
-        case 90:
         case 180:
+            camera_rotation = CAMERA_ROTATION_PORTRAIT;
+            break;
+        case 90:
+            camera_rotation = CAMERA_ROTATION_LANDSCAPE;
             break;
         default:
             ALOGE("%s: unexpected rotation of %d", __func__, val);
@@ -4740,10 +4744,13 @@
             // check and set swap
             //   - check if orientation changed and speaker active
             //   - set rotation and cache the rotation value
+            adev->camera_orientation =
+                           (adev->camera_orientation & ~CAMERA_ROTATION_MASK) | camera_rotation;
+#ifndef MAXXAUDIO_QDSP_ENABLED
             platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
+#endif
         }
     }
-#endif
 
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
     if (ret >= 0) {
@@ -4812,6 +4819,32 @@
         }
     }
 
+    //FIXME: to be replaced by proper video capture properties API
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_CAMERA_FACING, value, sizeof(value));
+    if (ret >= 0) {
+        int camera_facing = CAMERA_FACING_BACK;
+        if (strcmp(value, AUDIO_PARAMETER_VALUE_FRONT) == 0)
+            camera_facing = CAMERA_FACING_FRONT;
+        else if (strcmp(value, AUDIO_PARAMETER_VALUE_BACK) == 0)
+            camera_facing = CAMERA_FACING_BACK;
+        else {
+            ALOGW("%s: invalid camera facing value: %s", __func__, value);
+            goto done;
+        }
+        adev->camera_orientation =
+                       (adev->camera_orientation & ~CAMERA_FACING_MASK) | camera_facing;
+        struct audio_usecase *usecase;
+        struct listnode *node;
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            struct stream_in *in = usecase->stream.in;
+            if (usecase->type == PCM_CAPTURE && in != NULL &&
+                    in->source == AUDIO_SOURCE_CAMCORDER && !in->standby) {
+                select_devices(adev, in->usecase);
+            }
+        }
+    }
+
 done:
     str_parms_destroy(parms);
     pthread_mutex_unlock(&adev->lock);
@@ -5720,6 +5753,8 @@
 
     adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
 
+    adev->camera_orientation = CAMERA_DEFAULT;
+
     // commented as full set of app type cfg is sent from platform
     // audio_extn_utils_send_default_app_type_cfg(adev->platform, adev->mixer);
     audio_device_ref_count++;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 6379844..0b3b028 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -159,6 +159,33 @@
     OFFLOAD_CMD_ERROR,              /* offload playback hit some error */
 };
 
+/*
+ * Camera selection indicated via set_parameters "cameraFacing=front|back and
+ * "rotation=0|90|180|270""
+ */
+enum {
+  CAMERA_FACING_BACK = 0x0,
+  CAMERA_FACING_FRONT = 0x1,
+  CAMERA_FACING_MASK = 0x0F,
+  CAMERA_ROTATION_LANDSCAPE = 0x0,
+  CAMERA_ROTATION_INVERT_LANDSCAPE = 0x10,
+  CAMERA_ROTATION_PORTRAIT = 0x20,
+  CAMERA_ROTATION_MASK = 0xF0,
+  CAMERA_BACK_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_LANDSCAPE),
+  CAMERA_BACK_INVERT_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_INVERT_LANDSCAPE),
+  CAMERA_BACK_PORTRAIT = (CAMERA_FACING_BACK|CAMERA_ROTATION_PORTRAIT),
+  CAMERA_FRONT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_LANDSCAPE),
+  CAMERA_FRONT_INVERT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_INVERT_LANDSCAPE),
+  CAMERA_FRONT_PORTRAIT = (CAMERA_FACING_FRONT|CAMERA_ROTATION_PORTRAIT),
+
+  CAMERA_DEFAULT = CAMERA_BACK_LANDSCAPE,
+};
+
+//FIXME: to be replaced by proper video capture properties API
+#define AUDIO_PARAMETER_KEY_CAMERA_FACING "cameraFacing"
+#define AUDIO_PARAMETER_VALUE_FRONT "front"
+#define AUDIO_PARAMETER_VALUE_BACK "back"
+
 enum {
     OFFLOAD_STATE_IDLE,
     OFFLOAD_STATE_PLAYING,
@@ -309,6 +336,7 @@
 
 struct audio_device {
     struct audio_hw_device device;
+
     pthread_mutex_t lock; /* see note below on mutex acquisition order */
     struct mixer *mixer;
     audio_mode_t mode;
@@ -367,6 +395,7 @@
 
     /* logging */
     snd_device_t last_logged_snd_device[AUDIO_USECASE_MAX][2]; /* [out, in] */
+    int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index a3462d1..4a4e997 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -316,7 +316,7 @@
     [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
     [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
-    [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = "camcorder-mic",
 
     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
@@ -358,6 +358,11 @@
     [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
     [SND_DEVICE_IN_HANDSET_TMIC_AEC] = "three-mic",
     [SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
+    [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
 };
 
 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -434,7 +439,7 @@
     [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 21,
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
     [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 38,
-    [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
+    [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = 61,
 
     [SND_DEVICE_IN_VOICE_DMIC] = 41,
     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
@@ -475,6 +480,11 @@
     [SND_DEVICE_IN_HANDSET_QMIC] = 125,
     [SND_DEVICE_IN_HANDSET_TMIC_AEC] = 125, /* override this for new target to 140 */
     [SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125, /* override this for new target to 140 */
+    [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = 61,
+    [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = 61,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = 61,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = 61,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
 };
 
 // Platform specific backend bit width table
@@ -562,7 +572,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
-    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_LANDSCAPE)},
 
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
@@ -603,6 +613,13 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_PORTRAIT)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
+    /* For legacy xml file parsing */
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1292,7 +1309,7 @@
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_AEC] = strdup("SLIMBUS_0_TX");
-    hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC] = strdup("SLIMBUS_0_TX");
@@ -1334,6 +1351,11 @@
     hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_TMIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC_AEC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_PORTRAIT] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX");
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 }
 
@@ -2939,7 +2961,30 @@
     } else if (source == AUDIO_SOURCE_CAMCORDER) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-            snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
+            switch (adev->camera_orientation) {
+            case CAMERA_BACK_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+                break;
+            case CAMERA_BACK_INVERT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE;
+                break;
+            case CAMERA_BACK_PORTRAIT:
+                snd_device = SND_DEVICE_IN_CAMCORDER_PORTRAIT;
+                break;
+            case CAMERA_FRONT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE;
+                break;
+            case CAMERA_FRONT_INVERT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE;
+                break;
+            case CAMERA_FRONT_PORTRAIT:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT;
+                break;
+            default:
+                ALOGW("%s: invalid camera orientation %08x", __func__, adev->camera_orientation);
+                snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+                break;
+            }
         }
     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 8661fad..911a782 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -141,7 +141,7 @@
     SND_DEVICE_IN_BT_SCO_MIC_NREC,
     SND_DEVICE_IN_BT_SCO_MIC_WB,
     SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
-    SND_DEVICE_IN_CAMCORDER_MIC,
+    SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
 
     SND_DEVICE_IN_VOICE_DMIC,
     SND_DEVICE_IN_VOICE_DMIC_TMUS,
@@ -184,10 +184,16 @@
     SND_DEVICE_IN_HANDSET_QMIC,
     SND_DEVICE_IN_HANDSET_TMIC_AEC,
     SND_DEVICE_IN_HANDSET_QMIC_AEC,
+    SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_PORTRAIT,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
-
+    /* For legacy xml file parsing */
+    SND_DEVICE_IN_CAMCORDER_MIC = SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
 };
 #define DEFAULT_OUTPUT_SAMPLING_RATE    48000
 #define OUTPUT_SAMPLING_RATE_44100      44100