libaudiohal: Implement some functions called during startup

Based on the logs during CF startup, implemented the following
methods:
  - DeviceFactoryHalAild::getHalPids
  - DeviceHalAidl::dump
  - DeviceHalAidl::get/setMasterMute
  - DeviceHalAidl::get/setMasterVolume
  - DeviceHalAidl::get/setMicMute
  - DeviceHalAidl::setMode
  - DeviceHalAidl::setVoiceVolume

Also implemented retrieving of IStreamCommon.

Bug: 205884982
Test: boot cuttlefish with AIDL enabled
Change-Id: Ie1619def1b5d8e2079d849b2e9e23ebeed6e2936
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
index 097ccfd..db6b6cf 100644
--- a/media/libaudiohal/impl/ConversionHelperAidl.h
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -18,9 +18,28 @@
 
 #include <string>
 #include <string_view>
+#include <vector>
+
+#include <utils/String16.h>
+#include <utils/Vector.h>
 
 namespace android {
 
+class Args {
+  public:
+    explicit Args(const Vector<String16>& args)
+            : mValues(args.size()), mPtrs(args.size()) {
+        for (size_t i = 0; i < args.size(); ++i) {
+            mValues[i] = std::string(String8(args[i]));
+            mPtrs[i] = mValues[i].c_str();
+        }
+    }
+    const char** args() { return mPtrs.data(); }
+  private:
+    std::vector<std::string> mValues;
+    std::vector<const char*> mPtrs;
+};
+
 class ConversionHelperAidl {
   protected:
     ConversionHelperAidl(std::string_view className) : mClassName(className) {}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 02e8fa7..179a655 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -16,15 +16,22 @@
 
 #define LOG_TAG "DeviceHalAidl"
 
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionUtil.h>
 #include <mediautils/TimeCheck.h>
 #include <utils/Log.h>
 
-#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
-
 #include "DeviceHalAidl.h"
 #include "StreamHalAidl.h"
 
-using ::aidl::android::hardware::audio::core::StreamDescriptor;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::Float;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::ITelephony;
+using aidl::android::hardware::audio::core::StreamDescriptor;
 
 namespace android {
 
@@ -41,58 +48,66 @@
 
 status_t DeviceHalAidl::setVoiceVolume(float volume) {
     TIME_CHECK();
-    mVoiceVolume = volume;
-    ALOGE("%s not implemented yet %f", __func__, volume);
-    return OK;
+    if (!mModule) return NO_INIT;
+    std::shared_ptr<ITelephony> telephony;
+    if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+            status.isOk() && telephony != nullptr) {
+        ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
+        RETURN_STATUS_IF_ERROR(
+                statusTFromBinderStatus(telephony->setTelecomConfig(inConfig, &outConfig)));
+        ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
+                "%s: the resulting voice volume %f is not the same as requested %f",
+                __func__, outConfig.voiceVolume.value().value, volume);
+    }
+    return INVALID_OPERATION;
 }
 
 status_t DeviceHalAidl::setMasterVolume(float volume) {
     TIME_CHECK();
-    mMasterVolume = volume;
-    ALOGE("%s not implemented yet %f", __func__, volume);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMasterVolume(volume));
 }
 
 status_t DeviceHalAidl::getMasterVolume(float *volume) {
     TIME_CHECK();
-    *volume = mMasterVolume;
-    ALOGE("%s not implemented yet %f", __func__, *volume);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMasterVolume(volume));
 }
 
-status_t DeviceHalAidl::setMode(audio_mode_t mode __unused) {
+status_t DeviceHalAidl::setMode(audio_mode_t mode) {
     TIME_CHECK();
     if (!mModule) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
+    std::shared_ptr<ITelephony> telephony;
+    if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+            status.isOk() && telephony != nullptr) {
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(telephony->switchAudioMode(audioMode)));
+    }
+    return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
 }
 
 status_t DeviceHalAidl::setMicMute(bool state) {
     TIME_CHECK();
-    mMicMute = state;
-    ALOGE("%s not implemented yet %d", __func__, state);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMicMute(state));
 }
 
 status_t DeviceHalAidl::getMicMute(bool *state) {
     TIME_CHECK();
-    *state = mMicMute;
-    ALOGE("%s not implemented yet %d", __func__, *state);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMicMute(state));
 }
 
 status_t DeviceHalAidl::setMasterMute(bool state) {
     TIME_CHECK();
-    mMasterMute = state;
-    ALOGE("%s not implemented yet %d", __func__, state);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMasterMute(state));
 }
 
 status_t DeviceHalAidl::getMasterMute(bool *state) {
     TIME_CHECK();
-    *state = mMasterMute;
-    ALOGE("%s not implemented yet %d", __func__, *state);
-    return OK;
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMasterMute(state));
 }
 
 status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
