/* * 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/phone_pp.h" #include "services/normal/phone_call_util.h" #include "services/common/comm_session/session.h" #include "kernel/events.h" #include "fake_events.h" #include "fake_session.h" #include "fake_system_task.h" #include "stubs_bt_lock.h" #include "stubs_passert.h" #include "stubs_pbl_malloc.h" #include "stubs_hexdump.h" #include "stubs_serial.h" #include "stubs_logging.h" #include "stubs_mutex.h" #include "stubs_i18n.h" extern void phone_protocol_msg_callback(CommSession *session, const uint8_t* iter, size_t length); // Helpers /////////////////////////////////////////////////////////// static const uint32_t expected_cookie = 0x877d41a; static void prv_assert_last_event(PhoneEventType subtype, bool check_cookie, bool check_name_number, const char *name, const char *number) { PebbleEvent e = fake_event_get_last(); cl_assert_equal_i(e.type, PEBBLE_PHONE_EVENT); cl_assert_equal_i(e.phone.source, PhoneCallSource_PP); cl_assert_equal_i(e.phone.type, subtype); if (check_cookie) { cl_assert_equal_i(e.phone.call_identifier, expected_cookie); } if (check_name_number) { cl_assert_equal_s(e.phone.caller->name, name); cl_assert_equal_s(e.phone.caller->number, number); } } // Tests /////////////////////////////////////////////////////////// static Transport *s_transport; static CommSession *s_session; void test_phone_pp__initialize(void) { fake_event_init(); fake_comm_session_init(); s_transport = fake_transport_create(TransportDestinationSystem, NULL, NULL); s_session = fake_transport_set_connected(s_transport, true /* connected */); pp_get_phone_state_set_enabled(false); } void test_phone_pp__cleanup(void) { fake_comm_session_cleanup(); } void test_phone_pp__incoming_no_caller_id(void) { uint8_t pp_msg[] = {0x04, 0x1a, 0xd4, 0x77, 0x08, 0x00, 0x00}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Incoming, true /* check_cookie */, true /* check_name_number */, "Unknown", NULL); } void test_phone_pp__incoming_no_name(void) { uint8_t pp_msg[] = {0x04, 0x1a, 0xd4, 0x77, 0x08, 0x0d, 0x35, 0x35, 0x35, 0x2D, 0x35, 0x35, 0x35, 0x2D, 0x35, 0x35, 0x35, 0x35, 0x00, // "555-555-5555" 0x00}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Incoming, true /* check_cookie */, true /* check_name_number */, "", "555-555-5555"); } void test_phone_pp__incoming_no_number(void) { uint8_t pp_msg[] = {0x04, 0x1a, 0xd4, 0x77, 0x08, 0x00, 0x06, 0x42, 0x6F, 0x62, 0x62, 0x79, 0x00}; // "Bobby" phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Incoming, true /* check_cookie */, true /* check_name_number */, "Bobby", ""); } void test_phone_pp__incoming(void) { uint8_t pp_msg[] = {0x04, 0x1a, 0xd4, 0x77, 0x08, 0x0d, 0x35, 0x35, 0x35, 0x2D, 0x35, 0x35, 0x35, 0x2D, 0x35, 0x35, 0x35, 0x35, 0x00, // "555-555-5555" 0x06, 0x42, 0x6F, 0x62, 0x62, 0x79, 0x00}; // "Bobby" phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Incoming, true /* check_cookie */, true /* check_name_number */, "Bobby", "555-555-5555"); } void test_phone_pp__start(void) { uint8_t pp_msg[] = {0x08, 0x1a, 0xd4, 0x77, 0x08}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Start, true /* check_cookie */, false /* check_name_number */, NULL, NULL); } void test_phone_pp__end(void) { uint8_t pp_msg[] = {0x09, 0x1a, 0xd4, 0x77, 0x08}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_End, true /* check_cookie */, false /* check_name_number */, NULL, NULL); } static void prv_assert_answer_call_sent_cb(uint16_t endpoint_id, const uint8_t* data, unsigned int data_length) { uint8_t expected_answer_msg[] = {0x01, 0x1a, 0xd4, 0x77, 0x08}; cl_assert_equal_i(sizeof(expected_answer_msg), data_length); cl_assert_equal_i(memcmp(expected_answer_msg, data, sizeof(expected_answer_msg)), 0); } void test_phone_pp__answer_call(void) { fake_transport_set_sent_cb(s_transport, prv_assert_answer_call_sent_cb); pp_answer_call(expected_cookie); fake_comm_session_process_send_next(); } static void prv_assert_decline_call_sent_cb(uint16_t endpoint_id, const uint8_t* data, unsigned int data_length) { uint8_t expected_decline_msg[] = {0x02, 0x1a, 0xd4, 0x77, 0x08}; cl_assert_equal_i(sizeof(expected_decline_msg), data_length); cl_assert_equal_i(memcmp(expected_decline_msg, data, sizeof(expected_decline_msg)), 0); } void test_phone_pp__decline_call(void) { fake_transport_set_sent_cb(s_transport, prv_assert_decline_call_sent_cb); pp_decline_call(expected_cookie); fake_comm_session_process_send_next(); } static void prv_assert_get_phone_call_state_sent_cb(uint16_t endpoint_id, const uint8_t* data, unsigned int data_length) { uint8_t expected_request_msg[] = {0x03}; cl_assert_equal_i(sizeof(expected_request_msg), data_length); cl_assert_equal_i(memcmp(expected_request_msg, data, sizeof(expected_request_msg)), 0); } void test_phone_pp__get_phone_call_state_request(void) { fake_transport_set_sent_cb(s_transport, prv_assert_get_phone_call_state_sent_cb); pp_get_phone_state(); fake_comm_session_process_send_next(); } void test_phone_pp__get_phone_call_state_response_no_calls(void) { pp_get_phone_state_set_enabled(true); uint8_t pp_msg[] = {0x83}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_End, false /* check_cookie */, false /* check_name_number */, NULL, NULL); } void test_phone_pp__get_phone_call_state_response_one_started_call(void) { pp_get_phone_state_set_enabled(true); uint8_t pp_msg[] = {0x83, 0x05, 0x08, 0x1a, 0xd4, 0x77, 0x08}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); prv_assert_last_event(PhoneEventType_Start, true /* check_cookie */, false /* check_name_number */, NULL, NULL); } void test_phone_pp__get_phone_call_state_response_two_started_calls(void) { pp_get_phone_state_set_enabled(true); uint8_t pp_msg[] = {0x83, 0x05, 0x12, 0x34, 0x45, 0x67, 0x89, 0x05, 0x08, 0x1a, 0xd4, 0x77, 0x08}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); // TODO: assert the first event as well prv_assert_last_event(PhoneEventType_Start, true /* check_cookie */, false /* check_name_number */, NULL, NULL); } void test_phone_pp__get_phone_call_state_response_disabled(void) { pp_get_phone_state_set_enabled(false); uint8_t pp_msg[] = {0x83}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); PebbleEvent e = fake_event_get_last(); cl_assert_equal_i(e.type, PEBBLE_NULL_EVENT); } // PBL-34640 Make sure we don't put an incoming call event to a state response - the incoming call // state is only used for iOS 8 devices now and just causes trouble void test_phone_pp__get_phone_call_state_response_incoming(void) { pp_get_phone_state_set_enabled(true); uint8_t pp_msg[] = {0x83, 0x07, 0x04, 0x1a, 0xd4, 0x77, 0x08, 0x00, 0x00}; phone_protocol_msg_callback(s_session, pp_msg, sizeof(pp_msg)); fake_system_task_callbacks_invoke_pending(); // We shouldn't have emitted any event in this case cl_assert_equal_i(fake_event_get_count(), 0); }