Merge changes Ia7f3461d,I169d9f23 into main
* changes:
libaudiohal@aidl: adjust pause and flush for a stream
libaudiohal@aidl: Fix drain expectation
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 94de8ea..7a80a6a 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -417,8 +417,16 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- return sendCommand(makeHalCommand<HalCommand::Tag::pause>(), reply,
- true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+
+ if (const auto state = getState(); isInPlayOrRecordState(state)) {
+ return sendCommand(
+ makeHalCommand<HalCommand::Tag::pause>(), reply,
+ true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+ } else {
+ ALOGD("%s: already stream in one of the PAUSED kind of states, current state: %s", __func__,
+ toString(state).c_str());
+ return OK;
+ }
}
status_t StreamHalAidl::resume(StreamDescriptor::Reply* reply) {
@@ -473,8 +481,19 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- return sendCommand(makeHalCommand<HalCommand::Tag::flush>(), reply,
- true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+
+ if (const auto state = getState(); isInPausedState(state)) {
+ return sendCommand(
+ makeHalCommand<HalCommand::Tag::flush>(), reply,
+ true /*safeFromNonWorkerThread*/); // The workers stops its I/O activity first.
+ } else if (isInPlayOrRecordState(state)) {
+ ALOGE("%s: found stream in non-flushable state: %s", __func__, toString(state).c_str());
+ return INVALID_OPERATION;
+ } else {
+ ALOGD("%s: already stream in one of the flushable state: current state: %s", __func__,
+ toString(state).c_str());
+ return OK;
+ }
}
status_t StreamHalAidl::exit() {
@@ -798,9 +817,9 @@
status_t StreamOutHalAidl::drain(bool earlyNotify) {
if (!mStream) return NO_INIT;
- if(const auto state = getState(); state == StreamDescriptor::State::IDLE) {
- ALOGD("%p %s stream already in IDLE state", this, __func__);
- if(mContext.isAsynchronous()) onDrainReady();
+ if (const auto state = getState(); isInDrainedState(state)) {
+ ALOGD("%p %s stream already in %s", this, __func__, toString(state).c_str());
+ if (mContext.isAsynchronous()) onDrainReady();
return OK;
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 0587640..baf4ac0 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -220,6 +220,41 @@
return mLastReply.state;
}
+ bool isInDrainedState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::IDLE ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::STANDBY) {
+ // drain equivalent states
+ return true;
+ }
+ return false;
+ }
+
+ bool isInPlayOrRecordState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::ACTIVE ||
+ state ==
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State::TRANSFERRING ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAINING) {
+ // play or record equivalent states
+ return true;
+ }
+ return false;
+ }
+
+ bool isInPausedState(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor::State& state) {
+ if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::PAUSED ||
+ state ==
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAIN_PAUSED ||
+ state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::
+ TRANSFER_PAUSED) {
+ // pause equivalent states
+ return true;
+ }
+ return false;
+ }
+
status_t getLatency(uint32_t *latency);
// Always returns non-negative values.