audio policy: concurrent capture effects

Add pre processing effect management for concurrent capture scenarii.
When several clients on the same input stream have enabled audio effects,
only the effects attached to the top priotity client are active.
Other effects are suspended.

Add AudioFlinger API to suspend/restore audio effects build on top
of exisiting internal effect suspend mechanism.

RecordThread now supports more than one effect chain.

AOSP pre processing implementation supports more than one effect session
per input.

Refactor AudioPolicyManager::closeAllInputs() to call closeInput() on
all inputs instead of partially duplicated code.

Bug: 128419018
Test: make
Change-Id: I685286da4c2905a8894a4354679f9787b1400621
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 825cd4e..dd95e34 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -89,6 +89,7 @@
     GET_MICROPHONES,
     SET_MASTER_BALANCE,
     GET_MASTER_BALANCE,
+    SET_EFFECT_SUSPENDED,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -718,6 +719,18 @@
         return reply.readInt32();
     }
 
+    virtual void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeInt32(effectId);
+        data.writeInt32(sessionId);
+        data.writeInt32(suspended ? 1 : 0);
+        remote()->transact(SET_EFFECT_SUSPENDED, data, &reply);
+    }
+
     virtual audio_module_handle_t loadHwModule(const char *name)
     {
         Parcel data, reply;
@@ -913,6 +926,7 @@
         case INVALIDATE_STREAM:
         case SET_VOICE_VOLUME:
         case MOVE_EFFECTS:
+        case SET_EFFECT_SUSPENDED:
         case LOAD_HW_MODULE:
         case LIST_AUDIO_PORTS:
         case GET_AUDIO_PORT:
@@ -926,6 +940,7 @@
             // return status only for non void methods
             switch (code) {
                 case SET_RECORD_SILENCED:
+                case SET_EFFECT_SUSPENDED:
                     break;
                 default:
                     reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
@@ -1371,6 +1386,14 @@
             reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
             return NO_ERROR;
         } break;
+        case SET_EFFECT_SUSPENDED: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            int effectId = data.readInt32();
+            audio_session_t sessionId = (audio_session_t) data.readInt32();
+            bool suspended = data.readInt32() == 1;
+            setEffectSuspended(effectId, sessionId, suspended);
+            return NO_ERROR;
+        } break;
         case LOAD_HW_MODULE: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32(loadHwModule(data.readCString()));
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index ef0ed0c..dcc18b6 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -457,6 +457,10 @@
     virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
                                     audio_io_handle_t dstOutput) = 0;
 
+    virtual void setEffectSuspended(int effectId,
+                                    audio_session_t sessionId,
+                                    bool suspended) = 0;
+
     virtual audio_module_handle_t loadHwModule(const char *name) = 0;
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 50c33c6..5fab5be 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -926,7 +926,7 @@
         delete session->revBuf;
         session->revBuf = NULL;
 
-        session->io = 0;
+        session->id = 0;
     }
 
     return 0;
@@ -1155,7 +1155,7 @@
 {
     size_t i;
     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
-        if (sSessions[i].io == ioId) {
+        if (sSessions[i].id == sessionId) {
             if (sSessions[i].createdMsk & (1 << procId)) {
                 return NULL;
             }
@@ -1163,7 +1163,7 @@
         }
     }
     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
-        if (sSessions[i].io == 0) {
+        if (sSessions[i].id == 0) {
             sSessions[i].id = sessionId;
             sSessions[i].io = ioId;
             return &sSessions[i];
@@ -1915,7 +1915,7 @@
     status = Session_CreateEffect(session, procId, pInterface);
 
     if (status < 0 && session->createdMsk == 0) {
-        session->io = 0;
+        session->id = 0;
     }
     return status;
 }
@@ -1929,7 +1929,7 @@
 
     preproc_effect_t *fx = (preproc_effect_t *)interface;
 
-    if (fx->session->io == 0) {
+    if (fx->session->id == 0) {
         return -EINVAL;
     }
     return Session_ReleaseEffect(fx->session, fx);