pebble/tests/fw/services/test_audio_endpoint.c
2025-01-27 11:38:16 -08:00

155 lines
5.2 KiB
C

/*
* Copyright 2024 Google LLC
*
* 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.
*/
#include "clar.h"
#include "services/normal/audio_endpoint.h"
#include "services/normal/audio_endpoint_private.h"
#include "util/circular_buffer.h"
#include "util/list.h"
#include "stubs_bt_lock.h"
#include "stubs_hexdump.h"
#include "stubs_logging.h"
#include "stubs_passert.h"
#include "fake_session.h"
#include "fake_system_task.h"
#include "fake_new_timer.h"
extern void audio_endpoint_protocol_msg_callback(CommSession *session,
const uint8_t* data, size_t size);
static AudioEndpointSessionId s_session_id;
static uint8_t s_test_frame[] = {
0x01, 0x02, 0x03, 0x04,
};
static CommSession *s_session;
static void prv_test_data_transfer_msg(uint16_t endpoint_id, const uint8_t* data,
unsigned int length) {
DataTransferMsg *msg = (DataTransferMsg *)data;
cl_assert(msg->msg_id == MsgIdDataTransfer);
cl_assert(msg->session_id == s_session_id);
for (unsigned int i = 0; i < msg->frame_count; i += (sizeof(msg->frame_count) +
sizeof(s_test_frame))) {
cl_assert(msg->frames[i] == sizeof(s_test_frame));
for (unsigned int j = 0; j < sizeof(s_test_frame); j++) {
cl_assert(msg->frames[i + sizeof(msg->frame_count) + j] == s_test_frame[j]);
}
}
}
static void prv_test_stop_transfer_msg(uint16_t endpoint_id, const uint8_t* data,
unsigned int length) {
StopTransferMsg *msg = (StopTransferMsg *)data;
cl_assert(msg->msg_id == MsgIdStopTransfer);
cl_assert(msg->session_id == s_session_id);
}
static int s_setup_complete_call_count;
static void prv_test_setup_complete_callback(AudioEndpointSessionId session_id) {
cl_assert(session_id == s_session_id);
++s_setup_complete_call_count;
}
static void prv_test_stop_transfer_callback(AudioEndpointSessionId session_id) {
cl_assert(session_id == s_session_id);
}
Transport *s_transport;
void test_audio_endpoint__initialize(void) {
fake_comm_session_init();
s_setup_complete_call_count = 0;
s_transport = fake_transport_create(TransportDestinationSystem, NULL, NULL);
s_session = fake_transport_set_connected(s_transport, true);
s_session_id = audio_endpoint_setup_transfer(prv_test_setup_complete_callback,
prv_test_stop_transfer_callback);
cl_assert(s_session_id != AUDIO_ENDPOINT_SESSION_INVALID_ID);
}
void test_audio_endpoint__setup_complete_callback_call_once(void) {
ResponsivenessGrantedHandler granted_handler =
fake_comm_session_get_last_responsiveness_granted_handler();
cl_assert_equal_i(s_setup_complete_call_count, 0);
granted_handler();
cl_assert_equal_i(s_setup_complete_call_count, 1);
granted_handler();
cl_assert_equal_i(s_setup_complete_call_count, 1);
audio_endpoint_stop_transfer(s_session_id);
}
void test_audio_endpoint__dont_call_setup_complete_callback_if_session_stopped(void) {
ResponsivenessGrantedHandler granted_handler =
fake_comm_session_get_last_responsiveness_granted_handler();
audio_endpoint_stop_transfer(s_session_id);
granted_handler();
cl_assert_equal_i(s_setup_complete_call_count, 0);
}
void test_audio_endpoint__session_control(void) {
// Test that it is not possible to start another transfer session if one is already on-going:
AudioEndpointSessionId session_id = audio_endpoint_setup_transfer(NULL, NULL);
cl_assert(session_id == AUDIO_ENDPOINT_SESSION_INVALID_ID);
audio_endpoint_stop_transfer(s_session_id);
fake_transport_set_sent_cb(s_transport, prv_test_stop_transfer_msg);
fake_comm_session_process_send_next();
}
void test_audio_endpoint__buffer_overflow(void) {
// add a huge number of frames (1 kB) to the buffer to cause it to overflow
for (unsigned int i = 0; i < 1024 / (sizeof(DataTransferMsg) + sizeof(s_test_frame)); i++) {
audio_endpoint_add_frame(s_session_id, s_test_frame, sizeof(s_test_frame));
}
fake_transport_set_sent_cb(s_transport, prv_test_data_transfer_msg);
fake_comm_session_process_send_next();
audio_endpoint_stop_transfer(s_session_id);
fake_transport_set_sent_cb(s_transport, prv_test_stop_transfer_msg);
fake_comm_session_process_send_next();
}
void test_audio_endpoint__remote_stop_transfer(void) {
StopTransferMsg *msg = (StopTransferMsg *)malloc(sizeof(StopTransferMsg));
msg->msg_id = MsgIdStopTransfer;
msg->session_id = s_session_id;
audio_endpoint_protocol_msg_callback(s_session, (uint8_t *)msg, sizeof(StopTransferMsg));
fake_system_task_callbacks_invoke_pending();
free(msg);
}
void test_audio_endpoint__cleanup(void) {
fake_comm_session_cleanup();
fake_system_task_callbacks_cleanup();
s_transport = NULL;
fake_pbl_malloc_check_net_allocs();
fake_pbl_malloc_clear_tracking();
}