Add standby mode for aaudio service stream.
When the stream is stopped, everything will remain open but just stop
writing data. But this will keep the DSP running and using power
until the stream is closed.
To resolve this issue, the solution is to put the stream into standby
mode so that the HAL can release the corresponding resource.
When the HAL releases the resource, the shared file descriptor will also
be released. In that case, when the stream is restarted, AAudioService
needs to recreate shared buffer and the client needs to replace the new
shared buffer.
Test: atest AAudioTests
Test: test_steal_exclusive
Bug: 201000721
Bug: 196394385
Bug: 167345722
Bug: 208619472
Change-Id: Ib4f98e7aee72c2e56acd7f2f0ac378a94ec26241
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index dddd69f..b2ba725 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -116,6 +116,11 @@
*/
aaudio_result_t flush() EXCLUDES(mLock);
+ /**
+ * Exit standby mode. The MMAP buffer will be reallocated.
+ */
+ aaudio_result_t exitStandby(AudioEndpointParcelable *parcelable) EXCLUDES(mLock);
+
virtual aaudio_result_t startClient(const android::AudioClient& client,
const audio_attributes_t *attr __unused,
audio_port_handle_t *clientHandle __unused) {
@@ -314,6 +319,33 @@
mDisconnected = flag;
}
+ virtual aaudio_result_t standby_l() REQUIRES(mLock) {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+ class ExitStandbyParam : public AAudioCommandParam {
+ public:
+ ExitStandbyParam(AudioEndpointParcelable* parcelable)
+ : AAudioCommandParam(), mParcelable(parcelable) { }
+ ~ExitStandbyParam() = default;
+
+ AudioEndpointParcelable* mParcelable;
+ };
+ virtual aaudio_result_t exitStandby_l(
+ AudioEndpointParcelable* parcelable __unused) REQUIRES(mLock) {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+ bool isStandby_l() const REQUIRES(mLock) {
+ return mStandby;
+ }
+ void setStandby_l(bool standby) REQUIRES(mLock) {
+ mStandby = standby;
+ }
+
+ bool isIdle_l() const REQUIRES(mLock) {
+ return mState == AAUDIO_STREAM_STATE_OPEN || mState == AAUDIO_STREAM_STATE_PAUSED
+ || mState == AAUDIO_STREAM_STATE_STOPPED;
+ }
+
pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID;
std::mutex mUpMessageQueueLock;
@@ -329,6 +361,7 @@
REGISTER_AUDIO_THREAD,
UNREGISTER_AUDIO_THREAD,
GET_DESCRIPTION,
+ EXIT_STANDBY,
};
AAudioThread mCommandThread;
std::atomic<bool> mThreadEnabled{false};
@@ -391,6 +424,8 @@
bool mDisconnected GUARDED_BY(mLock) {false};
+ bool mStandby GUARDED_BY(mLock) = false;
+
protected:
// Locking order is important.
// Acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams