blob: ad62d8a9b81cf0626f70b3aebca47bde20efd5ca [file] [log] [blame]
/*
* 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 {
using aaudio_command_opcode = int32_t;
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(std::move(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(const 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);
/**
* Start waiting for commands. Commands can only be pushed into the command queue after it
* starts waiting.
*/
void startWaiting();
/**
* 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) = false;
};
} // namespace aaudio