From f74df70fd777cc2fa426e992c64c1f4aa78a9122 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 19 May 2017 16:46:28 -0700 Subject: [PATCH] audiohal: Prevent logspam when calling get_presentation_position get_presentation_position can return ENODATA if the stream has stopped but the write is still querying the position. Bug: 38376424 Change-Id: I9d516a19fb347843a8ec8e8e9a0f5eab0b0798e6 Test: no log messages from StreamHAL about get_presentation_position (cherry picked from commit 96a3a19beda45bef7c34fc06a0048174f3a7e362) --- audio/2.0/default/Stream.cpp | 16 ++++++++++++++-- audio/2.0/default/Stream.h | 9 ++++++--- audio/2.0/default/StreamIn.cpp | 12 ++++++------ audio/2.0/default/StreamOut.cpp | 15 ++++++++------- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/audio/2.0/default/Stream.cpp b/audio/2.0/default/Stream.cpp index 671f1710da..effdd28507 100644 --- a/audio/2.0/default/Stream.cpp +++ b/audio/2.0/default/Stream.cpp @@ -44,8 +44,20 @@ Stream::~Stream() { } // static -Result Stream::analyzeStatus(const char* funcName, int status, int ignoreError, int ignoreError2) { - if (status != 0 && status != -ignoreError && status != -ignoreError2) { +Result Stream::analyzeStatus(const char* funcName, int status) { + static const std::vector empty; + return analyzeStatus(funcName, status, empty); +} + +template +inline bool element_in(T e, const std::vector& v) { + return std::find(v.begin(), v.end(), e) != v.end(); +} + +// static +Result Stream::analyzeStatus(const char* funcName, int status, + const std::vector& ignoreErrors) { + if (status != 0 && (ignoreErrors.empty() || !element_in(-status, ignoreErrors))) { ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status)); } switch (status) { diff --git a/audio/2.0/default/Stream.h b/audio/2.0/default/Stream.h index b49e658273..82f05a77b4 100644 --- a/audio/2.0/default/Stream.h +++ b/audio/2.0/default/Stream.h @@ -17,6 +17,8 @@ #ifndef ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H #define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H +#include + #include #include #include @@ -79,10 +81,11 @@ struct Stream : public IStream, public ParametersUtil { Return close() override; // Utility methods for extending interfaces. - static Result analyzeStatus( - const char* funcName, int status, int ignoreError = OK, int ignoreError2 = OK); + static Result analyzeStatus(const char* funcName, int status); + static Result analyzeStatus(const char* funcName, int status, + const std::vector& ignoreErrors); - private: + private: audio_stream_t *mStream; virtual ~Stream(); diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp index abd0497fe1..b81cbb924f 100644 --- a/audio/2.0/default/StreamIn.cpp +++ b/audio/2.0/default/StreamIn.cpp @@ -416,15 +416,15 @@ Return StreamIn::getInputFramesLost() { // static Result StreamIn::getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, uint64_t* time) { + // HAL may have a stub function, always returning ENOSYS, don't + // spam the log in this case. + static const std::vector ignoredErrors{ENOSYS}; Result retval(Result::NOT_SUPPORTED); if (stream->get_capture_position != NULL) return retval; int64_t halFrames, halTime; - retval = Stream::analyzeStatus( - "get_capture_position", - stream->get_capture_position(stream, &halFrames, &halTime), - // HAL may have a stub function, always returning ENOSYS, don't - // spam the log in this case. - ENOSYS); + retval = Stream::analyzeStatus("get_capture_position", + stream->get_capture_position(stream, &halFrames, &halTime), + ignoredErrors); if (retval == Result::OK) { *frames = halFrames; *time = halTime; diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp index e48497f6c6..290d0b103c 100644 --- a/audio/2.0/default/StreamOut.cpp +++ b/audio/2.0/default/StreamOut.cpp @@ -487,16 +487,17 @@ Return StreamOut::flush() { Result StreamOut::getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames, TimeSpec* timeStamp) { + // Don't logspam on EINVAL--it's normal for get_presentation_position + // to return it sometimes. EAGAIN may be returned by A2DP audio HAL + // implementation. ENODATA can also be reported while the writer is + // continuously querying it, but the stream has been stopped. + static const std::vector ignoredErrors{EINVAL, EAGAIN, ENODATA}; Result retval(Result::NOT_SUPPORTED); if (stream->get_presentation_position == NULL) return retval; struct timespec halTimeStamp; - retval = Stream::analyzeStatus( - "get_presentation_position", - stream->get_presentation_position(stream, frames, &halTimeStamp), - // Don't logspam on EINVAL--it's normal for get_presentation_position - // to return it sometimes. EAGAIN may be returned by A2DP audio HAL - // implementation. - EINVAL, EAGAIN); + retval = Stream::analyzeStatus("get_presentation_position", + stream->get_presentation_position(stream, frames, &halTimeStamp), + ignoredErrors); if (retval == Result::OK) { timeStamp->tvSec = halTimeStamp.tv_sec; timeStamp->tvNSec = halTimeStamp.tv_nsec;