Expose capture state listener in AudioSystem

This is a client-side wrapper around the respective feature of APS.

Bug: 146157104
Test: Manual verification of proper behavior when starting/stopping
      recording, killing of audio server, by examination of the logs.
Merged-In: I9b56c431f69e77683151de19830ec6f45741dd6f
Change-Id: I1f5279c4a4b18e0a7862d3b103d383ac3de4c9a0
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index ff2608c..74fa343 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 
 #include <utils/Log.h>
+
+#include <android/media/BnCaptureStateListener.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/IPCThreadState.h>
@@ -44,6 +46,10 @@
 dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
 record_config_callback AudioSystem::gRecordConfigCallback = NULL;
 
+// Required to be held while calling into gSoundTriggerCaptureStateListener.
+Mutex gSoundTriggerCaptureStateListenerLock;
+sp<AudioSystem::CaptureStateListener> gSoundTriggerCaptureStateListener = nullptr;
+
 // establish binder interface to AudioFlinger service
 const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
 {
@@ -1623,6 +1629,48 @@
     return aps->getPreferredDeviceForStrategy(strategy, device);
 }
 
+class CaptureStateListenerImpl : public media::BnCaptureStateListener,
+                                 public IBinder::DeathRecipient {
+public:
+    binder::Status setCaptureState(bool active) override {
+        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+        gSoundTriggerCaptureStateListener->onStateChanged(active);
+        return binder::Status::ok();
+    }
+
+    void binderDied(const wp<IBinder>&) override {
+        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+        gSoundTriggerCaptureStateListener->onServiceDied();
+        gSoundTriggerCaptureStateListener = nullptr;
+    }
+};
+
+status_t AudioSystem::registerSoundTriggerCaptureStateListener(
+    const sp<CaptureStateListener>& listener) {
+    const sp<IAudioPolicyService>& aps =
+            AudioSystem::get_audio_policy_service();
+    if (aps == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    sp<CaptureStateListenerImpl> wrapper = new CaptureStateListenerImpl();
+
+    Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+
+    bool active;
+    status_t status =
+        aps->registerSoundTriggerCaptureStateListener(wrapper, &active);
+    if (status != NO_ERROR) {
+        listener->onServiceDied();
+        return NO_ERROR;
+    }
+    gSoundTriggerCaptureStateListener = listener;
+    listener->onStateChanged(active);
+    sp<IBinder> binder = IInterface::asBinder(aps);
+    binder->linkToDeath(wrapper);
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(