Revert "Revert "audio policy: refactor audio record APIs""

This reverts commit e9ebcdbb0580bd4a75f4530b957b1859e535c028.

Bug: 72628781
Test: manual camcorder tests
Change-Id: I9fb550a9f62d2d15cafbd7534e5e7eaa155a7213
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index f1d7d86..0ce562c 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -287,6 +287,7 @@
                                              audio_session_t session,
                                              pid_t pid,
                                              uid_t uid,
+                                             const String16& opPackageName,
                                              const audio_config_base_t *config,
                                              audio_input_flags_t flags,
                                              audio_port_handle_t *selectedDeviceId,
@@ -367,6 +368,13 @@
             }
             return status;
         }
+
+        sp<AudioRecordClient> client =
+                new AudioRecordClient(*attr, *input, uid, pid, opPackageName, session);
+        client->active = false;
+        client->isConcurrent = false;
+        client->isVirtualDevice = false; //TODO : update from APM->getInputForAttr()
+        mAudioRecordClients.add(*portId, client);
     }
 
     if (audioPolicyEffects != 0) {
@@ -379,23 +387,28 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyService::startInput(audio_io_handle_t input,
-                                        audio_session_t session,
-                                        audio_devices_t device,
-                                        uid_t uid,
-                                        bool *silenced)
+status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenced)
 {
-    // If UID inactive it records silence until becoming active
-    *silenced = !mUidPolicy->isUidActive(uid) && !is_virtual_input_device(device);
-
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
 
     Mutex::Autolock _l(mLock);
+
+    ssize_t index = mAudioRecordClients.indexOfKey(portId);
+    if (index < 0) {
+        return INVALID_OPERATION;
+    }
+    sp<AudioRecordClient> client = mAudioRecordClients.valueAt(index);
+
+    // If UID inactive it records silence until becoming active
+    *silenced = !mUidPolicy->isUidActive(client->uid) && !client->isVirtualDevice;
+
     AudioPolicyInterface::concurrency_type__mask_t concurrency =
             AudioPolicyInterface::API_INPUT_CONCURRENCY_NONE;
-    status_t status = mAudioPolicyManager->startInput(input, session, *silenced, &concurrency);
+
+    status_t status = mAudioPolicyManager->startInput(
+            client->input, client->session, *silenced, &concurrency);
 
     if (status == NO_ERROR) {
         LOG_ALWAYS_FATAL_IF(concurrency & ~AudioPolicyInterface::API_INPUT_CONCURRENCY_ALL,
@@ -413,38 +426,52 @@
     return status;
 }
 
-status_t AudioPolicyService::stopInput(audio_io_handle_t input,
-                                       audio_session_t session)
+status_t AudioPolicyService::stopInput(audio_port_handle_t portId)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mAudioPolicyManager->stopInput(input, session);
+    ssize_t index = mAudioRecordClients.indexOfKey(portId);
+    if (index < 0) {
+        return INVALID_OPERATION;
+    }
+    sp<AudioRecordClient> client = mAudioRecordClients.valueAt(index);
+
+    return mAudioPolicyManager->stopInput(client->input, client->session);
 }
 
-void AudioPolicyService::releaseInput(audio_io_handle_t input,
-                                      audio_session_t session)
+void AudioPolicyService::releaseInput(audio_port_handle_t portId)
 {
     if (mAudioPolicyManager == NULL) {
         return;
     }
     sp<AudioPolicyEffects>audioPolicyEffects;
+    sp<AudioRecordClient> client;
     {
         Mutex::Autolock _l(mLock);
         audioPolicyEffects = mAudioPolicyEffects;
+        ssize_t index = mAudioRecordClients.indexOfKey(portId);
+        if (index < 0) {
+            return;
+        }
+        client = mAudioRecordClients.valueAt(index);
+        mAudioRecordClients.removeItem(portId);
+    }
+    if (client == 0) {
+        return;
     }
     if (audioPolicyEffects != 0) {
         // release audio processors from the input
-        status_t status = audioPolicyEffects->releaseInputEffects(input, session);
+        status_t status = audioPolicyEffects->releaseInputEffects(client->input, client->session);
         if(status != NO_ERROR) {
-            ALOGW("Failed to release effects on input %d", input);
+            ALOGW("Failed to release effects on input %d", client->input);
         }
     }
     {
         Mutex::Autolock _l(mLock);
-        mAudioPolicyManager->releaseInput(input, session);
+        mAudioPolicyManager->releaseInput(client->input, client->session);
     }
 }
 
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c21aa58..bfa3ef4 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -98,19 +98,15 @@
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,
+                                     const String16& opPackageName,
                                      const audio_config_base_t *config,
                                      audio_input_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId = NULL,
                                      audio_port_handle_t *portId = NULL);
-    virtual status_t startInput(audio_io_handle_t input,
-                                audio_session_t session,
-                                audio_devices_t device,
-                                uid_t uid,
+    virtual status_t startInput(audio_port_handle_t portId,
                                 bool *silenced);
-    virtual status_t stopInput(audio_io_handle_t input,
-                               audio_session_t session);
-    virtual void releaseInput(audio_io_handle_t input,
-                              audio_session_t session);
+    virtual status_t stopInput(audio_port_handle_t portId);
+    virtual void releaseInput(audio_port_handle_t portId);
     virtual status_t initStreamVolume(audio_stream_type_t stream,
                                       int indexMin,
                                       int indexMax);
@@ -611,6 +607,31 @@
               bool                          mAudioPortCallbacksEnabled;
     };
 
+    // --- AudioRecordClient ---
+    // Information about each registered AudioRecord client
+    // (between calls to getInputForAttr() and releaseInput())
+    class AudioRecordClient : public RefBase {
+    public:
+                AudioRecordClient(const audio_attributes_t attributes,
+                                  const audio_io_handle_t input, uid_t uid, pid_t pid,
+                                  const String16& opPackageName, const audio_session_t session) :
+                                      attributes(attributes),
+                                      input(input), uid(uid), pid(pid),
+                                      opPackageName(opPackageName), session(session),
+                                      active(false), isConcurrent(false), isVirtualDevice(false) {}
+        virtual ~AudioRecordClient() {}
+
+        const audio_attributes_t attributes; // source, flags ...
+        const audio_io_handle_t input;       // audio HAL input IO handle
+        const uid_t uid;                     // client UID
+        const pid_t pid;                     // client PID
+        const String16 opPackageName;        // client package name
+        const audio_session_t session;       // audio session ID
+        bool active;                   // Capture is active or inactive
+        bool isConcurrent;             // is allowed to concurrent capture
+        bool isVirtualDevice;          // uses vitual device: updated by APM::getInputForAttr()
+    };
+
     // Internal dump utilities.
     status_t dumpPermissionDenial(int fd);
 
@@ -636,6 +657,7 @@
     audio_mode_t mPhoneState;
 
     sp<UidPolicy> mUidPolicy;
+    DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> >   mAudioRecordClients;
 };
 
 } // namespace android