Avoid explicit use of keyRouting, keyInputSource

This moves the parameter-based method of creating and releasing audio
patches into libaudiohal.

Test: Manual verification of basic playback / recording.
Change-Id: I27019ce950c7a7363d71500971436468ee706429
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index b2f1cf3..f4e93b5 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -271,6 +271,32 @@
     return err == 0;
 }
 
+status_t StreamHalHidl::legacyCreateAudioPatch(const struct audio_port_config& port,
+                                               std::optional<audio_source_t> source,
+                                               audio_devices_t type) {
+    LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
+    char* address;
+    if (strcmp(port.ext.device.address, "") != 0) {
+        // FIXME: we only support address on first sink with HAL version < 3.0
+        address = audio_device_address_to_parameter(port.ext.device.type, port.ext.device.address);
+    } else {
+        address = (char*)calloc(1, 1);
+    }
+    AudioParameter param = AudioParameter(String8(address));
+    free(address);
+    param.addInt(String8(AudioParameter::keyRouting), (int)type);
+    if (source.has_value()) {
+        param.addInt(String8(AudioParameter::keyInputSource), (int)source.value());
+    }
+    return setParameters(param.toString());
+}
+
+status_t StreamHalHidl::legacyReleaseAudioPatch() {
+    AudioParameter param;
+    param.addInt(String8(AudioParameter::keyRouting), 0);
+    return setParameters(param.toString());
+}
+
 namespace {
 
 /* Notes on callback ownership.
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 03342ef..21b0627 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -88,6 +88,12 @@
     // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
     virtual status_t setHalThreadPriority(int priority);
 
+    status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+                                            std::optional<audio_source_t> source,
+                                            audio_devices_t type) override;
+
+    status_t legacyReleaseAudioPatch() override;
+
   protected:
     // Subclasses can not be constructed directly by clients.
     explicit StreamHalHidl(IStream *stream);
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index e12fe77..3f2e450 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -89,6 +89,12 @@
     // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
     virtual status_t setHalThreadPriority(int priority) = 0;
 
+    virtual status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+                                            std::optional<audio_source_t> source,
+                                            audio_devices_t type) = 0;
+
+    virtual status_t legacyReleaseAudioPatch() = 0;
+
   protected:
     // Subclasses can not be constructed directly by clients.
     StreamHalInterface() {}