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

220 lines
5.1 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/common/debounced_connection_service.h"
#include "services/common/regular_timer.h"
#include "syscall/syscall.h"
#include "fake_new_timer.h"
#include "fake_rtc.h"
#include "fake_system_task.h"
#include "fake_pbl_malloc.h"
#include "fake_session.h"
#include "stubs_bt_lock.h"
#include "stubs_logging.h"
#include "stubs_mutex.h"
#include "stubs_hexdump.h"
#include "stubs_passert.h"
// Fakes
///////////////////////////////////////////////////////////
static TimerID s_debounce_timer;
static bool s_default_connection_state;
static unsigned int s_event_count = 0;
static PebbleEvent s_cached_event;
static Transport *s_transport;
static CommSession *s_session;
bool remote_is_connected(void) {
return s_default_connection_state;
}
void event_put(PebbleEvent* event) {
s_event_count++;
s_cached_event = (PebbleEvent) {
.type = event->type,
.bluetooth.comm_session_event = event->bluetooth.comm_session_event
};
}
// Helper functions
///////////////////////////////////////////////////////////
static void init(bool connected) {
if (connected) {
s_transport = fake_transport_create(TransportDestinationSystem, NULL, NULL);
s_session = fake_transport_set_connected(s_transport, true);
}
s_default_connection_state = connected;
regular_timer_init();
debounced_connection_service_init();
}
static void check_connected(void) {
// Connected = true
cl_assert(sys_mobile_app_is_connected_debounced());
}
static void check_waiting_to_send_disconnect(void) {
// Connected = true
cl_assert(sys_mobile_app_is_connected_debounced());
}
static void check_waiting_to_send_second_disconnect(void) {
// Connected = false
cl_assert(!sys_mobile_app_is_connected_debounced());
}
static void check_disconnected(void) {
// Connected = false
cl_assert(!sys_mobile_app_is_connected_debounced());
}
static void prv_send_connection_event(bool is_connected) {
//! Get connected event
PebbleCommSessionEvent event = {
.is_open = is_connected,
.is_system = true,
};
debounced_connection_service_handle_event(&event);
}
static void prv_assert_event_received(bool is_connected) {
cl_assert_equal_i(s_event_count, 1);
cl_assert_equal_b(s_cached_event.bluetooth.comm_session_event.is_open, is_connected);
}
// Tests
///////////////////////////////////////////////////////////
void test_debounced_connection_service__cleanup(void) {
s_event_count = 0;
regular_timer_deinit();
fake_comm_session_cleanup();
}
void test_debounced_connection_service__connected_to_disconnected(void) {
init(true /* connected */);
check_connected();
//! Get disconnected event
prv_send_connection_event(false);
check_waiting_to_send_disconnect();
// No event put
cl_assert_equal_i(s_event_count, 0);
//! Timer fires
regular_timer_fire_seconds(1);
// Event put
prv_assert_event_received(false);
check_disconnected();
}
void test_debounced_connection_service__disconnected_to_connected(void) {
init(false /* disconnected */);
check_disconnected();
//! Get connected event
prv_send_connection_event(true);
// Event put
prv_assert_event_received(true);
check_connected();
}
void test_debounced_connection_service__connected_to_connected(void) {
init(true /* connected */);
check_connected();
//! Get connected event
prv_send_connection_event(true);
check_connected();
// Event put
prv_assert_event_received(true);
}
void test_debounced_connection_service__disconnected_to_disconnected(void) {
//! Currently disconnected
init(false /* disconnected */);
check_disconnected();
//! Get disconnected event
prv_send_connection_event(false);
check_waiting_to_send_second_disconnect();
// No event put
cl_assert_equal_i(s_event_count, 0);
}
void test_debounced_connection_service__disconnected_wait_disconnected(void) {
//! Currently disconnected
init(false /* disconnected */);
check_disconnected();
//! Get disconnected event
prv_send_connection_event(false);
check_waiting_to_send_second_disconnect();
//! Timer fires
regular_timer_fire_seconds(1);
check_disconnected();
// Event put
prv_assert_event_received(false);
}
void test_debounced_connection_service__reconnected_quickly(void) {
//! Currently connected
init(true /* connected */);
check_connected();
//! Get disconnected event
prv_send_connection_event(false);
check_waiting_to_send_disconnect();
// No event put
cl_assert_equal_i(s_event_count, 0);
//! Get connected event before timer fires
prv_send_connection_event(true);
check_connected();
// No event put
cl_assert_equal_i(s_event_count, 0);
}