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/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