Add AAudioCommandQueue in aaudio service.
With AAudioCommandQueue, all the requests to aaudio service stream can
be turned into command and executed one by one. This can help reduce
multiple thread issue in aaudio service.
Test: atest AAudioTest
Test: run oboetester
Bug: 201000721
Change-Id: I81134e036d8921d327feb029d8fda725ce65d080
diff --git a/services/oboeservice/AAudioCommandQueue.h b/services/oboeservice/AAudioCommandQueue.h
new file mode 100644
index 0000000..5f25507
--- /dev/null
+++ b/services/oboeservice/AAudioCommandQueue.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <queue>
+
+#include <aaudio/AAudio.h>
+#include <android-base/thread_annotations.h>
+
+namespace aaudio {
+
+typedef int32_t aaudio_command_opcode;
+
+class AAudioCommandParam {
+public:
+ AAudioCommandParam() = default;
+ virtual ~AAudioCommandParam() = default;
+};
+
+class AAudioCommand {
+public:
+ explicit AAudioCommand(
+ aaudio_command_opcode opCode, std::shared_ptr<AAudioCommandParam> param = nullptr,
+ bool waitForReply = false, int64_t timeoutNanos = 0)
+ : operationCode(opCode), parameter(param), isWaitingForReply(waitForReply),
+ timeoutNanoseconds(timeoutNanos) { }
+ virtual ~AAudioCommand() = default;
+
+ std::mutex lock;
+ std::condition_variable conditionVariable;
+
+ const aaudio_command_opcode operationCode;
+ std::shared_ptr<AAudioCommandParam> parameter;
+ bool isWaitingForReply GUARDED_BY(lock);
+ const int64_t timeoutNanoseconds;
+ aaudio_result_t result GUARDED_BY(lock) = AAUDIO_OK;
+};
+
+class AAudioCommandQueue {
+public:
+ AAudioCommandQueue() = default;
+ ~AAudioCommandQueue() = default;
+
+ /**
+ * Send a command to the command queue. The return will be waiting for a specified timeout
+ * period indicated by the command if it is required.
+ *
+ * @param command the command to send to the command queue.
+ * @return the result of sending the command or the result of executing the command if command
+ * need to wait for a reply. If timeout happens, AAUDIO_ERROR_TIMEOUT will be returned.
+ */
+ aaudio_result_t sendCommand(std::shared_ptr<AAudioCommand> command);
+
+ /**
+ * Wait for next available command OR until the timeout is expired.
+ *
+ * @param timeoutNanos the maximum time to wait for next command (0 means return immediately in
+ * any case), negative to wait forever.
+ * @return the next available command if any or a nullptr when there is none.
+ */
+ std::shared_ptr<AAudioCommand> waitForCommand(int64_t timeoutNanos = -1);
+
+ /**
+ * Force stop waiting for next command
+ */
+ void stopWaiting();
+
+private:
+ std::mutex mLock;
+ std::condition_variable mWaitWorkCond;
+
+ std::queue<std::shared_ptr<AAudioCommand>> mCommands GUARDED_BY(mLock);
+ bool mRunning GUARDED_BY(mLock) = true;
+};
+
+} // namespace aaudio
\ No newline at end of file