PatchPanel: Add latency information for software patches
Test: audioflinger dumpsys when patches present
Bug: 80546849
Change-Id: Ib5b26e065ab20b5f8d530db57398e7b4a59ed1f1
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 3d688fb..c2927ba 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -475,11 +475,48 @@
mPlayback.closeConnections(panel);
}
+status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
+{
+ if (!isSoftware()) return INVALID_OPERATION;
+
+ auto recordTrack = mRecord.const_track();
+ if (recordTrack.get() == nullptr) return INVALID_OPERATION;
+
+ auto playbackTrack = mPlayback.const_track();
+ if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
+
+ // Latency information for tracks may be called without obtaining
+ // the underlying thread lock.
+ //
+ // We use record server latency + playback track latency (generally smaller than the
+ // reverse due to internal biases).
+ //
+ // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
+ double recordServerLatencyMs;
+ if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) != OK) return INVALID_OPERATION;
+
+ double playbackTrackLatencyMs;
+ if (playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) != OK) return INVALID_OPERATION;
+
+ *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
+ return OK;
+}
+
String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle)
{
String8 result;
- result.appendFormat("Patch %d: thread %p => thread %p\n",
+
+ // TODO: Consider table dump form for patches, just like tracks.
+ result.appendFormat("Patch %d: thread %p => thread %p",
myHandle, mRecord.thread().get(), mPlayback.thread().get());
+
+ // add latency if it exists
+ double latencyMs;
+ if (getLatencyMs(&latencyMs) == OK) {
+ result.appendFormat(" latency: %.2lf", latencyMs);
+ }
+
+ result.append("\n");
return result;
}
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index dff8ad2..5d6bf00 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -65,6 +65,7 @@
audio_patch_handle_t handle() const { return mHandle; }
sp<ThreadType> thread() { return mThread; }
sp<TrackType> track() { return mTrack; }
+ sp<const TrackType> const_track() const { return mTrack; }
void closeConnections(PatchPanel *panel) {
if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
@@ -118,6 +119,9 @@
return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
+ // returns the latency of the patch (from record to playback).
+ status_t getLatencyMs(double *latencyMs) const;
+
String8 dump(audio_patch_handle_t myHandle);
// Note that audio_patch::id is only unique within a HAL module