1 /* 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 27 namespace aaudio { 28 29 using aaudio_command_opcode = int32_t; 30 31 class AAudioCommandParam { 32 public: 33 AAudioCommandParam() = default; 34 virtual ~AAudioCommandParam() = default; 35 }; 36 37 class AAudioCommand { 38 public: 39 explicit AAudioCommand( 40 aaudio_command_opcode opCode, std::shared_ptr<AAudioCommandParam> param = nullptr, 41 bool waitForReply = false, int64_t timeoutNanos = 0) operationCode(opCode)42 : operationCode(opCode), parameter(std::move(param)), isWaitingForReply(waitForReply), 43 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 56 class AAudioCommandQueue { 57 public: 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 */ 69 aaudio_result_t sendCommand(const std::shared_ptr<AAudioCommand>& command); 70 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 /** 81 * Start waiting for commands. Commands can only be pushed into the command queue after it 82 * starts waiting. 83 */ 84 void startWaiting(); 85 86 /** 87 * Force stop waiting for next command 88 */ 89 void stopWaiting(); 90 91 private: 92 std::mutex mLock; 93 std::condition_variable mWaitWorkCond; 94 95 std::queue<std::shared_ptr<AAudioCommand>> mCommands GUARDED_BY(mLock); 96 bool mRunning GUARDED_BY(mLock) = false; 97 }; 98 99 } // namespace aaudio