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,