Merge 26e29974ac3464debba03fe61800ca243945c6a3 on remote branch

Change-Id: I9e1b6b95a297bba2a8d2655c385ae5bcbfda9544
diff --git a/service/Android.mk b/service/Android.mk
index 50bf4d2..9af7423 100644
--- a/service/Android.mk
+++ b/service/Android.mk
@@ -69,5 +69,9 @@
 LOCAL_HEADER_LIBRARIES += libaudiologutils_headers
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DEVICE_PREPARE_SEQ)), true)
+    LOCAL_CFLAGS += -DENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+endif
+
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/service/src/session_obj.c b/service/src/session_obj.c
index 1319543..1c21eeb 100644
--- a/service/src/session_obj.c
+++ b/service/src/session_obj.c
@@ -964,6 +964,9 @@
 {
     int ret = 0;
     struct aif *aif_obj = NULL;
+#ifdef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+    enum direction dir = sess_obj->stream_config.dir;
+#endif
     enum agm_session_mode sess_mode = sess_obj->stream_config.sess_mode;
     struct listnode *node = NULL;
     uint32_t count = 0;
@@ -988,8 +991,36 @@
             if (ret)
                 goto done;
         }
+#ifdef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+        if ((dir == TX) && (sess_obj->state != SESSION_STARTED)) {
+            ret = graph_prepare(sess_obj->graph);
+            if (ret) {
+                AGM_LOGE("Error:%d preparing graph\n", ret);
+                goto done;
+            }
+        }
 
+        list_for_each(node, &sess_obj->aif_pool) {
+            aif_obj = node_to_item(node, struct aif, node);
+            if (!aif_obj) {
+                AGM_LOGE("Error:%d could not find aif node\n", ret);
+                goto done;
+            }
+            //TODO 1: in device switch cases, only the aif not prepared
+            //should be prepared.
+            if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
+                ret = device_prepare(aif_obj->dev_obj);
+                if (ret) {
+                    AGM_LOGE("Error:%d preparing device\n", ret);
+                    goto done;
+                }
+                aif_obj->state = AIF_PREPARED;
+            }
+        }
+        if ((dir == RX) && (sess_obj->state != SESSION_STARTED)) {
+#else
         if ((sess_obj->state != SESSION_STARTED)) {
+#endif
             pthread_mutex_lock(&hwep_lock);
             ret = graph_prepare(sess_obj->graph);
             pthread_mutex_unlock(&hwep_lock);
@@ -1080,7 +1111,17 @@
                     goto done;
                 }
             }
+#ifndef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
         }
+#endif
+            ret = graph_start(sess_obj->graph);
+            if (ret) {
+                AGM_LOGE("Error:%d starting graph\n", ret);
+                goto done;
+            }
+#ifdef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+        }
+#endif
 
         pthread_mutex_lock(&hwep_lock);
 
@@ -1137,7 +1178,7 @@
                 (aif_obj->dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
                 continue;
             }
-
+#ifndef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
             if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
                 ret = device_prepare(aif_obj->dev_obj);
                 if (ret) {
@@ -1147,7 +1188,7 @@
                 }
                 aif_obj->state = AIF_PREPARED;
             }
-
+#endif
             if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_PREPARED ||
                                                  aif_obj->state == AIF_STOPPED ) {
                 ret = device_start(aif_obj->dev_obj);
@@ -1160,6 +1201,15 @@
                 aif_obj->state = AIF_STARTED;
             }
         }
+#ifdef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+        if (dir == RX) {
+            ret = graph_start(sess_obj->graph);
+            if (ret) {
+                AGM_LOGE("Error:%d starting graph\n", ret);
+                goto unwind;
+            }
+        }
+#endif
         pthread_mutex_unlock(&hwep_lock);
     } else {
         ret = graph_start(sess_obj->graph);
@@ -1174,7 +1224,10 @@
 
 unwind:
     pthread_mutex_lock(&hwep_lock);
-    graph_stop(sess_obj->graph, NULL);
+#ifdef ENABLE_DEV_PREPARE_BEFORE_GRAPH_START_SEQ
+    if (dir == TX)
+#endif
+        graph_stop(sess_obj->graph, NULL);
 device_stop:
     if (sess_mode != AGM_SESSION_NON_TUNNEL  && sess_mode != AGM_SESSION_NO_CONFIG) {
         list_for_each(node, &sess_obj->aif_pool) {