audio: Add optional 'DriverInterface::getPosition' method.
This is a method which can be optionally implemented
by a stream in case it can provide more exact position,
for example by taking into account data in intermediate
buffers.
Implemented this method for StreamAlsa and StreamRemoteSubmix.
Bug: 264712385
Test: atest VtsHalAudioCoreTargetTest
Change-Id: I392933f8f6b22d784726925199db00dcb0313648
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index ecb3c78..17c7feb 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <Utils.h>
+#include <audio_utils/clock.h>
#include <error/expected_utils.h>
#include "core-impl/StreamAlsa.h"
@@ -96,6 +97,37 @@
return ::android::OK;
}
+::android::status_t StreamAlsa::getPosition(StreamDescriptor::Position* position) {
+ if (mAlsaDeviceProxies.empty()) {
+ LOG(FATAL) << __func__ << ": no input devices";
+ return ::android::NO_INIT;
+ }
+ if (mIsInput) {
+ if (int ret = proxy_get_capture_position(mAlsaDeviceProxies[0].get(), &position->frames,
+ &position->timeNs);
+ ret != 0) {
+ LOG(WARNING) << __func__ << ": failed to retrieve capture position: " << ret;
+ return ::android::INVALID_OPERATION;
+ }
+ } else {
+ uint64_t hwFrames;
+ struct timespec timestamp;
+ if (int ret = proxy_get_presentation_position(mAlsaDeviceProxies[0].get(), &hwFrames,
+ ×tamp);
+ ret == 0) {
+ if (hwFrames > std::numeric_limits<int64_t>::max()) {
+ hwFrames -= std::numeric_limits<int64_t>::max();
+ }
+ position->frames = static_cast<int64_t>(hwFrames);
+ position->timeNs = audio_utils_ns_from_timespec(×tamp);
+ } else {
+ LOG(WARNING) << __func__ << ": failed to retrieve presentation position: " << ret;
+ return ::android::INVALID_OPERATION;
+ }
+ }
+ return ::android::OK;
+}
+
void StreamAlsa::shutdown() {
mAlsaDeviceProxies.clear();
}