AudioPolicy/AudioFlinger: Track AudioRecords via Record IDs

The client must provide a unique Record ID (RIID) when creating
an AudioRecord. This RIID is passed down to AudioInputDescriptor
in AudioPolicyManager which sends configuration updates
via IAudioPolicyServiceClient callback.

By supplying RIID, the Audio Service can coalesce start / stop
events coming from clients (apps) with recording configuration
update events.

For AAudio MMap clients everything is handled at the server
side because they correspond directly to audioserver objects.

Bug: 123312504
Test: android.media.cts.AudioRecordingConfigurationTest
      AudioRecordTest#testAudioRecordInfoCallback
      MediaRecorderTest#testAudioRecordInfoCallback
      manual testing using Oboe and Solo test apps

Change-Id: I3d32241752d9a747736606dc4cb1e068e6b7aa3b
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 4b56a46..49937f0 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -124,6 +124,7 @@
     // request an input appropriate for record from the supplied device with supplied parameters.
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      uid_t uid,
                                      const audio_config_base_t *config,
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 4bb225d..0d05a63 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 
 #include <system/audio.h>
+#include <audiomanager/AudioManager.h>
 #include <media/AudioProductStrategy.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -146,20 +147,23 @@
 class RecordClientDescriptor: public ClientDescriptor
 {
 public:
-    RecordClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
-                        audio_attributes_t attributes, audio_config_base_t config,
-                        audio_port_handle_t preferredDeviceId,
+    RecordClientDescriptor(audio_port_handle_t portId, audio_unique_id_t riid, uid_t uid,
+                        audio_session_t sessionId, audio_attributes_t attributes,
+                        audio_config_base_t config, audio_port_handle_t preferredDeviceId,
                         audio_source_t source, audio_input_flags_t flags, bool isSoundTrigger) :
         ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
-        mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger), mAppState(APP_STATE_IDLE) {}
+        mRIId(riid), mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger),
+        mAppState(APP_STATE_IDLE) {}
     ~RecordClientDescriptor() override = default;
 
     using ClientDescriptor::dump;
     void dump(String8 *dst, int spaces, int index) const override;
 
+    audio_unique_id_t riid() const { return mRIId; }
     audio_source_t source() const { return mSource; }
     audio_input_flags_t flags() const { return mFlags; }
     bool isSoundTrigger() const { return mIsSoundTrigger; }
+    bool isLowLevel() const { return mRIId == RECORD_RIID_INVALID; }
     void setAppState(app_state_t appState) { mAppState = appState; }
     app_state_t appState() { return mAppState; }
     bool isSilenced() const { return mAppState == APP_STATE_IDLE; }
@@ -167,6 +171,7 @@
     EffectDescriptorCollection getEnabledEffects() const { return mEnabledEffects; }
 
 private:
+    const audio_unique_id_t mRIId;
     const audio_source_t mSource;
     const audio_input_flags_t mFlags;
     const bool mIsSoundTrigger;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 58683be..a096e8f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "APM::AudioInputDescriptor"
 //#define LOG_NDEBUG 0
 
+#include <audiomanager/AudioManager.h>
 #include <media/AudioPolicy.h>
 #include <policy.h>
 #include <AudioPolicyInterface.h>
@@ -179,7 +180,9 @@
     mPatchHandle = handle;
     for (const auto &client : getClientIterable()) {
         if (client->active()) {
-            updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+            updateClientRecordingConfiguration(
+                    client->isLowLevel() ? RECORD_CONFIG_EVENT_START : RECORD_CONFIG_EVENT_UPDATE,
+                    client);
         }
     }
 }
@@ -342,15 +345,19 @@
 void AudioInputDescriptor::updateClientRecordingConfiguration(
     int event, const sp<RecordClientDescriptor>& client)
 {
+    ALOGV("%s riid %d uid %d port %d session %d event %d",
+            __func__, client->riid(), client->uid(), client->portId(), client->session(), event);
     // do not send callback if starting and no device is selected yet to avoid
     // double callbacks from startInput() before and after the device is selected
-    if (event ==  RECORD_CONFIG_EVENT_START
-            && mPatchHandle == AUDIO_PATCH_HANDLE_NONE) {
+    // "start" and "stop" events for "high level" clients (AudioRecord) are sent by the client side
+    if ((event == RECORD_CONFIG_EVENT_START && mPatchHandle == AUDIO_PATCH_HANDLE_NONE)
+            || (!client->isLowLevel()
+                    && (event == RECORD_CONFIG_EVENT_START || event == RECORD_CONFIG_EVENT_STOP))) {
         return;
     }
 
     const audio_config_base_t sessionConfig = client->config();
-    const record_client_info_t recordClientInfo{client->uid(), client->session(),
+    const record_client_info_t recordClientInfo{client->riid(), client->uid(), client->session(),
                                                 client->source(), client->portId(),
                                                 client->isSilenced()};
     const audio_config_base_t config = getConfig();
@@ -429,7 +436,7 @@
     checkSuspendEffects();
 
     for (const auto& client : updatedClients) {
-        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
     }
 }
 
@@ -462,7 +469,7 @@
     checkSuspendEffects();
 
     for (const auto& client : updatedClients) {
-        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
     }
 }
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 6bd64d6..066363f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1881,6 +1881,7 @@
 
 status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              uid_t uid,
                                              const audio_config_base_t *config,
@@ -2024,7 +2025,7 @@
         mSoundTriggerSessions.indexOfKey(session) > 0;
     *portId = AudioPort::getNextUniqueId();
 
-    clientDesc = new RecordClientDescriptor(*portId, uid, session, attributes, *config,
+    clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
                                             requestedDeviceId, attributes.source, flags,
                                             isSoundTrigger);
     inputDesc = mInputs.valueFor(*input);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 3376965..835fbdc 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -128,6 +128,7 @@
         virtual void releaseOutput(audio_port_handle_t portId);
         virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                          audio_io_handle_t *input,
+                                         audio_unique_id_t riid,
                                          audio_session_t session,
                                          uid_t uid,
                                          const audio_config_base_t *config,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 2e47eb6..06e68a9 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -334,6 +334,7 @@
 
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              pid_t pid,
                                              uid_t uid,
@@ -403,7 +404,7 @@
         {
             AutoCallerClear acc;
             // the audio_in_acoustics_t parameter is ignored by get_input()
-            status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
+            status = mAudioPolicyManager->getInputForAttr(attr, input, riid, session, uid,
                                                          config,
                                                          flags, selectedDeviceId,
                                                          &inputType, portId);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 6c19912..be6d1ac 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -91,6 +91,7 @@
     virtual void releaseOutput(audio_port_handle_t portId);
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,