TimeCheck: Track audio Hidl hwbinder calls
DeviceHalHidl, StreamInHalHidl, StreamOutHalHidl
Test: adb shell dumpsys media.audio_flinger
Bug: 219958414
Change-Id: I3ff630983bdca6c8fd9ba9868e831cb063afdadc
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 1d34814..a1668ca 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -99,8 +99,8 @@
values->setTo(params.toString());
}
-ConversionHelperHidl::ConversionHelperHidl(const char* className)
- : mClassName(className) {
+ConversionHelperHidl::ConversionHelperHidl(std::string_view className)
+ : mClassName(className.begin(), className.end()) {
}
// static
@@ -125,7 +125,7 @@
}
void ConversionHelperHidl::emitError(const char* funcName, const char* description) {
- ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
+ ALOGE("%s %p %s: %s (from rpc)", mClassName.c_str(), this, funcName, description);
}
} // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.h b/media/libaudiohal/impl/ConversionHelperHidl.h
index 9368551..3163cbb 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.h
+++ b/media/libaudiohal/impl/ConversionHelperHidl.h
@@ -40,7 +40,7 @@
static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
static void argsFromHal(const Vector<String16>& args, hidl_vec<hidl_string> *hidlArgs);
- ConversionHelperHidl(const char* className);
+ ConversionHelperHidl(std::string_view className);
template<typename R, typename T>
status_t processReturn(const char* funcName, const Return<R>& ret, T *retval) {
@@ -76,8 +76,12 @@
return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
}
+ const std::string& getClassName() const {
+ return mClassName;
+ }
+
private:
- const char* mClassName;
+ const std::string mClassName;
static status_t analyzeResult(const CoreResult& result);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 16863e4..7fa1d45 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -23,6 +23,7 @@
#include <cutils/properties.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioContainers.h>
+#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
@@ -45,13 +46,16 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
+#define TIME_CHECK() auto timeCheck = \
+ mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
- : ConversionHelperHidl("Device"), mDevice(device) {
+ : ConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
}
DeviceHalHidl::DeviceHalHidl(
const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
- : ConversionHelperHidl("Device"),
+ : ConversionHelperHidl("DeviceHalHidl"),
#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
mDevice(device),
#endif
@@ -84,22 +88,26 @@
}
status_t DeviceHalHidl::initCheck() {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("initCheck", mDevice->initCheck());
}
status_t DeviceHalHidl::setVoiceVolume(float volume) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
if (mPrimaryDevice == 0) return INVALID_OPERATION;
return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
}
status_t DeviceHalHidl::setMasterVolume(float volume) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
}
status_t DeviceHalHidl::getMasterVolume(float *volume) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
Return<void> ret = mDevice->getMasterVolume(
@@ -113,17 +121,20 @@
}
status_t DeviceHalHidl::setMode(audio_mode_t mode) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
if (mPrimaryDevice == 0) return INVALID_OPERATION;
return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
}
status_t DeviceHalHidl::setMicMute(bool state) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("setMicMute", mDevice->setMicMute(state));
}
status_t DeviceHalHidl::getMicMute(bool *state) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
Return<void> ret = mDevice->getMicMute(
@@ -137,11 +148,13 @@
}
status_t DeviceHalHidl::setMasterMute(bool state) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("setMasterMute", mDevice->setMasterMute(state));
}
status_t DeviceHalHidl::getMasterMute(bool *state) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
Return<void> ret = mDevice->getMasterMute(
@@ -155,6 +168,7 @@
}
status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
hidl_vec<ParameterValue> hidlParams;
status_t status = parametersFromHal(kvPairs, &hidlParams);
@@ -165,6 +179,7 @@
}
status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
+ TIME_CHECK();
values->clear();
if (mDevice == 0) return NO_INIT;
hidl_vec<hidl_string> hidlKeys;
@@ -185,6 +200,7 @@
status_t DeviceHalHidl::getInputBufferSize(
const struct audio_config *config, size_t *size) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
AudioConfig hidlConfig;
HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
@@ -207,6 +223,7 @@
struct audio_config *config,
const char *address,
sp<StreamOutHalInterface> *outStream) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
DeviceAddress hidlDevice;
if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
@@ -263,6 +280,7 @@
audio_devices_t outputDevice,
const char *outputDeviceAddress,
sp<StreamInHalInterface> *inStream) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
DeviceAddress hidlDevice;
if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
@@ -326,6 +344,7 @@
}
status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
}
@@ -336,6 +355,7 @@
unsigned int num_sinks,
const struct audio_port_config *sinks,
audio_patch_handle_t *patch) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
if (patch == nullptr) return BAD_VALUE;
@@ -381,6 +401,7 @@
}
status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
}
@@ -403,10 +424,12 @@
}
status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
+ TIME_CHECK();
return getAudioPortImpl(port);
}
status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
+ TIME_CHECK();
#if MAJOR_VERSION >= 7
return getAudioPortImpl(port);
#else
@@ -427,6 +450,7 @@
}
status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
AudioPortConfig hidlConfig;
HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
@@ -441,6 +465,7 @@
}
#elif MAJOR_VERSION >= 4
status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
Return<void> ret = mDevice->getMicrophones(
@@ -461,6 +486,7 @@
#if MAJOR_VERSION >= 6
status_t DeviceHalHidl::addDeviceEffect(
audio_port_handle_t device, sp<EffectHalInterface> effect) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
static_cast<AudioPortHandle>(device), effect->effectId()));
@@ -475,6 +501,7 @@
#if MAJOR_VERSION >= 6
status_t DeviceHalHidl::removeDeviceEffect(
audio_port_handle_t device, sp<EffectHalInterface> effect) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
static_cast<AudioPortHandle>(device), effect->effectId()));
@@ -487,6 +514,7 @@
#endif
status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
if (supportsSetConnectedState7_1) {
@@ -513,6 +541,7 @@
}
error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
audio_hw_sync_t value;
Result result;
@@ -525,6 +554,7 @@
}
status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
+ TIME_CHECK();
if (mDevice == 0) return NO_INIT;
native_handle_t* hidlHandle = native_handle_create(1, 0);
hidlHandle->data[0] = fd;
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 8ba0f72..77c2da0 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -22,6 +22,7 @@
#include <media/AudioParameter.h>
#include <mediautils/memory.h>
#include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamOutCallback.h)
@@ -45,8 +46,11 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
-StreamHalHidl::StreamHalHidl(IStream *stream)
- : ConversionHelperHidl("Stream"),
+#define TIME_CHECK() auto TimeCheck = \
+ mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
+StreamHalHidl::StreamHalHidl(std::string_view className, IStream *stream)
+ : ConversionHelperHidl(className),
mStream(stream),
mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT),
mCachedBufferSize(0){
@@ -67,6 +71,7 @@
}
status_t StreamHalHidl::getBufferSize(size_t *size) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
status_t status = processReturn("getBufferSize", mStream->getBufferSize(), size);
if (status == OK) {
@@ -76,6 +81,7 @@
}
status_t StreamHalHidl::getAudioProperties(audio_config_base_t *configBase) {
+ TIME_CHECK();
*configBase = AUDIO_CONFIG_BASE_INITIALIZER;
if (!mStream) return NO_INIT;
#if MAJOR_VERSION <= 6
@@ -105,6 +111,7 @@
}
status_t StreamHalHidl::setParameters(const String8& kvPairs) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
hidl_vec<ParameterValue> hidlParams;
status_t status = parametersFromHal(kvPairs, &hidlParams);
@@ -114,6 +121,7 @@
}
status_t StreamHalHidl::getParameters(const String8& keys, String8 *values) {
+ TIME_CHECK();
values->clear();
if (!mStream) return NO_INIT;
hidl_vec<hidl_string> hidlKeys;
@@ -134,21 +142,25 @@
}
status_t StreamHalHidl::addEffect(sp<EffectHalInterface> effect) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("addEffect", mStream->addEffect(effect->effectId()));
}
status_t StreamHalHidl::removeEffect(sp<EffectHalInterface> effect) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("removeEffect", mStream->removeEffect(effect->effectId()));
}
status_t StreamHalHidl::standby() {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("standby", mStream->standby());
}
status_t StreamHalHidl::dump(int fd, const Vector<String16>& args) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
native_handle_t* hidlHandle = native_handle_create(1, 0);
hidlHandle->data[0] = fd;
@@ -173,17 +185,20 @@
}
status_t StreamHalHidl::start() {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("start", mStream->start());
}
status_t StreamHalHidl::stop() {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("stop", mStream->stop());
}
status_t StreamHalHidl::createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info) {
+ TIME_CHECK();
Result retval;
Return<void> ret = mStream->createMmapBuffer(
minSizeFrames,
@@ -216,6 +231,7 @@
}
status_t StreamHalHidl::getMmapPosition(struct audio_mmap_position *position) {
+ TIME_CHECK();
Result retval;
Return<void> ret = mStream->getMmapPosition(
[&](Result r, const MmapPosition& hidlPosition) {
@@ -244,7 +260,7 @@
status_t StreamHalHidl::getHalPid(pid_t *pid) {
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::manager::V1_0::IServiceManager;
-
+ TIME_CHECK();
DebugInfo debugInfo;
auto ret = mStream->getDebugInfo([&] (const auto &info) {
debugInfo = info;
@@ -275,6 +291,7 @@
status_t StreamHalHidl::legacyCreateAudioPatch(const struct audio_port_config& port,
std::optional<audio_source_t> source,
audio_devices_t type) {
+ TIME_CHECK();
LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
unique_malloced_ptr<char> address;
if (strcmp(port.ext.device.address, "") != 0) {
@@ -293,6 +310,7 @@
}
status_t StreamHalHidl::legacyReleaseAudioPatch() {
+ TIME_CHECK();
AudioParameter param;
param.addInt(String8(AudioParameter::keyRouting), 0);
return setParameters(param.toString());
@@ -352,7 +370,8 @@
StreamOutHalHidl::StreamOutHalHidl(
const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& stream)
- : StreamHalHidl(stream.get()), mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
+ : StreamHalHidl("StreamOutHalHidl", stream.get())
+ , mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
}
StreamOutHalHidl::~StreamOutHalHidl() {
@@ -376,11 +395,13 @@
}
status_t StreamOutHalHidl::getFrameSize(size_t *size) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("getFrameSize", mStream->getFrameSize(), size);
}
status_t StreamOutHalHidl::getLatency(uint32_t *latency) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
if (mWriterClient == gettid() && mCommandMQ) {
return callWriterThread(
@@ -394,12 +415,14 @@
}
status_t StreamOutHalHidl::setVolume(float left, float right) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("setVolume", mStream->setVolume(left, right));
}
#if MAJOR_VERSION == 2
status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
std::vector<ParameterValue> parameters;
String8 halParameters;
@@ -410,6 +433,7 @@
}
#elif MAJOR_VERSION >= 4
status_t StreamOutHalHidl::selectPresentation(int presentationId, int programId) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("selectPresentation",
mStream->selectPresentation(presentationId, programId));
@@ -417,6 +441,7 @@
#endif
status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
*written = 0;
@@ -562,6 +587,7 @@
}
status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getRenderPosition(
@@ -575,6 +601,7 @@
}
status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getNextWriteTimestamp(
@@ -588,6 +615,7 @@
}
status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
status_t status = processReturn(
"setCallback", mStream->setCallback(new StreamOutCallback(this)));
@@ -598,6 +626,7 @@
}
status_t StreamOutHalHidl::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Return<void> ret = mStream->supportsPauseAndResume(
[&](bool p, bool r) {
@@ -608,32 +637,38 @@
}
status_t StreamOutHalHidl::pause() {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("pause", mStream->pause());
}
status_t StreamOutHalHidl::resume() {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("pause", mStream->resume());
}
status_t StreamOutHalHidl::supportsDrain(bool *supportsDrain) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("supportsDrain", mStream->supportsDrain(), supportsDrain);
}
status_t StreamOutHalHidl::drain(bool earlyNotify) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn(
"drain", mStream->drain(earlyNotify ? AudioDrain::EARLY_NOTIFY : AudioDrain::ALL));
}
status_t StreamOutHalHidl::flush() {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("pause", mStream->flush());
}
status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
if (mWriterClient == gettid() && mCommandMQ) {
return callWriterThread(
@@ -667,6 +702,7 @@
#elif MAJOR_VERSION >= 4
status_t StreamOutHalHidl::updateSourceMetadata(
const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
+ TIME_CHECK();
#if MAJOR_VERSION == 4
::android::hardware::audio::CORE_TYPES_CPP_VERSION::SourceMetadata hidlMetadata;
#else
@@ -717,6 +753,7 @@
#else
status_t StreamOutHalHidl::getDualMonoMode(audio_dual_mono_mode_t* mode) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getDualMonoMode(
@@ -730,12 +767,14 @@
}
status_t StreamOutHalHidl::setDualMonoMode(audio_dual_mono_mode_t mode) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn(
"setDualMonoMode", mStream->setDualMonoMode(static_cast<DualMonoMode>(mode)));
}
status_t StreamOutHalHidl::getAudioDescriptionMixLevel(float* leveldB) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getAudioDescriptionMixLevel(
@@ -749,12 +788,14 @@
}
status_t StreamOutHalHidl::setAudioDescriptionMixLevel(float leveldB) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn(
"setAudioDescriptionMixLevel", mStream->setAudioDescriptionMixLevel(leveldB));
}
status_t StreamOutHalHidl::getPlaybackRateParameters(audio_playback_rate_t* playbackRate) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getPlaybackRateParameters(
@@ -775,6 +816,7 @@
}
status_t StreamOutHalHidl::setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn(
"setPlaybackRateParameters", mStream->setPlaybackRateParameters(
@@ -809,6 +851,7 @@
status_t StreamOutHalHidl::setEventCallback(
const sp<StreamOutHalInterfaceEventCallback>& callback) {
+ TIME_CHECK();
if (mStream == nullptr) return NO_INIT;
mEventCallback = callback;
status_t status = processReturn(
@@ -823,12 +866,14 @@
using hardware::audio::V7_1::LatencyMode;
status_t StreamOutHalHidl::setLatencyMode(audio_latency_mode_t mode) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn(
"setLatencyMode", mStream->setLatencyMode(static_cast<LatencyMode>(mode)));
};
status_t StreamOutHalHidl::getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
Result retval;
Return<void> ret = mStream->getRecommendedLatencyModes(
@@ -869,6 +914,7 @@
status_t StreamOutHalHidl::setLatencyModeCallback(
const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) {
+ TIME_CHECK();
if (mStream == nullptr) return NO_INIT;
mLatencyModeCallback = callback;
@@ -940,7 +986,8 @@
StreamInHalHidl::StreamInHalHidl(
const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& stream)
- : StreamHalHidl(stream.get()), mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
+ : StreamHalHidl("StreamInHalHidl", stream.get())
+ , mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
}
StreamInHalHidl::~StreamInHalHidl() {
@@ -953,16 +1000,19 @@
}
status_t StreamInHalHidl::getFrameSize(size_t *size) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("getFrameSize", mStream->getFrameSize(), size);
}
status_t StreamInHalHidl::setGain(float gain) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("setGain", mStream->setGain(gain));
}
status_t StreamInHalHidl::read(void *buffer, size_t bytes, size_t *read) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
*read = 0;
@@ -1090,11 +1140,13 @@
}
status_t StreamInHalHidl::getInputFramesLost(uint32_t *framesLost) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
return processReturn("getInputFramesLost", mStream->getInputFramesLost(), framesLost);
}
status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
+ TIME_CHECK();
if (mStream == 0) return NO_INIT;
if (mReaderClient == gettid() && mCommandMQ) {
ReadParameters params;
@@ -1134,6 +1186,7 @@
#elif MAJOR_VERSION >= 4
status_t StreamInHalHidl::getActiveMicrophones(
std::vector<media::MicrophoneInfo> *microphonesInfo) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
Result retval;
Return<void> ret = mStream->getActiveMicrophones(
@@ -1152,6 +1205,7 @@
status_t StreamInHalHidl::updateSinkMetadata(const
StreamInHalInterface::SinkMetadata& sinkMetadata) {
+ TIME_CHECK();
#if MAJOR_VERSION == 4
::android::hardware::audio::CORE_TYPES_CPP_VERSION::SinkMetadata hidlMetadata;
#else
@@ -1179,12 +1233,14 @@
}
#else
status_t StreamInHalHidl::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("setPreferredMicrophoneDirection",
mStream->setMicrophoneDirection(static_cast<MicrophoneDirection>(direction)));
}
status_t StreamInHalHidl::setPreferredMicrophoneFieldDimension(float zoom) {
+ TIME_CHECK();
if (!mStream) return NO_INIT;
return processReturn("setPreferredMicrophoneFieldDimension",
mStream->setMicrophoneFieldDimension(zoom));
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 4e80e88..b5ecfd1 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -97,7 +97,7 @@
protected:
// Subclasses can not be constructed directly by clients.
- explicit StreamHalHidl(IStream *stream);
+ StreamHalHidl(std::string_view className, IStream *stream);
~StreamHalHidl() override;
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 569ea2a..c333fa6 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -30,6 +30,7 @@
"ISchedulingPolicyService.cpp",
"LimitProcessMemory.cpp",
"MemoryLeakTrackUtil.cpp",
+ "MethodStatistics.cpp",
"ProcessInfo.cpp",
"SchedulingPolicyService.cpp",
"ServiceUtilities.cpp",
diff --git a/media/utils/MethodStatistics.cpp b/media/utils/MethodStatistics.cpp
new file mode 100644
index 0000000..875c43d
--- /dev/null
+++ b/media/utils/MethodStatistics.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mediautils/MethodStatistics.h>
+
+namespace android::mediautils {
+
+// Repository for MethodStatistics Objects
+
+std::shared_ptr<std::vector<std::string>>
+getStatisticsClassesForModule(std::string_view moduleName) {
+ static const std::map<std::string, std::shared_ptr<std::vector<std::string>>> m {
+ {
+ METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL,
+ std::shared_ptr<std::vector<std::string>>(
+ new std::vector<std::string>{
+ "DeviceHalHidl",
+ "StreamInHalHidl",
+ "StreamOutHalHidl",
+ })
+ },
+ };
+ auto it = m.find({moduleName.begin(), moduleName.end()});
+ if (it == m.end()) return {};
+ return it->second;
+}
+
+static void addClassesToMap(const std::shared_ptr<std::vector<std::string>> &classNames,
+ std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> &map) {
+ if (classNames) {
+ for (const auto& className : *classNames) {
+ map.emplace(className, std::make_shared<MethodStatistics<std::string>>());
+ }
+ }
+}
+
+// singleton statistics for DeviceHalHidl StreamOutHalHidl StreamInHalHidl
+std::shared_ptr<MethodStatistics<std::string>>
+getStatisticsForClass(std::string_view className) {
+ static const std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> m =
+ // copy elided initialization of map m.
+ [](){
+ std::map<std::string, std::shared_ptr<MethodStatistics<std::string>>> m;
+ addClassesToMap(
+ getStatisticsClassesForModule(METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL),
+ m);
+ return m;
+ }();
+
+ auto it = m.find({className.begin(), className.end()});
+ if (it == m.end()) return {};
+ return it->second;
+}
+
+} // android::mediautils
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 0237977..d0dc9e1 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -20,6 +20,7 @@
#include <audio_utils/clock.h>
#include <mediautils/EventLog.h>
+#include <mediautils/MethodStatistics.h>
#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
#include "debuggerd/handler.h"
@@ -201,4 +202,24 @@
tag.c_str(), formatTime(startTime).c_str(), tid, summary.c_str());
}
+// Automatically create a TimeCheck class for a class and method.
+// This is used for Audio HIDL support.
+mediautils::TimeCheck makeTimeCheckStatsForClassMethod(
+ std::string_view className, std::string_view methodName) {
+ std::shared_ptr<MethodStatistics<std::string>> statistics =
+ mediautils::getStatisticsForClass(className);
+ if (!statistics) return {}; // empty TimeCheck.
+ return mediautils::TimeCheck(
+ std::string(className).append("::").append(methodName),
+ [ clazz = std::string(className), method = std::string(methodName),
+ stats = std::move(statistics) ]
+ (bool timeout, float elapsedMs) {
+ if (timeout) {
+ ; // ignored, there is no timeout value.
+ } else {
+ stats->event(method, elapsedMs);
+ }
+ }, 0 /* timeoutMs */);
+}
+
} // namespace android::mediautils
diff --git a/media/utils/include/mediautils/MethodStatistics.h b/media/utils/include/mediautils/MethodStatistics.h
index 7d8061d..700fbaa 100644
--- a/media/utils/include/mediautils/MethodStatistics.h
+++ b/media/utils/include/mediautils/MethodStatistics.h
@@ -19,6 +19,7 @@
#include <map>
#include <mutex>
#include <string>
+#include <vector>
#include <android-base/thread_annotations.h>
#include <audio_utils/Statistics.h>
@@ -91,9 +92,16 @@
std::string dump() const {
std::stringstream ss;
std::lock_guard lg(mLock);
- for (const auto &[code, stats] : mStatisticsMap) {
- ss << int(code) << " " << getMethodForCode(code) <<
- " n=" << stats.getN() << " " << stats.toString() << "\n";
+ if constexpr (std::is_same_v<Code, std::string>) {
+ for (const auto &[code, stats] : mStatisticsMap) {
+ ss << code <<
+ " n=" << stats.getN() << " " << stats.toString() << "\n";
+ }
+ } else /* constexpr */ {
+ for (const auto &[code, stats] : mStatisticsMap) {
+ ss << int(code) << " " << getMethodForCode(code) <<
+ " n=" << stats.getN() << " " << stats.toString() << "\n";
+ }
}
return ss.str();
}
@@ -104,6 +112,18 @@
std::map<Code, StatsType> mStatisticsMap GUARDED_BY(mLock);
};
+// Managed Statistics support.
+// Supported Modules
+#define METHOD_STATISTICS_MODULE_NAME_AUDIO_HIDL "AudioHidl"
+
+// Returns a vector of class names for the module, or a nullptr if module not found.
+std::shared_ptr<std::vector<std::string>>
+getStatisticsClassesForModule(std::string_view moduleName);
+
+// Returns a statistics object for that class, or a nullptr if class not found.
+std::shared_ptr<MethodStatistics<std::string>>
+getStatisticsForClass(std::string_view className);
+
// Only if used, requires IBinder.h to be included at the location of invocation.
#define METHOD_STATISTICS_BINDER_CODE_NAMES(CODE_TYPE) \
{(CODE_TYPE)IBinder::PING_TRANSACTION , "ping"}, \
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index d5130b0..ef03aef 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -99,4 +99,9 @@
const TimerThread::Handle mTimerHandle = TimerThread::INVALID_HANDLE;
};
+// Returns a TimeCheck object that sends info to MethodStatistics
+// obtained from getStatisticsForClass(className).
+TimeCheck makeTimeCheckStatsForClassMethod(
+ std::string_view className, std::string_view methodName);
+
} // namespace android::mediautils