hal: Standby low-latency i/p stream with routing updates

Standby input stream with the following scenarios:
- Input routing changes for low latency capture
- In_focus for low latency capture cannot be
acquired due to system call failure in libadm.

Change-Id: If5dc33d90b0871e2b8cf70944bba95d72dec4927
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index bc74132..fcb1d89 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -583,14 +583,19 @@
         adev->adm_request_focus(adev->adm_data, out->handle);
 }
 
-static void request_in_focus(struct stream_in *in, long ns)
+static int request_in_focus(struct stream_in *in, long ns)
 {
     struct audio_device *adev = in->dev;
+    int ret = 0;
 
-    if (adev->adm_request_focus_v2)
+    if (adev->adm_request_focus_v2_1)
+        ret = adev->adm_request_focus_v2_1(adev->adm_data, in->capture_handle, ns);
+    else if (adev->adm_request_focus_v2)
         adev->adm_request_focus_v2(adev->adm_data, in->capture_handle, ns);
     else if (adev->adm_request_focus)
         adev->adm_request_focus(adev->adm_data, in->capture_handle);
+
+    return ret;
 }
 
 static void release_out_focus(struct stream_out *out)
@@ -6146,6 +6151,8 @@
                         adev->adm_on_routing_change(adev->adm_data,
                                                     in->capture_handle);
                         ret = select_devices(adev, in->usecase);
+                        if (in->usecase == USECASE_AUDIO_RECORD_LOW_LATENCY)
+                            adev->adm_routing_changed = true;
                     }
                 }
             }
@@ -6279,6 +6286,12 @@
         goto exit;
     }
 
+    if (in->usecase == USECASE_AUDIO_RECORD_LOW_LATENCY &&
+        !in->standby && adev->adm_routing_changed) {
+        ret = -ENOSYS;
+        goto exit;
+    }
+
     if (in->standby) {
         pthread_mutex_lock(&adev->lock);
         if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
@@ -6301,7 +6314,9 @@
         ns = pcm_bytes_to_frames(in->pcm, bytes)*1000000000LL/
                                              in->config.rate;
 
-    request_in_focus(in, ns);
+    ret = request_in_focus(in, ns);
+    if (ret != 0)
+        goto exit;
     bool use_mmap = is_mmap_usecase(in->usecase) || in->realtime;
 
     if (audio_extn_cin_attached_usecase(in->usecase)) {
@@ -6370,6 +6385,8 @@
             memset(buffer, 0, bytes);
         }
         in_standby(&in->stream.common);
+        if (in->usecase == USECASE_AUDIO_RECORD_LOW_LATENCY)
+            adev->adm_routing_changed = false;
         ALOGV("%s: read failed status %d- sleeping for buffer duration", __func__, ret);
         usleep((uint64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
                                    in_get_sample_rate(&in->stream.common));
@@ -9138,6 +9155,7 @@
     adev->dsp_bit_width_enforce_mode = 0;
     adev->enable_hfp = false;
     adev->use_old_pspd_mix_ctrl = false;
+    adev->adm_routing_changed = false;
 
     /* Loads platform specific libraries dynamically */
     adev->platform = platform_init(adev);
@@ -9249,6 +9267,8 @@
                                     dlsym(adev->adm_lib, "adm_is_noirq_avail");
             adev->adm_on_routing_change = (adm_on_routing_change_t)
                                     dlsym(adev->adm_lib, "adm_on_routing_change");
+            adev->adm_request_focus_v2_1 = (adm_request_focus_v2_1_t)
+                                    dlsym(adev->adm_lib, "adm_request_focus_v2_1");
         }
     }
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 0b904bd..9a93ed7 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -531,6 +531,7 @@
 typedef void (*adm_request_focus_v2_t)(void *, audio_io_handle_t, long);
 typedef bool (*adm_is_noirq_avail_t)(void *, int, int, int);
 typedef void (*adm_on_routing_change_t)(void *, audio_io_handle_t);
+typedef int (*adm_request_focus_v2_1_t)(void *, audio_io_handle_t, long);
 
 struct audio_device {
     struct audio_hw_device device;
@@ -600,6 +601,7 @@
     adm_request_focus_v2_t adm_request_focus_v2;
     adm_is_noirq_avail_t adm_is_noirq_avail;
     adm_on_routing_change_t adm_on_routing_change;
+    adm_request_focus_v2_1_t adm_request_focus_v2_1;
 
     void (*offload_effects_get_parameters)(struct str_parms *,
                                            struct str_parms *);
@@ -640,6 +642,7 @@
     struct listnode active_outputs_list;
     bool use_old_pspd_mix_ctrl;
     int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
+    bool adm_routing_changed;
 };
 
 int select_devices(struct audio_device *adev,