Audio policy manager changes for audio effects

Added methods for audio effects management by audio policy manager.
- control of total CPU load and memory used by effect engines
- selection of output stream for global effects
- added audio session id in parameter list for startOutput() and stopOutput().
this is not used in default audio policy manager implementation.

Modifications of audio effect framework in AudioFlinger to allow moving and reconfiguring
effect engines from one output mixer thread to another when audio tracks in the same session
are moved or when requested by audio policy manager.
Also fixed mutex deadlock problem with effect chains locks.

Change-Id: Ida43484b06e9b890d6b9e53c13958d042720ebdb
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index bb3905c..f24e08e 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -119,7 +119,8 @@
     if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
         return BAD_VALUE;
     }
-    if (state != AudioSystem::DEVICE_STATE_AVAILABLE && state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
+    if (state != AudioSystem::DEVICE_STATE_AVAILABLE &&
+            state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
         return BAD_VALUE;
     }
 
@@ -128,8 +129,9 @@
     return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
 }
 
-AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(AudioSystem::audio_devices device,
-                                                  const char *device_address)
+AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(
+                                                              AudioSystem::audio_devices device,
+                                                              const char *device_address)
 {
     if (mpPolicyManager == NULL) {
         return AudioSystem::DEVICE_STATE_UNAVAILABLE;
@@ -175,7 +177,8 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
+status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage,
+                                         AudioSystem::forced_config config)
 {
     if (mpPolicyManager == NULL) {
         return NO_INIT;
@@ -223,24 +226,28 @@
     return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
 }
 
-status_t AudioPolicyService::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+status_t AudioPolicyService::startOutput(audio_io_handle_t output,
+                                         AudioSystem::stream_type stream,
+                                         int session)
 {
     if (mpPolicyManager == NULL) {
         return NO_INIT;
     }
     LOGV("startOutput() tid %d", gettid());
     Mutex::Autolock _l(mLock);
-    return mpPolicyManager->startOutput(output, stream);
+    return mpPolicyManager->startOutput(output, stream, session);
 }
 
-status_t AudioPolicyService::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
+                                        AudioSystem::stream_type stream,
+                                        int session)
 {
     if (mpPolicyManager == NULL) {
         return NO_INIT;
     }
     LOGV("stopOutput() tid %d", gettid());
     Mutex::Autolock _l(mLock);
-    return mpPolicyManager->stopOutput(output, stream);
+    return mpPolicyManager->stopOutput(output, stream, session);
 }
 
 void AudioPolicyService::releaseOutput(audio_io_handle_t output)
@@ -339,8 +346,46 @@
     return mpPolicyManager->getStreamVolumeIndex(stream, index);
 }
 
+uint32_t AudioPolicyService::getStrategyForStream(AudioSystem::stream_type stream)
+{
+    if (mpPolicyManager == NULL) {
+        return 0;
+    }
+    return mpPolicyManager->getStrategyForStream(stream);
+}
+
+audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->getOutputForEffect(desc);
+}
+
+status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
+                                audio_io_handle_t output,
+                                uint32_t strategy,
+                                int session,
+                                int id)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    return mpPolicyManager->registerEffect(desc, output, strategy, session, id);
+}
+
+status_t AudioPolicyService::unregisterEffect(int id)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    return mpPolicyManager->unregisterEffect(id);
+}
+
 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
-    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
+            IPCThreadState::self()->getCallingPid());
 }
 
 static bool tryLock(Mutex& mutex)
@@ -447,10 +492,16 @@
         return 0;
     }
 
-    return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, pLatencyMs, flags);
+    return af->openOutput(pDevices,
+                          pSamplingRate,
+                          (uint32_t *)pFormat,
+                          pChannels,
+                          pLatencyMs,
+                          flags);
 }
 
-audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2)
+audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1,
+                                                          audio_io_handle_t output2)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -514,12 +565,16 @@
     return af->closeInput(input);
 }
 
-status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
+status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream,
+                                             float volume,
+                                             audio_io_handle_t output,
+                                             int delayMs)
 {
     return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
 }
 
-status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output)
+status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream,
+                                             audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) return PERMISSION_DENIED;
@@ -527,8 +582,18 @@
     return af->setStreamOutput(stream, output);
 }
 
+status_t AudioPolicyService::moveEffects(int session, audio_io_handle_t srcOutput,
+                                               audio_io_handle_t dstOutput)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
 