@@ -259,9 +274,10 @@
     return base::unexpected(INVALID_OPERATION);
 }
 
-status_t DeviceHalAidl::dump(int __unused, const Vector<String16>& __unused) {
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return mModule->dump(fd, Args(args).args(), args.size());
 };
 
 int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 91d48cc..99e28d8 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -121,11 +121,6 @@
     friend class sp<DeviceHalAidl>;
 
     const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
-    // FIXME: Remove these after implementing calls into the HAL.
-    float mMasterVolume = 0.0f;
-    float mVoiceVolume = 0.0f;
-    bool mMasterMute = false;
-    bool mMicMute = false;
 
     // Can not be constructed directly by clients.
     explicit DeviceHalAidl(
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index ee29f09..78d03e7 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -19,6 +19,7 @@
 
 #include <aidl/android/hardware/audio/core/IModule.h>
 #include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
 #include <memory>
 #include <utils/Log.h>
 
@@ -64,8 +65,23 @@
     if (pids == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    // The functionality for retrieving debug infos of services is not exposed via the NDK.
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+        return NO_INIT;
+    }
+    std::set<pid_t> pidsSet;
+    const auto moduleServiceName = std::string(IModule::descriptor) + "/";
+    auto debugInfos = sm->getServiceDebugInfo();
+    for (const auto& info : debugInfos) {
+        if (info.pid > 0 &&
+                info.name.size() > moduleServiceName.size() && // '>' as there must be instance name
+                info.name.substr(0, moduleServiceName.size()) == moduleServiceName) {
+            pidsSet.insert(info.pid);
+        }
+    }
+    *pids = {pidsSet.begin(), pidsSet.end()};
+    return NO_ERROR;
 }
 
 status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 7338952..1c6a014 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -31,6 +31,20 @@
 
 namespace android {
 
+// static
+template<class T>
+std::shared_ptr<IStreamCommon> StreamHalAidl::getStreamCommon(const std::shared_ptr<T>& stream) {
+    std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> streamCommon;
+    if (stream != nullptr) {
+        if (ndk::ScopedAStatus status = stream->getStreamCommon(&streamCommon);
+                !status.isOk()) {
+            ALOGE("%s: failed to retrieve IStreamCommon instance: %s", __func__,
+                    status.getDescription().c_str());
+        }
+    }
+    return streamCommon;
+}
+
 StreamHalAidl::StreamHalAidl(
         std::string_view className, bool isInput, const StreamDescriptor& descriptor,
         const std::shared_ptr<IStreamCommon>& stream)
@@ -130,11 +144,10 @@
     return OK;
 }
 
-status_t StreamHalAidl::dump(int fd __unused, const Vector<String16>& args __unused) {
+status_t StreamHalAidl::dump(int fd, const Vector<String16>& args) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    return mStream->dump(fd, Args(args).args(), args.size());
 }
 
 status_t StreamHalAidl::start() {
@@ -190,18 +203,13 @@
 status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
                                                std::optional<audio_source_t> source __unused,
                                                audio_devices_t type __unused) {
-    TIME_CHECK();
-    LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+    return INVALID_OPERATION;
 }
 
 status_t StreamHalAidl::legacyReleaseAudioPatch() {
-    TIME_CHECK();
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+    return INVALID_OPERATION;
 }
 
 namespace {
@@ -237,8 +245,7 @@
 
 StreamOutHalAidl::StreamOutHalAidl(
         const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
-        : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor,
-                nullptr /* FIXME: Retrieve IStreamCommon */),
+        : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor, getStreamCommon(stream)),
           mStream(stream) {}
 
 status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
@@ -452,8 +459,7 @@
 
 StreamInHalAidl::StreamInHalAidl(
         const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
-        : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor,
-                nullptr /* FIXME: Retrieve IStreamCommon */),
+        : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor, getStreamCommon(stream)),
           mStream(stream) {}
 
 status_t StreamInHalAidl::setGain(float gain __unused) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 86f48f3..c56d5e3 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -94,6 +94,10 @@
     typedef AidlMessageQueue<int8_t,
             ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
 
+    template<class T>
+    static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
+            const std::shared_ptr<T>& stream);
+
     // Subclasses can not be constructed directly by clients.
     StreamHalAidl(std::string_view className,
             bool isInput,