Call getAudioPort to get supported attributes for audio devices.

GetAudioPort API will return the supported attributes for the devices.
Call getAudioPort to get the supported attributes for the audio
devices so that it is no needed to get supported attributes via
getParameters API.

Bug: 160352965
Test: make
Test: atest audiopolicy_tests AudioPlaybackCaptureTest
Change-Id: Icdfe76e15066bbff10308d6dfd1cf742da33fec9
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2ff6af5..14ed2ad 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -266,7 +266,7 @@
                                     struct audio_port *ports);
 
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port *port);
+    virtual status_t getAudioPort(struct audio_port_v7 *port);
 
     /* Create an audio patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/services/audioflinger/AudioHwDevice.cpp b/services/audioflinger/AudioHwDevice.cpp
index dda164c..16b25f6 100644
--- a/services/audioflinger/AudioHwDevice.cpp
+++ b/services/audioflinger/AudioHwDevice.cpp
@@ -98,5 +98,9 @@
     return mHwDevice->supportsAudioPatches(&result) == OK ? result : false;
 }
 
+status_t AudioHwDevice::getAudioPort(struct audio_port_v7 *port) const {
+    return mHwDevice->getAudioPort(port);
+}
+
 
 }; // namespace android
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index 6709d17..fc2c693 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -83,6 +83,8 @@
 
     bool supportsAudioPatches() const;
 
+    status_t getAudioPort(struct audio_port_v7 *port) const;
+
 private:
     const audio_module_handle_t mHandle;
     const char * const          mModuleName;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index b58fd8b..b956b96 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -55,8 +55,7 @@
 }
 
 /* Get supported attributes for a given audio port */
-status_t AudioFlinger::getAudioPort(struct audio_port *port)
-{
+status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
     Mutex::Autolock _l(mLock);
     return mPatchPanel.getAudioPort(port);
 }
@@ -103,10 +102,22 @@
 }
 
 /* Get supported attributes for a given audio port */
-status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
+status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port_v7 *port)
 {
-    ALOGV(__func__);
-    return NO_ERROR;
+    if (port->type != AUDIO_PORT_TYPE_DEVICE) {
+        // Only query the HAL when the port is a device.
+        // TODO: implement getAudioPort for mix.
+        return INVALID_OPERATION;
+    }
+    AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module);
+    if (hwDevice == nullptr) {
+        ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
+        return BAD_VALUE;
+    }
+    if (!hwDevice->supportsAudioPatches()) {
+        return INVALID_OPERATION;
+    }
+    return hwDevice->getAudioPort(port);
 }
 
 /* Connect a patch between several source and sink ports */
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 89d4eb1..2568dd3 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -52,7 +52,7 @@
                                     struct audio_port *ports);
 
     /* Get supported attributes for a given audio port */
-    status_t getAudioPort(struct audio_port *port);
+    status_t getAudioPort(struct audio_port_v7 *port);
 
     /* Create a patch between several source and sink ports */
     status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 93819f5..b00426f 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -444,6 +444,8 @@
     // sessions to be preempted on modules that do not support sound trigger
     // recognition concurrently with audio capture.
     virtual void setSoundTriggerCaptureState(bool active) = 0;
+
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 };
 
 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index ca29591..80190b7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -88,6 +88,7 @@
 
     // AudioPort
     virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
     void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
                                             bool force = false);
@@ -97,6 +98,13 @@
     void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
 
 private:
+    template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+                                        || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+    void toAudioPortInternal(T* port) const {
+        DeviceDescriptorBase::toAudioPort(port);
+        port->ext.device.hw_module = getModuleHandle();
+    }
+
     std::string mTagName; // Unique human readable identifier for a device port found in conf file.
     FormatVector        mEncodedFormats;
     audio_format_t      mCurrentEncodedFormat;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 6ff1a98..e43ca0f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -160,8 +160,12 @@
 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
 {
     ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
-    DeviceDescriptorBase::toAudioPort(port);
-    port->ext.device.hw_module = getModuleHandle();
+    toAudioPortInternal(port);
+}
+
+void DeviceDescriptor::toAudioPort(struct audio_port_v7 *port) const {
+    ALOGV("DeviceDescriptor::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
+    toAudioPortInternal(port);
 }
 
 void DeviceDescriptor::importAudioPortAndPickAudioProfile(
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4a3e31f..7b8a2ea 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4833,7 +4833,15 @@
     }
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
-        // first list already open outputs that can be routed to this device
+        // first call getAudioPort to get the supported attributes from the HAL
+        struct audio_port_v7 port = {};
+        device->toAudioPort(&port);
+        status_t status = mpClientInterface->getAudioPort(&port);
+        if (status == NO_ERROR) {
+            device->importAudioPort(port);
+        }
+
+        // then list already open outputs that can be routed to this device
         for (size_t i = 0; i < mOutputs.size(); i++) {
             desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated() && desc->supportsDevice(device)
@@ -4895,8 +4903,8 @@
                   deviceType, address.string(), profile.get(), profile->getName().c_str());
             desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = desc->open(nullptr, DeviceVector(device),
-                                         AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
+            status = desc->open(nullptr, DeviceVector(device),
+                                AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
 
             if (status == NO_ERROR) {
                 // Here is where the out_set_parameters() for card & device gets called
@@ -4920,9 +4928,8 @@
                     config.offload_info.channel_mask = config.channel_mask;
                     config.offload_info.format = config.format;
 
-                    status_t status = desc->open(&config, DeviceVector(device),
-                                                 AUDIO_STREAM_DEFAULT,
-                                                 AUDIO_OUTPUT_FLAG_NONE, &output);
+                    status = desc->open(&config, DeviceVector(device),
+                                        AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
                     if (status != NO_ERROR) {
                         output = AUDIO_IO_HANDLE_NONE;
                     }
@@ -4952,8 +4959,8 @@
                         // open a duplicating output thread for the new output and the primary output
                         sp<SwAudioOutputDescriptor> dupOutputDesc =
                                 new SwAudioOutputDescriptor(NULL, mpClientInterface);
-                        status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
-                                                                         &duplicatedOutput);
+                        status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
+                                                                &duplicatedOutput);
                         if (status == NO_ERROR) {
                             // add duplicated output descriptor
                             addOutput(duplicatedOutput, dupOutputDesc);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9fa7a53..1cc6d48 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -246,4 +246,14 @@
     mAudioPolicyService->mCaptureStateNotifier.setCaptureState(active);
 }
 
+status_t AudioPolicyService::AudioPolicyClient::getAudioPort(struct audio_port_v7 *port)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return PERMISSION_DENIED;
+    }
+    return af->getAudioPort(port);
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 0b218c2..70a0e3a 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -765,6 +765,8 @@
 
         void setSoundTriggerCaptureState(bool active) override;
 
+        status_t getAudioPort(struct audio_port_v7 *port) override;
+
      private:
         AudioPolicyService *mAudioPolicyService;
     };
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index c628e70..fa6b90f 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -87,6 +87,9 @@
                             audio_session_t sessionId __unused,
                             bool suspended __unused) {}
     void setSoundTriggerCaptureState(bool active __unused) override {};
+    status_t getAudioPort(struct audio_port_v7 *port __unused) override {
+        return INVALID_OPERATION;
+    };
 };
 
 } // namespace android