blob: ad62d8a9b81cf0626f70b3aebca47bde20efd5ca [file] [log] [blame]
jiabin2a594622021-10-14 00:32:25 +00001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <condition_variable>
20#include <memory>
21#include <mutex>
22#include <queue>
23
24#include <aaudio/AAudio.h>
25#include <android-base/thread_annotations.h>
26
27namespace aaudio {
28
jiabin613e6ae2022-12-21 20:20:11 +000029using aaudio_command_opcode = int32_t;
jiabin2a594622021-10-14 00:32:25 +000030
31class AAudioCommandParam {
32public:
33 AAudioCommandParam() = default;
34 virtual ~AAudioCommandParam() = default;
35};
36
37class AAudioCommand {
38public:
39 explicit AAudioCommand(
40 aaudio_command_opcode opCode, std::shared_ptr<AAudioCommandParam> param = nullptr,
41 bool waitForReply = false, int64_t timeoutNanos = 0)
jiabin613e6ae2022-12-21 20:20:11 +000042 : operationCode(opCode), parameter(std::move(param)), isWaitingForReply(waitForReply),
jiabin2a594622021-10-14 00:32:25 +000043 timeoutNanoseconds(timeoutNanos) { }
44 virtual ~AAudioCommand() = default;
45
46 std::mutex lock;
47 std::condition_variable conditionVariable;
48
49 const aaudio_command_opcode operationCode;
50 std::shared_ptr<AAudioCommandParam> parameter;
51 bool isWaitingForReply GUARDED_BY(lock);
52 const int64_t timeoutNanoseconds;
53 aaudio_result_t result GUARDED_BY(lock) = AAUDIO_OK;
54};
55
56class AAudioCommandQueue {
57public:
58 AAudioCommandQueue() = default;
59 ~AAudioCommandQueue() = default;
60
61 /**
62 * Send a command to the command queue. The return will be waiting for a specified timeout
63 * period indicated by the command if it is required.
64 *
65 * @param command the command to send to the command queue.
66 * @return the result of sending the command or the result of executing the command if command
67 * need to wait for a reply. If timeout happens, AAUDIO_ERROR_TIMEOUT will be returned.
68 */
jiabin613e6ae2022-12-21 20:20:11 +000069 aaudio_result_t sendCommand(const std::shared_ptr<AAudioCommand>& command);
jiabin2a594622021-10-14 00:32:25 +000070
71 /**
72 * Wait for next available command OR until the timeout is expired.
73 *
74 * @param timeoutNanos the maximum time to wait for next command (0 means return immediately in
75 * any case), negative to wait forever.
76 * @return the next available command if any or a nullptr when there is none.
77 */
78 std::shared_ptr<AAudioCommand> waitForCommand(int64_t timeoutNanos = -1);
79
80 /**
jiabinba75f212021-12-07 20:06:30 +000081 * Start waiting for commands. Commands can only be pushed into the command queue after it
82 * starts waiting.
83 */
84 void startWaiting();
85
86 /**
jiabin2a594622021-10-14 00:32:25 +000087 * Force stop waiting for next command
88 */
89 void stopWaiting();
90
91private:
92 std::mutex mLock;
93 std::condition_variable mWaitWorkCond;
94
95 std::queue<std::shared_ptr<AAudioCommand>> mCommands GUARDED_BY(mLock);
jiabinba75f212021-12-07 20:06:30 +000096 bool mRunning GUARDED_BY(mLock) = false;
jiabin2a594622021-10-14 00:32:25 +000097};
98
99} // namespace aaudio