APM: Notify the client about new audio ports

Added missing notification to the APM client
about new audio ports. This should make the
ports provided by the newly discovered HAL
to be available to apps.

Process the onNewAudioModulesAvailable notification
on the "APM Output" command thread to avoid clashing
with outgoing commands from APM during module
initialization.

Bug: 149854039
Test: atest audiopolicy_tests
Change-Id: I3fede7f5a04419b15e15476d8b5ac7dc6d63c98d
Merged-In: I3fede7f5a04419b15e15476d8b5ac7dc6d63c98d
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8de8ecd..d1909ea 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -134,12 +134,14 @@
     sp<DeviceDescriptor> device =
             mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
                                            state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
-    if (device == 0) {
-        return INVALID_OPERATION;
-    }
+    return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
+}
 
+status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
+                                                         audio_policy_dev_state_t state)
+{
     // handle output devices
-    if (audio_is_output_device(deviceType)) {
+    if (audio_is_output_device(device->type())) {
         SortedVector <audio_io_handle_t> outputs;
 
         ssize_t index = mAvailableOutputDevices.indexOf(device);
@@ -156,7 +158,7 @@
                 return INVALID_OPERATION;
             }
             ALOGV("%s() connecting device %s format %x",
-                    __func__, device->toString().c_str(), encodedFormat);
+                    __func__, device->toString().c_str(), device->getEncodedFormat());
 
             // register new device as available
             if (mAvailableOutputDevices.add(device) < 0) {
@@ -218,16 +220,13 @@
         // output device used by a dynamic policy of type recorder as no
         // playback use case is affected.
         bool doCheckForDeviceAndOutputChanges = true;
-        if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
-                && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
+        if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX && device->address() != "0") {
             for (audio_io_handle_t output : outputs) {
                 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
                 sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
                 if (policyMix != nullptr
                         && policyMix->mMixType == MIX_TYPE_RECORDERS
-                        && strncmp(device_address,
-                                   policyMix->mDeviceAddress.string(),
-                                   AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+                        && device->address() == policyMix->mDeviceAddress.string()) {
                     doCheckForDeviceAndOutputChanges = false;
                     break;
                 }
@@ -273,7 +272,7 @@
                 // a valid device selection on those outputs.
                 bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
                         && !desc->isDuplicated()
-                        && (!device_distinguishes_on_address(deviceType)
+                        && (!device_distinguishes_on_address(device->type())
                                 // always force when disconnecting (a non-duplicated device)
                                 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
                 setOutputDevices(desc, newDevices, force, 0);
@@ -289,7 +288,7 @@
     }  // end if is output device
 
     // handle input devices
-    if (audio_is_input_device(deviceType)) {
+    if (audio_is_input_device(device->type())) {
         ssize_t index = mAvailableInputDevices.indexOf(device);
         switch (state)
         {
@@ -4387,7 +4386,7 @@
 
     // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
     // open all output streams needed to access attached devices
-    onNewAudioModulesAvailable();
+    onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
 
     // make sure default device is reachable
     if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
@@ -4444,6 +4443,16 @@
 
 void AudioPolicyManager::onNewAudioModulesAvailable()
 {
+    DeviceVector newDevices;
+    onNewAudioModulesAvailableInt(&newDevices);
+    if (!newDevices.empty()) {
+        nextAudioPortGeneration();
+        mpClientInterface->onAudioPortListUpdate();
+    }
+}
+
+void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
+{
     for (const auto& hwModule : mHwModulesAll) {
         if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
             continue;
@@ -4507,6 +4516,7 @@
                 if (!device->isAttached()) {
                     device->attach(hwModule);
                     mAvailableOutputDevices.add(device);
+                    if (newDevices) newDevices->add(device);
                     setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                 }
             }
@@ -4562,6 +4572,7 @@
                     device->attach(hwModule);
                     device->importAudioPortAndPickAudioProfile(inProfile, true);
                     mAvailableInputDevices.add(device);
+                    if (newDevices) newDevices->add(device);
                     setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                 }
             }