blob: b8dd6e410ee5abf4de790e08745f1e939a9555e5 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MEDIA_AUDIO_DRIVERS_TEST_AUDIO_DRIVER_TEST_H_
#define SRC_MEDIA_AUDIO_DRIVERS_TEST_AUDIO_DRIVER_TEST_H_
#include <fuchsia/media/cpp/fidl.h>
#include <lib/fzl/vmo-mapper.h>
#include <zircon/device/audio.h>
#include "lib/fsl/io/device_watcher.h"
#include "src/media/audio/lib/test/message_transceiver.h"
#include "src/media/audio/lib/test/test_fixture.h"
namespace media::audio::test {
constexpr size_t kUniqueIdLength = 16;
enum DeviceType { Input, Output };
class AudioDriverTest : public TestFixture {
protected:
static void SetUpTestSuite();
static zx_txid_t NextTransactionId();
void SetUp() override;
void TearDown() override;
bool WaitForDevice(DeviceType device_type);
void AddDevice(int dir_fd, const std::string& name, DeviceType device_type);
void RequestUniqueId();
void RequestManufacturerString();
void RequestProductString();
void RequestGain();
void RequestSetGain();
void RequestSetGain(audio_set_gain_flags_t flags, float gain_db);
void RequestFormats();
void SelectFirstFormat();
void SelectLastFormat();
void RequestSetFormatMin();
void RequestSetFormatMax();
void RequestPlugDetect();
void RequestFifoDepth();
void RequestBuffer(uint32_t min_ring_buffer_frames, uint32_t notifications_per_ring);
void RequestStart();
void RequestStop();
void OnInboundStreamMessage(MessageTransceiver::Message message);
bool ValidateResponseCommand(audio_cmd_hdr header, audio_cmd_t expected_command);
void ValidateResponseTransaction(audio_cmd_hdr header, zx_txid_t expected_transaction_id);
bool ValidateResponseHeader(audio_cmd_hdr header, zx_txid_t expected_transaction_id,
audio_cmd_t expected_command);
void HandleGetUniqueIdResponse(const audio_stream_cmd_get_unique_id_resp_t& response);
void HandleGetStringResponse(const audio_stream_cmd_get_string_resp_t& response);
void HandleGetGainResponse(const audio_stream_cmd_get_gain_resp_t& response);
void HandleSetGainResponse(const audio_stream_cmd_set_gain_resp_t& response);
void HandleGetFormatsResponse(const audio_stream_cmd_get_formats_resp_t& response);
void HandleSetFormatResponse(const audio_stream_cmd_set_format_resp_t& response);
void CalculateFrameSize();
void HandlePlugDetect(audio_pd_notify_flags_t flags, zx_time_t plug_state_time);
void HandlePlugDetectResponse(const audio_stream_cmd_plug_detect_resp_t& response);
void HandlePlugDetectNotify(const audio_stream_cmd_plug_detect_resp_t& notify);
void ExtractRingBufferChannel(MessageTransceiver::Message set_format_response);
void OnInboundRingBufferMessage(MessageTransceiver::Message message);
void HandleGetFifoDepthResponse(const audio_rb_cmd_get_fifo_depth_resp_t& response);
void HandleGetBufferResponse(const audio_rb_cmd_get_buffer_resp_t& response);
void ExtractRingBuffer(MessageTransceiver::Message get_buffer_response);
void HandleStartResponse(const audio_rb_cmd_start_resp_t& response);
void HandleStopResponse(const audio_rb_cmd_stop_resp_t& response);
void HandlePositionNotify(const audio_rb_position_notify_t& notify);
void ExpectPositionNotifyCount(uint32_t count);
void ExpectNoPositionNotifications();
const MessageTransceiver& stream_transceiver() { return stream_transceiver_; }
const MessageTransceiver& ring_buffer_transceiver() { return ring_buffer_transceiver_; }
private:
static std::atomic_uint32_t unique_transaction_id_;
static bool no_input_devices_found_;
static bool no_output_devices_found_;
std::vector<std::unique_ptr<fsl::DeviceWatcher>> watchers_;
DeviceType device_type_;
zx::channel stream_channel_;
bool stream_channel_ready_ = false;
bool ring_buffer_channel_ready_ = false;
bool ring_buffer_ready_ = false;
MessageTransceiver stream_transceiver_;
MessageTransceiver ring_buffer_transceiver_;
zx_txid_t unique_id_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t manufacturer_string_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t product_string_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t get_gain_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t get_formats_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t set_gain_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t set_format_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t plug_detect_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t get_fifo_depth_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t get_buffer_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t start_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t stop_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
zx_txid_t get_position_transaction_id_ = AUDIO_INVALID_TRANSACTION_ID;
std::array<uint8_t, kUniqueIdLength> unique_id_;
std::string manufacturer_;
std::string product_;
bool cur_mute_ = false;
bool can_mute_ = false;
bool set_mute_ = false;
bool cur_agc_ = false;
bool can_agc_ = false;
bool set_agc_ = false;
float cur_gain_ = 0.0f;
float min_gain_ = 0.0f;
float max_gain_ = 0.0f;
float gain_step_ = 0.0f;
float set_gain_ = 0.0f;
std::vector<audio_stream_format_range_t> format_ranges_;
uint16_t get_formats_range_count_ = 0;
uint16_t next_format_range_ndx_ = 0;
uint64_t external_delay_nsec_ = 0;
uint32_t frame_rate_ = 0;
audio_sample_format_t sample_format_ = 0;
uint16_t num_channels_ = 0;
uint16_t frame_size_ = 0;
bool hardwired_ = false;
bool should_plug_notify_ = false;
bool can_plug_notify_ = false;
bool plugged_ = false;
zx_time_t plug_state_time_ = 0;
uint32_t fifo_depth_ = 0;
uint32_t min_ring_buffer_frames_ = 0;
uint32_t notifications_per_ring_ = 0;
uint32_t ring_buffer_frames_ = 0;
fzl::VmoMapper ring_buffer_;
zx_time_t start_time_ = 0;
uint32_t ring_buffer_position_ = 0;
zx_time_t last_monotonic_time_ = 0;
bool received_get_unique_id_ = false;
bool received_get_string_manufacturer_ = false;
bool received_get_string_product_ = false;
bool received_get_gain_ = false;
bool received_get_formats_ = false;
bool received_set_gain_ = false;
bool received_set_format_ = false;
bool received_plug_detect_ = false;
bool received_plug_detect_notify_ = false;
bool received_get_fifo_depth_ = false;
bool received_get_buffer_ = false;
bool received_start_ = false;
bool received_stop_ = false;
uint32_t position_notification_count_ = 0;
};
} // namespace media::audio::test
#endif // SRC_MEDIA_AUDIO_DRIVERS_TEST_AUDIO_DRIVER_TEST_H_