-void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs)
+    return af->moveEffects(session, (int)srcOutput, (int)dstOutput);
+}
+
+void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
+                                       const String8& keyValuePairs,
+                                       int delayMs)
 {
     mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
 }
@@ -539,7 +604,8 @@
     return result;
 }
 
-status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream)
+status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone,
+                                       AudioSystem::stream_type stream)
 {
     mTonePlaybackThread->startToneCommand(tone, stream);
     return NO_ERROR;
@@ -623,8 +689,11 @@
                     }break;
                 case SET_VOLUME: {
                     VolumeData *data = (VolumeData *)command->mParam;
-                    LOGV("AudioCommandThread() processing set volume stream %d, volume %f, output %d", data->mStream, data->mVolume, data->mIO);
-                    command->mStatus = AudioSystem::setStreamVolume(data->mStream, data->mVolume, data->mIO);
+                    LOGV("AudioCommandThread() processing set volume stream %d, \
+                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
+                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
+                                                                    data->mVolume,
+                                                                    data->mIO);
                     if (command->mWaitStatus) {
                         command->mCond.signal();
                         mWaitWorkCV.wait(mLock);
@@ -633,7 +702,8 @@
                     }break;
                 case SET_PARAMETERS: {
                      ParametersData *data = (ParametersData *)command->mParam;
-                     LOGV("AudioCommandThread() processing set parameters string %s, io %d", data->mKeyValuePairs.string(), data->mIO);
+                     LOGV("AudioCommandThread() processing set parameters string %s, io %d",
+                             data->mKeyValuePairs.string(), data->mIO);
                      command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
                      if (command->mWaitStatus) {
                          command->mCond.signal();
@@ -643,7 +713,8 @@
                      }break;
                 case SET_VOICE_VOLUME: {
                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
-                    LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
+                    LOGV("AudioCommandThread() processing set voice volume volume %f",
+                            data->mVolume);
                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
                     if (command->mWaitStatus) {
                         command->mCond.signal();
@@ -734,7 +805,10 @@
     mWaitWorkCV.signal();
 }
 
-status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
+status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream,
+                                                               float volume,
+                                                               int output,
+                                                               int delayMs)
 {
     status_t status = NO_ERROR;
 
@@ -752,7 +826,8 @@
     }
     Mutex::Autolock _l(mLock);
     insertCommand_l(command, delayMs);
-    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
+    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
+            stream, volume, output);
     mWaitWorkCV.signal();
     if (command->mWaitStatus) {
         command->mCond.wait(mLock);
@@ -762,7 +837,9 @@
     return status;
 }
 
-status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs)
+status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
+                                                                   const String8& keyValuePairs,
+                                                                   int delayMs)
 {
     status_t status = NO_ERROR;
 
@@ -779,7 +856,8 @@
     }
     Mutex::Autolock _l(mLock);
     insertCommand_l(command, delayMs);
-    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
+    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
+            keyValuePairs.string(), ioHandle, delayMs);
     mWaitWorkCV.signal();
     if (command->mWaitStatus) {
         command->mCond.wait(mLock);
@@ -840,7 +918,8 @@
             ParametersData *data = (ParametersData *)command->mParam;
             ParametersData *data2 = (ParametersData *)command2->mParam;
             if (data->mIO != data2->mIO) break;
-            LOGV("Comparing parameter command %s to new command %s", data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
+            LOGV("Comparing parameter command %s to new command %s",
+                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
             AudioParameter param = AudioParameter(data->mKeyValuePairs);
             AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
             for (size_t j = 0; j < param.size(); j++) {
@@ -872,7 +951,8 @@
             VolumeData *data2 = (VolumeData *)command2->mParam;
             if (data->mIO != data2->mIO) break;
             if (data->mStream != data2->mStream) break;
-            LOGV("Filtering out volume command on output %d for stream %d", data->mIO, data->mStream);
+            LOGV("Filtering out volume command on output %d for stream %d",
+                    data->mIO, data->mStream);
             removedCommands.add(command2);
         } break;
         case START_TONE:
@@ -896,7 +976,8 @@
     removedCommands.clear();
 
     // insert command at the right place according to its time stamp
-    LOGV("inserting command: %d at index %d, num commands %d", command->mCommand, (int)i+1, mAudioCommands.size());
+    LOGV("inserting command: %d at index %d, num commands %d",
+            command->mCommand, (int)i+1, mAudioCommands.size());
     mAudioCommands.insertAt(command, i + 1);
 }