mirror of
https://github.com/google/pebble
synced 2026-10-18 01:04:12 +02:00
Import of the watch repository from Pebble
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// These are the stubs that are common between the ancs_pebble_action and timeline_action tests
|
||||
// This huge list is mainly due to the inclusion of timeline_actions.c which handles both UI and
|
||||
// a large portion of action logic, which will hopefully be fixed eventually
|
||||
|
||||
#include "applib/ui/action_menu_window_private.h"
|
||||
#include "services/normal/blob_db/ios_notif_pref_db.h"
|
||||
#include "services/normal/blob_db/sync.h"
|
||||
#include "services/normal/filesystem/pfs.h"
|
||||
#include "services/normal/phone_call_util.h"
|
||||
#include "services/normal/timeline/actions_endpoint.h"
|
||||
#include "services/normal/timeline/timeline.h"
|
||||
#include "services/normal/timeline/timeline_actions.h"
|
||||
#include "util/size.h"
|
||||
|
||||
#include "stubs_action_chaining_window.h"
|
||||
#include "stubs_action_menu.h"
|
||||
#include "stubs_analytics.h"
|
||||
#include "stubs_app_install_manager.h"
|
||||
#include "stubs_app_manager.h"
|
||||
#include "stubs_app_state.h"
|
||||
#include "stubs_blob_db_sync.h"
|
||||
#include "stubs_dialog.h"
|
||||
#include "stubs_event_service_client.h"
|
||||
#include "stubs_evented_timer.h"
|
||||
#include "stubs_events.h"
|
||||
#include "stubs_expandable_dialog.h"
|
||||
#include "stubs_gcolor.h"
|
||||
#include "stubs_hexdump.h"
|
||||
#include "stubs_i18n.h"
|
||||
#include "stubs_layout_layer.h"
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_modal_manager.h"
|
||||
#include "stubs_mutex.h"
|
||||
#include "stubs_notification_storage.h"
|
||||
#include "stubs_notifications.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
#include "stubs_pebble_tasks.h"
|
||||
#include "stubs_pin_db.h"
|
||||
#include "stubs_progress_window.h"
|
||||
#include "stubs_rand_ptr.h"
|
||||
#include "stubs_regular_timer.h"
|
||||
#include "stubs_reminder_db.h"
|
||||
#include "stubs_rtc.h"
|
||||
#include "stubs_simple_dialog.h"
|
||||
#include "stubs_task_watchdog.h"
|
||||
#include "stubs_ui_window.h"
|
||||
#include "stubs_window_manager.h"
|
||||
#include "stubs_window_stack.h"
|
||||
|
||||
PebblePhoneCaller* phone_call_util_create_caller(const char *number, const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void launcher_task_add_callback(void (*callback)(void *data), void *data) {
|
||||
}
|
||||
|
||||
void system_task_add_callback(void (*callback)(void *data), void *data) {
|
||||
}
|
||||
|
||||
void ancs_perform_action(uint32_t notification_uid, uint8_t action_id) {
|
||||
}
|
||||
|
||||
status_t blob_db_delete(BlobDBId db_id, const uint8_t *key, int key_len) {
|
||||
return S_SUCCESS;
|
||||
}
|
||||
|
||||
void timeline_pin_window_push_modal(TimelineItem *item) {
|
||||
}
|
||||
|
||||
CommSession *comm_session_get_system_session(void) {
|
||||
// This can't be NULL (in that case we don't try to send the message)
|
||||
return (CommSession *) 1;
|
||||
}
|
||||
|
||||
void comm_session_set_responsiveness(
|
||||
CommSession *session, BtConsumer consumer, ResponseTimeState state, uint16_t max_period_secs) {
|
||||
return;
|
||||
}
|
||||
|
||||
void* event_service_claim_buffer(PebbleEvent *e) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void event_service_free_claimed_buffer(void *ref) {
|
||||
return;
|
||||
}
|
||||
|
||||
void timeline_resources_get_id(const TimelineResourceInfo *timeline_res, TimelineResourceSize size,
|
||||
AppResourceInfo *res_info) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool notification_window_is_modal(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t string_list_count(StringList *list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *string_list_get_at(StringList *list, size_t index) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool alerts_preferences_check_and_set_first_use_complete(int source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static TimelineItemActionSource s_current_timeline_action_source =
|
||||
TimelineItemActionSourceModalNotification;
|
||||
|
||||
TimelineItemActionSource kernel_ui_get_current_timeline_item_action_source(void) {
|
||||
return s_current_timeline_action_source;
|
||||
}
|
||||
|
||||
void kernel_ui_set_current_timeline_item_action_source(TimelineItemActionSource current_source) {
|
||||
s_current_timeline_action_source = current_source;
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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/notifications/ancs/ancs_notifications.h"
|
||||
#include "services/normal/notifications/ancs/ancs_notifications_util.h"
|
||||
#include "services/normal/notifications/ancs/ancs_item.h"
|
||||
#include "comm/ble/kernel_le_client/ancs/ancs_util.h"
|
||||
#include "comm/ble/kernel_le_client/ancs/ancs_types.h"
|
||||
|
||||
|
||||
// Test Data
|
||||
///////////////////////////////////////////////////////////
|
||||
#include "test_data.h"
|
||||
|
||||
|
||||
// Stubs
|
||||
///////////////////////////////////////////////////////////
|
||||
#include "stubs_common.h"
|
||||
#include "stubs_blob_db_sync_util.h"
|
||||
#include "stubs_prompt.h"
|
||||
#include "stubs_sleep.h"
|
||||
#include "stubs_nexmo.h"
|
||||
#include "stubs_codepoint.h"
|
||||
#include "stubs_utf8.h"
|
||||
|
||||
|
||||
// Externs
|
||||
///////////////////////////////////////////////////////////
|
||||
extern const int TIMELINE_ACTION_ENDPOINT;
|
||||
|
||||
|
||||
// Fakes / Helpers
|
||||
///////////////////////////////////////////////////////////
|
||||
#include "fake_spi_flash.h"
|
||||
|
||||
static const uint8_t *s_expected_send_data = NULL;
|
||||
static bool s_sent_action = false;
|
||||
|
||||
bool comm_session_send_data(CommSession *session, uint16_t endpoint_id,
|
||||
const uint8_t* data, size_t length, uint32_t timeout_ms) {
|
||||
if (s_expected_send_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (endpoint_id != TIMELINE_ACTION_ENDPOINT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cl_assert_equal_m(s_expected_send_data, data, length);
|
||||
s_sent_action = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void prv_support_sms_replies(void) {
|
||||
// Store the preference in our DB
|
||||
char *key = "com.apple.MobileSMS";
|
||||
int key_len = strlen(key);
|
||||
const int flags = 0;
|
||||
const int num_attributes = 0;
|
||||
const int num_actions = 1;
|
||||
const int action_id = 12;
|
||||
const int reply_action_attrs = 2; // Title + Emoji
|
||||
|
||||
uint8_t val[] = {0, 0, 0, 0, // Flags (unused for now)
|
||||
num_attributes, num_actions, action_id,
|
||||
TimelineItemActionTypeAncsResponse, // 0x0D
|
||||
reply_action_attrs,
|
||||
AttributeIdTitle, 0x05, 0x00, // Length
|
||||
0x52, 0x65, 0x70, 0x6c, 0x79, // "Reply"
|
||||
AttributeIdEmojiSupported, 0x01, 0x00, // Length
|
||||
0x01, // "Supported"
|
||||
};
|
||||
int val_len = sizeof(val);
|
||||
ios_notif_pref_db_insert((uint8_t *) key, key_len, (void *) &val, val_len);
|
||||
}
|
||||
|
||||
static void prv_support_sms_replies_no_emoji(void) {
|
||||
// Store the preference in our DB
|
||||
char *key = "com.apple.MobileSMS";
|
||||
int key_len = strlen(key);
|
||||
const int flags = 0;
|
||||
const int num_attributes = 0;
|
||||
const int num_actions = 1;
|
||||
const int action_id = 12;
|
||||
const int reply_action_attrs = 2; // Title + Emoji
|
||||
|
||||
uint8_t val[] = {0, 0, 0, 0, // Flags (unused for now)
|
||||
num_attributes, num_actions, action_id,
|
||||
TimelineItemActionTypeAncsResponse, // 0x0D
|
||||
reply_action_attrs,
|
||||
AttributeIdTitle, 0x05, 0x00, // Length
|
||||
0x52, 0x65, 0x70, 0x6c, 0x79, // "Reply"
|
||||
AttributeIdEmojiSupported, 0x01, 0x00, // Length
|
||||
0x00, // "Not supported"
|
||||
};
|
||||
int val_len = sizeof(val);
|
||||
ios_notif_pref_db_insert((uint8_t *) key, key_len, (void *) &val, val_len);
|
||||
}
|
||||
|
||||
|
||||
// Tests
|
||||
///////////////////////////////////////////////////////////
|
||||
void test_ancs_pebble_actions__initialize(void) {
|
||||
s_expected_send_data = NULL;
|
||||
s_sent_action = false;
|
||||
|
||||
fake_spi_flash_init(0, 0x1000000);
|
||||
pfs_init(false);
|
||||
pfs_format(false);
|
||||
}
|
||||
|
||||
void test_ancs_pebble_actions__cleanup(void) {
|
||||
}
|
||||
|
||||
|
||||
void test_ancs_pebble_actions__test_sms_reply(void) {
|
||||
prv_support_sms_replies();
|
||||
|
||||
ANCSAttribute *notif_attributes[NUM_FETCHED_NOTIF_ATTRIBUTES] = {0};
|
||||
ANCSAttribute *app_attrs[NUM_FETCHED_APP_ATTRIBUTES] = {0};
|
||||
|
||||
const size_t header_len = sizeof(GetNotificationAttributesMsg);
|
||||
bool error = false;
|
||||
const bool complete = ancs_util_get_attr_ptrs(s_sms_ancs_data + header_len,
|
||||
ARRAY_LENGTH(s_sms_ancs_data) - header_len,
|
||||
s_fetched_notif_attributes,
|
||||
NUM_FETCHED_NOTIF_ATTRIBUTES,
|
||||
notif_attributes,
|
||||
&error);
|
||||
|
||||
cl_assert(complete);
|
||||
cl_assert(!error);
|
||||
|
||||
time_t timestamp = 0;
|
||||
ANCSAppMetadata app_metadata = {0};
|
||||
const ANCSAttribute *app_id = notif_attributes[FetchedNotifAttributeIndexAppID];
|
||||
iOSNotifPrefs *notif_prefs = ios_notif_pref_db_get_prefs(app_id->value, app_id->length);
|
||||
TimelineItem *notif = ancs_item_create_and_populate(notif_attributes,
|
||||
app_attrs,
|
||||
&app_metadata,
|
||||
notif_prefs,
|
||||
timestamp,
|
||||
ANCSProperty_None);
|
||||
|
||||
cl_assert(notif);
|
||||
cl_assert_equal_i(notif->action_group.num_actions, 2);
|
||||
cl_assert_equal_i(notif->action_group.actions[0].type, TimelineItemActionTypeAncsNegative);
|
||||
TimelineItemAction *response_action = ¬if->action_group.actions[1];
|
||||
cl_assert_equal_i(response_action->type, TimelineItemActionTypeAncsResponse);
|
||||
cl_assert_equal_i(response_action->attr_list.num_attributes, 2);
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[0].id, AttributeIdTitle);
|
||||
cl_assert_equal_s(response_action->attr_list.attributes[0].cstring, "Reply");
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[1].id, AttributeIdEmojiSupported);
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[1].uint8, 1);
|
||||
|
||||
ActionMenuItem menu_item = (ActionMenuItem) {
|
||||
.action_data = ¬if->action_group.actions[1],
|
||||
};
|
||||
s_expected_send_data = s_sms_action_data;
|
||||
timeline_actions_invoke_action(¬if->action_group.actions[1], notif, NULL /*complete_cb*/,
|
||||
NULL /*cb_data*/);
|
||||
cl_assert(s_sent_action);
|
||||
}
|
||||
|
||||
void test_ancs_pebble_actions__test_sms_reply_no_emoji(void) {
|
||||
prv_support_sms_replies_no_emoji();
|
||||
|
||||
ANCSAttribute *notif_attributes[NUM_FETCHED_NOTIF_ATTRIBUTES] = {0};
|
||||
ANCSAttribute *app_attrs[NUM_FETCHED_APP_ATTRIBUTES] = {0};
|
||||
|
||||
const size_t header_len = sizeof(GetNotificationAttributesMsg);
|
||||
bool error = false;
|
||||
const bool complete = ancs_util_get_attr_ptrs(s_sms_ancs_data + header_len,
|
||||
ARRAY_LENGTH(s_sms_ancs_data) - header_len,
|
||||
s_fetched_notif_attributes,
|
||||
NUM_FETCHED_NOTIF_ATTRIBUTES,
|
||||
notif_attributes,
|
||||
&error);
|
||||
|
||||
cl_assert(complete);
|
||||
cl_assert(!error);
|
||||
|
||||
time_t timestamp = 0;
|
||||
ANCSAppMetadata app_metadata = {0};
|
||||
const ANCSAttribute *app_id = notif_attributes[FetchedNotifAttributeIndexAppID];
|
||||
iOSNotifPrefs *notif_prefs = ios_notif_pref_db_get_prefs(app_id->value, app_id->length);
|
||||
TimelineItem *notif = ancs_item_create_and_populate(notif_attributes,
|
||||
app_attrs,
|
||||
&app_metadata,
|
||||
notif_prefs,
|
||||
timestamp,
|
||||
ANCSProperty_None);
|
||||
|
||||
cl_assert(notif);
|
||||
cl_assert_equal_i(notif->action_group.num_actions, 2);
|
||||
cl_assert_equal_i(notif->action_group.actions[0].type, TimelineItemActionTypeAncsNegative);
|
||||
TimelineItemAction *response_action = ¬if->action_group.actions[1];
|
||||
cl_assert_equal_i(response_action->type, TimelineItemActionTypeAncsResponse);
|
||||
cl_assert_equal_i(response_action->attr_list.num_attributes, 2);
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[0].id, AttributeIdTitle);
|
||||
cl_assert_equal_s(response_action->attr_list.attributes[0].cstring, "Reply");
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[1].id, AttributeIdEmojiSupported);
|
||||
cl_assert_equal_i(response_action->attr_list.attributes[1].uint8, 0);
|
||||
|
||||
|
||||
s_expected_send_data = s_sms_action_data;
|
||||
timeline_actions_invoke_action(¬if->action_group.actions[1], notif, NULL /*complete_cb*/,
|
||||
NULL /*cb_data*/);
|
||||
cl_assert(s_sent_action);
|
||||
}
|
||||
|
||||
void test_ancs_pebble_actions__test_sms_replies_unsupported(void) {
|
||||
prv_support_sms_replies();
|
||||
|
||||
ANCSAttribute *notif_attributes[NUM_FETCHED_NOTIF_ATTRIBUTES] = {0};
|
||||
ANCSAttribute *app_attrs[NUM_FETCHED_APP_ATTRIBUTES] = {0};
|
||||
|
||||
const size_t header_len = sizeof(GetNotificationAttributesMsg);
|
||||
bool error = false;
|
||||
const bool complete = ancs_util_get_attr_ptrs(s_sms_ancs_data + header_len,
|
||||
ARRAY_LENGTH(s_sms_ancs_data) - header_len,
|
||||
s_fetched_notif_attributes,
|
||||
NUM_FETCHED_NOTIF_ATTRIBUTES,
|
||||
notif_attributes,
|
||||
&error);
|
||||
|
||||
cl_assert(complete);
|
||||
cl_assert(!error);
|
||||
|
||||
time_t timestamp = 0;
|
||||
ANCSAppMetadata app_metadata = {0};
|
||||
|
||||
TimelineItem *item = ancs_item_create_and_populate(notif_attributes,
|
||||
app_attrs,
|
||||
&app_metadata,
|
||||
NULL,
|
||||
timestamp,
|
||||
ANCSProperty_None);
|
||||
|
||||
cl_assert(item);
|
||||
cl_assert_equal_i(item->action_group.num_actions, 1);
|
||||
cl_assert_equal_i(item->action_group.actions[0].type, TimelineItemActionTypeAncsNegative);
|
||||
}
|
||||
|
||||
void test_ancs_pebble_actions__test_group_sms(void) {
|
||||
prv_support_sms_replies();
|
||||
|
||||
ANCSAttribute *notif_attributes[NUM_FETCHED_NOTIF_ATTRIBUTES] = {0};
|
||||
ANCSAttribute *app_attrs[NUM_FETCHED_APP_ATTRIBUTES] = {0};
|
||||
|
||||
const size_t header_len = sizeof(GetNotificationAttributesMsg);
|
||||
bool error = false;
|
||||
const bool complete = ancs_util_get_attr_ptrs(s_group_sms_ancs_data + header_len,
|
||||
ARRAY_LENGTH(s_group_sms_ancs_data) - header_len,
|
||||
s_fetched_notif_attributes,
|
||||
NUM_FETCHED_NOTIF_ATTRIBUTES,
|
||||
notif_attributes,
|
||||
&error);
|
||||
|
||||
cl_assert(complete);
|
||||
cl_assert(!error);
|
||||
|
||||
time_t timestamp = 0;
|
||||
ANCSAppMetadata app_metadata = {0};
|
||||
const ANCSAttribute *app_id = notif_attributes[FetchedNotifAttributeIndexAppID];
|
||||
iOSNotifPrefs *notif_prefs = ios_notif_pref_db_get_prefs(app_id->value, app_id->length);
|
||||
TimelineItem *item = ancs_item_create_and_populate(notif_attributes,
|
||||
app_attrs,
|
||||
&app_metadata,
|
||||
notif_prefs,
|
||||
timestamp,
|
||||
ANCSProperty_None);
|
||||
|
||||
cl_assert(item);
|
||||
|
||||
// We no longer show the reply action on group SMS messages (a less confusing UX)
|
||||
// Before the phone would reject the message right away.
|
||||
cl_assert_equal_i(item->action_group.num_actions, 1);
|
||||
cl_assert_equal_i(item->action_group.actions[0].type, TimelineItemActionTypeAncsNegative);
|
||||
}
|
||||
|
||||
// void test_ancs_pebble_actions__test_email(void) {
|
||||
// ANCSAttribute *notif_attributes[NUM_FETCHED_NOTIF_ATTRIBUTES] = {0};
|
||||
// ANCSAttribute *app_attrs[NUM_FETCHED_APP_ATTRIBUTES] = {0};
|
||||
|
||||
// const size_t header_len = sizeof(GetNotificationAttributesMsg);
|
||||
// bool error = false;
|
||||
// const bool complete = ancs_util_get_attr_ptrs(s_email_ancs_data + header_len,
|
||||
// ARRAY_LENGTH(s_email_ancs_data) - header_len,
|
||||
// s_fetched_notif_attributes,
|
||||
// NUM_FETCHED_NOTIF_ATTRIBUTES,
|
||||
// notif_attributes,
|
||||
// &error);
|
||||
|
||||
// cl_assert(complete);
|
||||
// cl_assert(!error);
|
||||
|
||||
// time_t timestamp = 0;
|
||||
// ANCSAppMetadata app_metadata = {0};
|
||||
// TimelineItem *item = ancs_item_create_and_populate(notif_attributes,
|
||||
// app_attrs,
|
||||
// &app_metadata,
|
||||
// timestamp,
|
||||
// ANCSProperty_None);
|
||||
|
||||
// cl_assert_equal_i(item->action_group.num_actions, 1);
|
||||
// cl_assert_equal_i(item->action_group.actions[0].type, TimelineItemActionTypeAncsNegative);
|
||||
|
||||
// No e-mail actions yet
|
||||
|
||||
// TimelineItemAction *response_action = &item->action_group.actions[1];
|
||||
// cl_assert_equal_i(response_action->type, TimelineItemActionTypeAncsResponse);
|
||||
// cl_assert_equal_i(response_action->attr_list.num_attributes, 3);
|
||||
// cl_assert_equal_i(response_action->attr_list.attributes[0].id, AttributeIdTitle);
|
||||
// cl_assert_equal_s(response_action->attr_list.attributes[0].cstring, "Reply");
|
||||
// cl_assert_equal_i(response_action->attr_list.attributes[1].id, AttributeIdSender);
|
||||
// cl_assert_equal_s(response_action->attr_list.attributes[1].cstring, "Philip G");
|
||||
// cl_assert_equal_i(response_action->attr_list.attributes[2].id, AttributeIdiOSAppIdentifier);
|
||||
// cl_assert_equal_s(response_action->attr_list.attributes[2].cstring, "com.apple.MobileSMS");
|
||||
|
||||
|
||||
// s_expected_send_data = s_email_action_data;
|
||||
// timeline_invoke_action(item, response_action, &response_action->attr_list);
|
||||
// cl_assert(s_sent_action);
|
||||
// }
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 <stdint.h>
|
||||
|
||||
/**************** ANCS SMS ****************/
|
||||
// 00 0c 00 00 00 06 00 00 07 05 00 43 6c 65 61 72 ........ ...Clear
|
||||
// 00 13 00 63 6f 6d 2e 61 70 70 6c 65 2e 4d 6f 62 ...com.a pple.Mob
|
||||
// 69 6c 65 53 4d 53 01 08 00 50 68 69 6c 69 70 20 ileSMS.. .Philip
|
||||
// 47 02 00 00 03 12 00 43 61 6e 61 64 61 20 69 73 G......C anada is
|
||||
// 20 74 68 65 20 62 65 73 74 05 0f 00 32 30 31 35 the bes t...2015
|
||||
// 30 38 33 31 54 31 30 32 34 34 33 0831T102 443
|
||||
static const uint8_t s_sms_ancs_data[] = {
|
||||
0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x05, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72,
|
||||
0x00, 0x13, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x6f, 0x62,
|
||||
0x69, 0x6c, 0x65, 0x53, 0x4d, 0x53, 0x01, 0x08, 0x00, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x20,
|
||||
0x47, 0x02, 0x00, 0x00, 0x03, 0x12, 0x00, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x20, 0x69, 0x73,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x73, 0x74, 0x05, 0x0f, 0x00, 0x32, 0x30, 0x31, 0x35,
|
||||
0x30, 0x38, 0x33, 0x31, 0x54, 0x31, 0x30, 0x32, 0x34, 0x34, 0x33
|
||||
};
|
||||
|
||||
// 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
// 00 0c 06 0c 08 00 50 68 69 6c 69 70 20 47 01 08 ......Ph ilip G..
|
||||
// 00 50 68 69 6c 69 70 20 47 03 12 00 43 61 6e 61 .Philip G...Cana
|
||||
// 64 61 20 69 73 20 74 68 65 20 62 65 73 74 20 13 da is th e best .
|
||||
// 00 63 6f 6d 2e 61 70 70 6c 65 2e 4d 6f 62 69 6c .com.app le.Mobil
|
||||
// 65 53 4d 53 04 04 00 00 00 00 00 25 04 00 00 00 eSMS.... ...%....
|
||||
// 00 00 ..
|
||||
|
||||
static const uint8_t s_sms_action_data[] = {
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x06, 0x0c, 0x08, 0x00, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x20, 0x47, 0x01, 0x08,
|
||||
0x00, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x20, 0x47, 0x03, 0x12, 0x00, 0x43, 0x61, 0x6e, 0x61,
|
||||
0x64, 0x61, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x73, 0x74, 0x20, 0x13,
|
||||
0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x6f, 0x62, 0x69, 0x6c,
|
||||
0x65, 0x53, 0x4d, 0x53, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
};
|
||||
|
||||
/**************** Group SMS ****************/
|
||||
// 00 0d 00 00 00 06 00 00 07 05 00 43 6c 65 61 72 ........ ...Clear
|
||||
// 00 13 00 63 6f 6d 2e 61 70 70 6c 65 2e 4d 6f 62 ...com.a pple.Mob
|
||||
// 69 6c 65 53 4d 53 01 10 00 62 6a 65 74 74 40 70 ileSMS.. .bjett@p
|
||||
// 65 62 62 6c 65 2e 63 6f 6d 02 17 00 54 6f 20 79 ebble.co m...To y
|
||||
// 6f 75 20 26 20 28 33 31 37 29 20 33 37 30 2d 32 ou & (31 7) 370-2
|
||||
// 38 32 39 03 08 00 54 65 73 74 69 6e 67 20 05 0f 829...Te sting ..
|
||||
// 00 32 30 31 35 30 39 30 32 54 31 36 31 39 32 32 .2015090 2T161922
|
||||
static const uint8_t s_group_sms_ancs_data[] = {
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x05, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72,
|
||||
0x00, 0x13, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x6f, 0x62,
|
||||
0x69, 0x6c, 0x65, 0x53, 0x4d, 0x53, 0x01, 0x10, 0x00, 0x62, 0x6a, 0x65, 0x74, 0x74, 0x40, 0x70,
|
||||
0x65, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x17, 0x00, 0x54, 0x6f, 0x20, 0x79,
|
||||
0x6f, 0x75, 0x20, 0x26, 0x20, 0x28, 0x33, 0x31, 0x37, 0x29, 0x20, 0x33, 0x37, 0x30, 0x2d, 0x32,
|
||||
0x38, 0x32, 0x39, 0x03, 0x08, 0x00, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x05, 0x0f,
|
||||
0x00, 0x32, 0x30, 0x31, 0x35, 0x30, 0x39, 0x30, 0x32, 0x54, 0x31, 0x36, 0x31, 0x39, 0x32, 0x32
|
||||
};
|
||||
|
||||
// 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
// 00 0d 05 01 05 00 52 65 70 6c 79 21 01 00 01 0c ......Reply!....
|
||||
// 10 00 62 6a 65 74 74 40 70 65 62 62 6c 65 2e 63 [email protected]
|
||||
// 6f 6d 20 13 00 63 6f 6d 2e 61 70 70 6c 65 2e 4d om ..com.apple.M
|
||||
// 6f 62 69 6c 65 53 4d 53 02 17 00 54 6f 20 79 6f obileSMS...To yo
|
||||
// 75 20 26 20 28 33 31 37 29 20 33 37 30 2d 32 38 u & (317) 370-28
|
||||
// 32 39 29
|
||||
|
||||
static const uint8_t s_group_sms_action_data[] = {
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0d, 0x05, 0x01, 0x05, 0x00, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x21, 0x01, 0x00, 0x01, 0x0c,
|
||||
0x10, 0x00, 0x62, 0x6a, 0x65, 0x74, 0x74, 0x40, 0x70, 0x65, 0x62, 0x62, 0x6c, 0x65, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x20, 0x13, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x4d,
|
||||
0x6f, 0x62, 0x69, 0x6c, 0x65, 0x53, 0x4d, 0x53, 0x02, 0x17, 0x00, 0x54, 0x6f, 0x20, 0x79, 0x6f,
|
||||
0x75, 0x20, 0x26, 0x20, 0x28, 0x33, 0x31, 0x37, 0x29, 0x20, 0x33, 0x37, 0x30, 0x2d, 0x32, 0x38,
|
||||
0x32, 0x39
|
||||
};
|
||||
|
||||
|
||||
/**************** Email ****************/
|
||||
static const uint8_t s_email_ancs_data[] = {
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x05, 0x00, 0x43, 0x6c, 0x65, 0x61, 0x72,
|
||||
0x00, 0x14, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x62,
|
||||
0x69, 0x6c, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x01, 0x0e, 0x00, 0x50, 0x68, 0x69, 0x6c, 0x20, 0x47,
|
||||
0x75, 0x6e, 0x6e, 0x65, 0x77, 0x69, 0x65, 0x6b, 0x02, 0x0b, 0x00, 0x54, 0x68, 0x65, 0x20, 0x53,
|
||||
0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x03, 0x08, 0x00, 0x54, 0x68, 0x65, 0x20, 0x42, 0x6f, 0x64,
|
||||
0x79, 0x05, 0x0f, 0x00, 0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x33, 0x31, 0x54, 0x31, 0x31, 0x30,
|
||||
0x33, 0x35, 0x39
|
||||
};
|
||||
|
||||
/**************** Send Text ****************/
|
||||
// 02 0f 71 aa ba 58 14 4b 5c 96 e2 c9 82 8c 97 34 ..q..X.K \......4
|
||||
// cb 00 02 01 0e 00 59 6f 2c 20 77 68 61 74 27 73 ......Yo , what's
|
||||
// 20 75 70 3f 0c 0c 00 35 35 35 2d 31 32 33 2d 34 up?...5 55-123-4
|
||||
// 35 36 37 567
|
||||
|
||||
static const uint8_t s_send_text_data[] = {
|
||||
0x02, 0x0f, 0x71, 0xaa, 0xba, 0x58, 0x14, 0x4b, 0x5c, 0x96, 0xe2, 0xc9, 0x82, 0x8c, 0x97, 0x34,
|
||||
0xcb, 0x00, 0x02, 0x01, 0x0e, 0x00, 0x59, 0x6f, 0x2c, 0x20, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73,
|
||||
0x20, 0x75, 0x70, 0x3f, 0x0c, 0x0c, 0x00, 0x35, 0x35, 0x35, 0x2d, 0x31, 0x32, 0x33, 0x2d, 0x34,
|
||||
0x35, 0x36, 0x37
|
||||
};
|
||||
|
||||
/**************** PP SMS ****************/
|
||||
// 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
// 00 00 01 01 0e 00 59 6f 2c 20 77 68 61 74 27 73 ......Yo , what's
|
||||
// 20 75 70 3f up?
|
||||
|
||||
static const uint8_t s_sms_reply_action_data[] = {
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x59, 0x6f, 0x2c, 0x20, 0x77, 0x68, 0x61, 0x74, 0x27, 0x73,
|
||||
0x20, 0x75, 0x70, 0x3f
|
||||
};
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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/timeline/timeline_actions.h"
|
||||
|
||||
// Test Data
|
||||
///////////////////////////////////////////////////////////
|
||||
#include "test_data.h"
|
||||
|
||||
static TimelineItemAction s_reply_action = {
|
||||
.id = 0,
|
||||
.type = TimelineItemActionTypeResponse,
|
||||
.attr_list = (AttributeList) {
|
||||
.num_attributes = 1,
|
||||
.attributes = (Attribute[1]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Reply" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Stubs
|
||||
///////////////////////////////////////////////////////////
|
||||
#include "stubs_common.h"
|
||||
|
||||
|
||||
// Externs
|
||||
///////////////////////////////////////////////////////////
|
||||
extern const int TIMELINE_ACTION_ENDPOINT;
|
||||
|
||||
typedef struct ActionResultData ActionResultData;
|
||||
extern ActionResultData *prv_invoke_action(ActionMenu *action_menu,
|
||||
const TimelineItemAction *action,
|
||||
const TimelineItem *pin, const char *label);
|
||||
|
||||
|
||||
// Fakes / Helpers
|
||||
///////////////////////////////////////////////////////////
|
||||
static const uint8_t *s_expected_send_data = NULL;
|
||||
static bool s_sent_action = false;
|
||||
|
||||
bool comm_session_send_data(CommSession *session, uint16_t endpoint_id,
|
||||
const uint8_t* data, size_t length, uint32_t timeout_ms) {
|
||||
if (s_expected_send_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (endpoint_id != TIMELINE_ACTION_ENDPOINT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cl_assert_equal_m(s_expected_send_data, data, length);
|
||||
s_sent_action = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Setup
|
||||
/////////////////////////
|
||||
void test_timeline_actions__initialize(void) {
|
||||
s_expected_send_data = NULL;
|
||||
s_sent_action = false;
|
||||
}
|
||||
|
||||
void test_timeline_actions__cleanup(void) {
|
||||
}
|
||||
|
||||
// Tests
|
||||
///////////////////////////
|
||||
|
||||
// Tests a regular response to a notification
|
||||
void test_timeline_actions__response(void) {
|
||||
const TimelineItem item = {
|
||||
.attr_list = (AttributeList) {
|
||||
.num_attributes = 5,
|
||||
.attributes = (Attribute[5]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Ian Graham" },
|
||||
{ .id = AttributeIdBody, .cstring = "this is a test notification" },
|
||||
{ .id = AttributeIdIconTiny, .uint32 = TIMELINE_RESOURCE_GENERIC_SMS },
|
||||
{ .id = AttributeIdBgColor, .uint8 = GColorIslamicGreenARGB8 }
|
||||
}
|
||||
},
|
||||
.action_group = (TimelineItemActionGroup) {
|
||||
.num_actions = 1,
|
||||
.actions = &s_reply_action
|
||||
}
|
||||
};
|
||||
|
||||
s_expected_send_data = s_sms_reply_action_data;
|
||||
prv_invoke_action(NULL, &item.action_group.actions[0], &item, "Yo, what's up?");
|
||||
cl_assert(s_sent_action);
|
||||
}
|
||||
|
||||
// Tests that we send the required data for the Send Text app and reply to call features
|
||||
void test_timeline_actions__send_text(void) {
|
||||
const TimelineItem item = {
|
||||
.header = {
|
||||
.id = UUID_SEND_SMS
|
||||
},
|
||||
.attr_list = (AttributeList) {
|
||||
.num_attributes = 2,
|
||||
.attributes = (Attribute[2]) {
|
||||
{ .id = AttributeIdSender, .cstring = "555-123-4567" },
|
||||
{ .id = AttributeIdiOSAppIdentifier, .cstring = "com.pebble.android.phone" }
|
||||
}
|
||||
},
|
||||
.action_group = (TimelineItemActionGroup) {
|
||||
.num_actions = 1,
|
||||
.actions = &s_reply_action
|
||||
}
|
||||
};
|
||||
|
||||
s_expected_send_data = s_send_text_data;
|
||||
prv_invoke_action(NULL, &item.action_group.actions[0], &item, "Yo, what's up?");
|
||||
cl_assert(s_sent_action);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
from waftools.pebble_test import clar
|
||||
|
||||
def build(ctx):
|
||||
clar(ctx,
|
||||
sources_ant_glob = \
|
||||
"src/fw/comm/ble/kernel_le_client/ancs/ancs_util.c " \
|
||||
"src/fw/flash_region/filesystem_regions.c " \
|
||||
"src/fw/flash_region/flash_region.c " \
|
||||
"src/fw/services/normal/blob_db/ios_notif_pref_db.c " \
|
||||
"src/fw/services/normal/filesystem/flash_translation.c " \
|
||||
"src/fw/services/normal/filesystem/pfs.c " \
|
||||
"src/fw/services/normal/notifications/ancs/ancs_filtering.c " \
|
||||
"src/fw/services/normal/notifications/ancs/ancs_item.c " \
|
||||
"src/fw/services/normal/notifications/ancs/ancs_notifications.c " \
|
||||
"src/fw/services/normal/notifications/ancs/ancs_notifications_util.c " \
|
||||
"src/fw/services/normal/notifications/ancs/ancs_phone_call.c " \
|
||||
"src/fw/services/normal/settings/settings_file.c " \
|
||||
"src/fw/services/normal/settings/settings_raw_iter.c " \
|
||||
"src/fw/services/normal/timeline/actions_endpoint.c " \
|
||||
"src/fw/services/normal/timeline/attribute.c " \
|
||||
"src/fw/services/normal/timeline/attribute_group.c " \
|
||||
"src/fw/services/normal/timeline/attributes_actions.c " \
|
||||
"src/fw/services/normal/timeline/item.c " \
|
||||
"src/fw/services/normal/timeline/timeline.c " \
|
||||
"src/fw/services/normal/timeline/timeline_actions.c " \
|
||||
"src/fw/util/buffer.c " \
|
||||
"src/fw/util/crc8.c " \
|
||||
"src/fw/util/legacy_checksum.c " \
|
||||
"src/fw/util/pstring.c " \
|
||||
"src/fw/util/rand/rand.c " \
|
||||
"src/fw/util/time/time.c "\
|
||||
"src/fw/vendor/tinymt32/tinymt32.c " \
|
||||
"tests/fakes/fake_spi_flash.c ",
|
||||
test_sources_ant_glob = "test_ancs_pebble_actions.c",
|
||||
override_includes=['dummy_board'])
|
||||
|
||||
clar(ctx,
|
||||
sources_ant_glob =
|
||||
"src/fw/services/normal/timeline/actions_endpoint.c " \
|
||||
"src/fw/services/normal/timeline/attribute.c " \
|
||||
"src/fw/services/normal/timeline/attribute_group.c " \
|
||||
"src/fw/services/normal/timeline/attributes_actions.c " \
|
||||
"src/fw/services/normal/timeline/item.c " \
|
||||
"src/fw/services/normal/timeline/timeline.c " \
|
||||
"src/fw/services/normal/timeline/timeline_actions.c " \
|
||||
"src/fw/util/time/time.c ",
|
||||
test_sources_ant_glob = "test_timeline_actions.c",
|
||||
override_includes=['dummy_board'])
|
||||
# vim:filetype=python
|
||||
Reference in New Issue
Block a user