mirror of
https://github.com/google/pebble
synced 2026-10-17 16:54:11 +02:00
Import of the watch repository from Pebble
This commit is contained in:
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* 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/alerts_preferences.h"
|
||||
#include "services/normal/notifications/ancs/ancs_filtering.h"
|
||||
#include "services/normal/blob_db/ios_notif_pref_db.h"
|
||||
#include "services/normal/timeline/attributes_actions.h"
|
||||
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
|
||||
// Fakes
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static time_t s_now;
|
||||
time_t rtc_get_time(void) {
|
||||
return s_now;
|
||||
}
|
||||
|
||||
RtcTicks rtc_get_ticks(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool s_performed_store = false;
|
||||
AttributeList *s_expected_attributes = NULL;
|
||||
TimelineItemActionGroup *s_expected_actions = NULL;
|
||||
|
||||
static uint8_t app_id_data[] = {
|
||||
0x00, // id
|
||||
0x04, 0x00, // length
|
||||
'P', 'h', 'i', 'l', // Value
|
||||
};
|
||||
static ANCSAttribute *s_app_id_attr = (ANCSAttribute *)&app_id_data;
|
||||
|
||||
static uint8_t display_name_data[] = {
|
||||
0x00, // id
|
||||
0x07, 0x00, // length
|
||||
'A', 'w', 'e', 's', 'o', 'm', 'e', // Value
|
||||
};
|
||||
static ANCSAttribute *s_display_name_attr = (ANCSAttribute *)&display_name_data;
|
||||
|
||||
static uint8_t title_data[] = {
|
||||
0x01, // id
|
||||
0x0E, 0x00, // length
|
||||
'A', 'p', 'p', 'l', 'e', ' ', 'P', 'a', 'y', ' ', '=', ' ', ':', '(' // Value
|
||||
};
|
||||
static ANCSAttribute *s_title_attr = (ANCSAttribute *)&title_data;
|
||||
|
||||
status_t ios_notif_pref_db_store_prefs(const uint8_t *app_id, int length, AttributeList *attr_list,
|
||||
TimelineItemActionGroup *action_group) {
|
||||
s_performed_store = true;
|
||||
if (s_expected_attributes) {
|
||||
const int buf_size = 256;
|
||||
uint8_t expected_buf[buf_size];
|
||||
uint8_t actual_buf[buf_size];
|
||||
attributes_actions_serialize_payload(s_expected_attributes, s_expected_actions,
|
||||
expected_buf, buf_size);
|
||||
attributes_actions_serialize_payload(attr_list, action_group,
|
||||
actual_buf, buf_size);
|
||||
cl_assert_equal_m(expected_buf, actual_buf,
|
||||
attributes_actions_get_serialized_payload_size(s_expected_attributes, s_expected_actions));
|
||||
}
|
||||
return S_SUCCESS;
|
||||
}
|
||||
|
||||
void ios_notif_pref_db_free_prefs(iOSNotifPrefs *prefs) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void prv_compare_notif_prefs(iOSNotifPrefs *prefs1, iOSNotifPrefs *prefs2) {
|
||||
const int buf_size = 256;
|
||||
uint8_t buf1[buf_size];
|
||||
uint8_t buf2[buf_size];
|
||||
attributes_actions_serialize_payload(&prefs1->attr_list, &prefs1->action_group, buf1, buf_size);
|
||||
attributes_actions_serialize_payload(&prefs2->attr_list, &prefs2->action_group, buf2, buf_size);
|
||||
cl_assert_equal_m(buf1, buf2, attributes_actions_get_serialized_payload_size(&prefs2->attr_list, &prefs2->action_group));
|
||||
}
|
||||
|
||||
void test_ancs_filtering__initialize(void) {
|
||||
s_now = 1;
|
||||
s_performed_store = false;
|
||||
s_expected_attributes = NULL;
|
||||
s_expected_actions = NULL;
|
||||
}
|
||||
|
||||
void test_ancs_filtering__cleanup(void) {
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_no_action_needed(void) {
|
||||
// We have some existing prefs which includes all the defaults
|
||||
// We don't need to insert anything
|
||||
iOSNotifPrefs prefs = {
|
||||
.attr_list = {
|
||||
.num_attributes = 5,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Title" },
|
||||
{ .id = AttributeIdBody, .cstring = "Body" },
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_Always },
|
||||
},
|
||||
},
|
||||
};
|
||||
iOSNotifPrefs *existing_prefs = &prefs;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(!s_performed_store);
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_no_prefs_yet(void) {
|
||||
// No existing prefs yet, we should instert all the defaults
|
||||
iOSNotifPrefs *existing_prefs = NULL;
|
||||
|
||||
AttributeList attr_list = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_None },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
}
|
||||
};
|
||||
s_expected_attributes = &attr_list;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(s_performed_store);
|
||||
|
||||
// Make sure the our existing prefs got updated
|
||||
iOSNotifPrefs expected_prefs = {
|
||||
.attr_list = attr_list,
|
||||
};
|
||||
prv_compare_notif_prefs(existing_prefs, &expected_prefs);
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_existing_mute(void) {
|
||||
// We already have a mute attribute and 2 unrelated attributes, make sure mute doesn't change
|
||||
// and the remaining default attributes are added
|
||||
iOSNotifPrefs prefs = {
|
||||
.attr_list = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Title" },
|
||||
{ .id = AttributeIdBody, .cstring = "Body" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_Always },
|
||||
},
|
||||
},
|
||||
};
|
||||
iOSNotifPrefs *existing_prefs = &prefs;
|
||||
|
||||
AttributeList expected_attributes = {
|
||||
.num_attributes = 5,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Title" },
|
||||
{ .id = AttributeIdBody, .cstring = "Body" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_Always },
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
}
|
||||
};
|
||||
s_expected_attributes = &expected_attributes;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(s_performed_store);
|
||||
|
||||
// Make sure the our existing prefs got updated
|
||||
iOSNotifPrefs expected_prefs = {
|
||||
.attr_list = expected_attributes,
|
||||
};
|
||||
prv_compare_notif_prefs(existing_prefs, &expected_prefs);
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_existing_display_name(void) {
|
||||
// We got a new app name, make sure it gets updated
|
||||
iOSNotifPrefs prefs = {
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Phil was here" },
|
||||
},
|
||||
},
|
||||
};
|
||||
iOSNotifPrefs *existing_prefs = &prefs;
|
||||
|
||||
AttributeList expected_attributes = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_None },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
}
|
||||
};
|
||||
s_expected_attributes = &expected_attributes;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(s_performed_store);
|
||||
|
||||
// Make sure the our existing prefs got updated
|
||||
iOSNotifPrefs expected_prefs = {
|
||||
.attr_list = expected_attributes,
|
||||
};
|
||||
prv_compare_notif_prefs(existing_prefs, &expected_prefs);
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_update_timestamp(void) {
|
||||
// We already have all the default attributes, but it has been a while since we got our last
|
||||
// notification from this source
|
||||
iOSNotifPrefs prefs = {
|
||||
.attr_list = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_None },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
},
|
||||
},
|
||||
};
|
||||
iOSNotifPrefs *existing_prefs = &prefs;
|
||||
|
||||
s_now += SECONDS_PER_DAY - 1;
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(!s_performed_store);
|
||||
|
||||
s_now += 2;
|
||||
AttributeList expected_attributes = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_None },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
}
|
||||
};
|
||||
s_expected_attributes = &expected_attributes;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, s_display_name_attr, s_title_attr);
|
||||
cl_assert(s_performed_store);
|
||||
|
||||
// Make sure the our existing prefs got updated
|
||||
iOSNotifPrefs expected_prefs = {
|
||||
.attr_list = expected_attributes,
|
||||
};
|
||||
prv_compare_notif_prefs(existing_prefs, &expected_prefs);
|
||||
}
|
||||
|
||||
void test_ancs_filtering__should_ignore_because_muted(void) {
|
||||
iOSNotifPrefs mute_always = {
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = 0x7F },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
iOSNotifPrefs mute_weekends = {
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = 0x41 },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
iOSNotifPrefs mute_weekdays = {
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = 0x3E },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
s_now = 1451606400; // Friday Jan 1, 2016
|
||||
cl_assert(ancs_filtering_is_muted(&mute_always));
|
||||
cl_assert(!ancs_filtering_is_muted(&mute_weekends));
|
||||
cl_assert(ancs_filtering_is_muted(&mute_weekdays));
|
||||
|
||||
s_now += SECONDS_PER_DAY; // Saturday Jan 2, 2016
|
||||
cl_assert(ancs_filtering_is_muted(&mute_always));
|
||||
cl_assert(ancs_filtering_is_muted(&mute_weekends));
|
||||
cl_assert(!ancs_filtering_is_muted(&mute_weekdays));
|
||||
|
||||
s_now += SECONDS_PER_DAY; // Sunday Jan 3, 2016
|
||||
cl_assert(ancs_filtering_is_muted(&mute_always));
|
||||
cl_assert(ancs_filtering_is_muted(&mute_weekends));
|
||||
cl_assert(!ancs_filtering_is_muted(&mute_weekdays));
|
||||
|
||||
s_now += SECONDS_PER_DAY; // Monday Jan 4, 2016
|
||||
cl_assert(ancs_filtering_is_muted(&mute_always));
|
||||
cl_assert(!ancs_filtering_is_muted(&mute_weekends));
|
||||
cl_assert(ancs_filtering_is_muted(&mute_weekdays));
|
||||
}
|
||||
|
||||
void test_ancs_filtering__record_app_no_display_name(void) {
|
||||
iOSNotifPrefs *existing_prefs = NULL;
|
||||
|
||||
// No display name so we expect the app name to be the title
|
||||
AttributeList expected_attributes = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdAppName, .cstring = "Apple Pay = :(" },
|
||||
{ .id = AttributeIdMuteDayOfWeek, .uint8 = MuteBitfield_None },
|
||||
{ .id = AttributeIdLastUpdated, .uint32 = s_now },
|
||||
}
|
||||
};
|
||||
s_expected_attributes = &expected_attributes;
|
||||
|
||||
ancs_filtering_record_app(&existing_prefs, s_app_id_attr, NULL, s_title_attr);
|
||||
cl_assert(s_performed_store);
|
||||
|
||||
// Make sure the our existing prefs got updated
|
||||
iOSNotifPrefs expected_prefs = {
|
||||
.attr_list = expected_attributes,
|
||||
};
|
||||
prv_compare_notif_prefs(existing_prefs, &expected_prefs);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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/alerts_preferences.h"
|
||||
#include "services/normal/notifications/ancs/ancs_notifications.h"
|
||||
#include "services/normal/blob_db/ios_notif_pref_db.h"
|
||||
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "stubs_analytics.h"
|
||||
#include "stubs_i18n.h"
|
||||
#include "stubs_layout_layer.h"
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_notifications.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
#include "stubs_pin_db.h"
|
||||
#include "stubs_regular_timer.h"
|
||||
#include "stubs_reminder_db.h"
|
||||
#include "stubs_timeline.h"
|
||||
#include "stubs_uuid.h"
|
||||
#include "stubs_nexmo.h"
|
||||
|
||||
iOSNotifPrefs* ios_notif_pref_db_get_prefs(const uint8_t *app_id, int length) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ios_notif_pref_db_free_prefs(iOSNotifPrefs *prefs) {
|
||||
return;
|
||||
}
|
||||
|
||||
void ancs_filtering_record_app(iOSNotifPrefs *app_notif_prefs,
|
||||
const ANCSAttribute *app_id,
|
||||
const ANCSAttribute *display_name,
|
||||
const ANCSAttribute *title) {
|
||||
}
|
||||
|
||||
bool ancs_filtering_is_muted(const iOSNotifPrefs *app_notif_prefs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Fakes
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "fake_events.h"
|
||||
#include "fake_notification_storage.h"
|
||||
|
||||
static time_t s_now;
|
||||
time_t rtc_get_time(void) {
|
||||
return s_now;
|
||||
}
|
||||
|
||||
RtcTicks rtc_get_ticks(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_ancs_notifications__initialize(void) {
|
||||
s_now = 1;
|
||||
fake_notification_storage_reset();
|
||||
fake_event_init();
|
||||
}
|
||||
|
||||
void test_ancs_notifications__cleanup(void) {
|
||||
}
|
||||
|
||||
void test_ancs_notifications__handle_phone_call_message(void) {
|
||||
|
||||
const uint8_t app_id[] = {
|
||||
0x00,
|
||||
21, 0x00,
|
||||
'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.',
|
||||
'm', 'o', 'b', 'i', 'l', 'e', 'p', 'h', 'o', 'n', 'e',
|
||||
};
|
||||
const uint8_t title[] = {
|
||||
0x01,
|
||||
23, 0x00,
|
||||
// Add some formatting modifiers before and after. iOS 10 seems to be sending phone numbers with them now.
|
||||
0xe2, 0x80, 0xad, '+', '1', ' ', '(', '5', '1', '0', ')', ' ', '4', '4', '4', '-', '3', '3', '3', '3', 0xe2, 0x80, 0xac,
|
||||
};
|
||||
const uint8_t subtitle[] = {
|
||||
0x02,
|
||||
8, 0x00,
|
||||
'P', 'e', 'b', 'b', 'l', 'e', 'H', 'Q',
|
||||
};
|
||||
const uint8_t message[] = {
|
||||
0x03,
|
||||
13, 0x00,
|
||||
'I', 'n', 'c', 'o', 'm', 'i', 'n', 'g', ' ', 'C', 'a', 'l', 'l',
|
||||
};
|
||||
const uint8_t date[] = {
|
||||
0x05,
|
||||
0x00, 0x00,
|
||||
};
|
||||
const uint8_t positive_action[] = {
|
||||
0x06,
|
||||
6, 0x00,
|
||||
'A', 'n', 's', 'w', 'e', 'r',
|
||||
};
|
||||
const uint8_t negative_action[] = {
|
||||
0x07,
|
||||
7, 0x00,
|
||||
'D', 'e', 'c', 'l', 'i', 'n', 'e',
|
||||
};
|
||||
|
||||
ANCSAttribute *notif_attributes[] = {
|
||||
[FetchedNotifAttributeIndexAppID] = (ANCSAttribute *)&app_id,
|
||||
[FetchedNotifAttributeIndexTitle] = (ANCSAttribute *)&title,
|
||||
[FetchedNotifAttributeIndexSubtitle] = (ANCSAttribute *)&subtitle,
|
||||
[FetchedNotifAttributeIndexMessage] = (ANCSAttribute *)&message,
|
||||
[FetchedNotifAttributeIndexDate]= (ANCSAttribute *)&date,
|
||||
[FetchedNotifAttributeIndexPositiveActionLabel] = (ANCSAttribute *)&positive_action,
|
||||
[FetchedNotifAttributeIndexNegativeActionLabel] = (ANCSAttribute *)&negative_action,
|
||||
};
|
||||
|
||||
const uint8_t app_display_name[] = {
|
||||
0x00,
|
||||
5, 0x0,
|
||||
'P', 'h', 'o', 'n', 'e',
|
||||
};
|
||||
|
||||
ANCSAttribute *app_attributes[] = {
|
||||
[FetchedAppAttributeIndexDisplayName] = (ANCSAttribute *)&app_display_name,
|
||||
};
|
||||
|
||||
ANCSProperty properties = ANCSProperty_IncomingCall;
|
||||
|
||||
ancs_notifications_handle_message(37, properties, notif_attributes, app_attributes);
|
||||
|
||||
// We just processed an incomming phone call event, there better be a phone event scheduled!
|
||||
PebbleEvent event = fake_event_get_last();
|
||||
|
||||
cl_assert_equal_i(event.type, PEBBLE_PHONE_EVENT);
|
||||
cl_assert_equal_i(event.phone.type, PhoneEventType_Incoming);
|
||||
cl_assert_equal_i(event.phone.source, PhoneCallSource_ANCS_Legacy);
|
||||
}
|
||||
|
||||
void test_ancs_notifications__handle_phone_call_removed(void) {
|
||||
const uint32_t uid = 5;
|
||||
|
||||
// Make sure we don't send any events when this isn't iOS9
|
||||
ancs_notifications_handle_notification_removed(uid, ANCSProperty_IncomingCall);
|
||||
cl_assert_equal_i(fake_event_get_count(), 0);
|
||||
|
||||
// Make sure that we trigger an event when this is iOS9
|
||||
ancs_notifications_handle_notification_removed(uid,
|
||||
ANCSProperty_IncomingCall | ANCSProperty_iOS9);
|
||||
PebbleEvent event = fake_event_get_last();
|
||||
cl_assert_equal_i(fake_event_get_count(), 1);
|
||||
cl_assert_equal_i(event.type, PEBBLE_PHONE_EVENT);
|
||||
cl_assert_equal_i(event.phone.type, PhoneEventType_Hide);
|
||||
cl_assert_equal_i(event.phone.source, PhoneCallSource_ANCS);
|
||||
cl_assert_equal_i(event.phone.call_identifier, uid);
|
||||
|
||||
// Make sure that having a matching notification in notif_db still results in a call hide event
|
||||
fake_notification_storage_set_existing_ancs_notification(&(Uuid)UUID_SYSTEM, uid);
|
||||
ancs_notifications_handle_notification_removed(uid,
|
||||
ANCSProperty_IncomingCall | ANCSProperty_iOS9);
|
||||
event = fake_event_get_last();
|
||||
cl_assert_equal_i(fake_event_get_count(), 2);
|
||||
cl_assert_equal_i(event.type, PEBBLE_PHONE_EVENT);
|
||||
cl_assert_equal_i(event.phone.type, PhoneEventType_Hide);
|
||||
cl_assert_equal_i(event.phone.source, PhoneCallSource_ANCS);
|
||||
cl_assert_equal_i(event.phone.call_identifier, uid);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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_util.h"
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
|
||||
// Fakes
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "fakes/fake_rtc.h"
|
||||
|
||||
// Tests
|
||||
////////////////////////////////////////////////////////////////
|
||||
void test_ancs_notifications_util__initialize(void) {
|
||||
}
|
||||
|
||||
void test_ancs_notifications_util__cleanup(void) {
|
||||
}
|
||||
|
||||
static ANCSAttribute *prv_create_ancs_attr(const char *str) {
|
||||
const size_t len = strlen(str);
|
||||
ANCSAttribute *attr = malloc(sizeof(ANCSAttribute) + len);
|
||||
attr->length = len;
|
||||
memcpy(&attr->value, str, len);
|
||||
return attr;
|
||||
}
|
||||
|
||||
static void prv_destroy_ancs_attr(ANCSAttribute *attr) {
|
||||
free(attr);
|
||||
}
|
||||
|
||||
void test_ancs_notifications_util__parse_timestamp(void) {
|
||||
struct tm apr_3_13_00 = {
|
||||
.tm_sec = 0,
|
||||
.tm_min = 0,
|
||||
.tm_hour = 13,
|
||||
.tm_mday = 3,
|
||||
.tm_mon = 3, // Apr
|
||||
.tm_year = 2015 - 1900,
|
||||
.tm_isdst = 1,
|
||||
};
|
||||
|
||||
// DST info for US/Canada 2015
|
||||
TimezoneInfo tz_info = {
|
||||
.dst_start = 1425780000, // Sun, 08 Mar 2015 02:00
|
||||
.dst_end = 1446343200 // Sun, 01 Nov 2015 02:00
|
||||
};
|
||||
time_util_update_timezone(&tz_info);
|
||||
|
||||
time_t actual = mktime(&apr_3_13_00);
|
||||
rtc_set_time(actual);
|
||||
|
||||
ANCSAttribute *valid_date = prv_create_ancs_attr("20150403T130000");
|
||||
time_t calculated = ancs_notifications_util_parse_timestamp(valid_date);
|
||||
prv_destroy_ancs_attr(valid_date);
|
||||
cl_assert_equal_i(calculated, actual);
|
||||
|
||||
ANCSAttribute *invalid_date = prv_create_ancs_attr("b4150403T123456");
|
||||
calculated = ancs_notifications_util_parse_timestamp(invalid_date);
|
||||
prv_destroy_ancs_attr(invalid_date);
|
||||
cl_assert_equal_i(calculated, 0);
|
||||
|
||||
ANCSAttribute *crazy_bad_date = prv_create_ancs_attr("F");
|
||||
calculated = ancs_notifications_util_parse_timestamp(crazy_bad_date);
|
||||
prv_destroy_ancs_attr(crazy_bad_date);
|
||||
cl_assert_equal_i(calculated, 0);
|
||||
|
||||
ANCSAttribute *zero_length_date = prv_create_ancs_attr("");
|
||||
calculated = ancs_notifications_util_parse_timestamp(zero_length_date);
|
||||
prv_destroy_ancs_attr(zero_length_date);
|
||||
cl_assert_equal_i(calculated, 0);
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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/nexmo.h"
|
||||
#include "services/normal/notifications/ancs/ancs_notifications_util.h"
|
||||
#include "services/normal/timeline/attributes_actions.h"
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////////////////////////////////
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
|
||||
// Fakes
|
||||
////////////////////////////////////////////////////////////////
|
||||
extern const char *NEXMO_REAUTH_STRING;
|
||||
|
||||
static AttributeList *s_expected_attributes = NULL;
|
||||
static TimelineItemActionGroup *s_expected_actions = NULL;
|
||||
static bool s_performed_store = false;
|
||||
|
||||
status_t ios_notif_pref_db_store_prefs(const uint8_t *app_id, int length, AttributeList *attr_list,
|
||||
TimelineItemActionGroup *action_group) {
|
||||
const int buf_size = 256;
|
||||
uint8_t buf1[buf_size];
|
||||
uint8_t buf2[buf_size];
|
||||
attributes_actions_serialize_payload(attr_list, action_group, buf1, buf_size);
|
||||
attributes_actions_serialize_payload(s_expected_attributes, s_expected_actions, buf2, buf_size);
|
||||
cl_assert_equal_m(buf1, buf2, attributes_actions_get_serialized_payload_size(s_expected_attributes, s_expected_actions));
|
||||
|
||||
s_performed_store = true;
|
||||
return S_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t s_expected_uid = 0;
|
||||
static bool s_performed_dismiss = false;
|
||||
|
||||
void ancs_perform_action(uint32_t notification_uid, uint8_t action_id) {
|
||||
cl_assert_equal_i(notification_uid, s_expected_uid);
|
||||
cl_assert_equal_i(action_id, ActionIDNegative);
|
||||
s_performed_dismiss = true;
|
||||
}
|
||||
|
||||
void test_nexmo__initialize(void) {
|
||||
s_expected_attributes = NULL;
|
||||
s_expected_actions = NULL;
|
||||
s_performed_store = false;
|
||||
s_expected_uid = INVALID_UID;
|
||||
s_performed_dismiss = false;
|
||||
}
|
||||
|
||||
void test_nexmo__cleanup(void) {
|
||||
}
|
||||
|
||||
void test_nexmo__is_reuath_sms(void) {
|
||||
uint8_t expected_app_id_buf[128];
|
||||
ANCSAttribute *expected_app_id = (ANCSAttribute *)&expected_app_id_buf;
|
||||
expected_app_id->length = strlen(IOS_SMS_APP_ID);
|
||||
memcpy(expected_app_id->value, IOS_SMS_APP_ID, strlen(IOS_SMS_APP_ID));
|
||||
|
||||
char valid_message[128];
|
||||
strcpy(valid_message, "possible preamble ");
|
||||
strcat(valid_message, NEXMO_REAUTH_STRING);
|
||||
strcat(valid_message, " possible postamble");
|
||||
|
||||
uint8_t expected_message_buf[128];
|
||||
ANCSAttribute *expected_message = (ANCSAttribute *)&expected_message_buf;
|
||||
expected_message->length = strlen(valid_message);
|
||||
memcpy(expected_message->value, valid_message, strlen(valid_message));
|
||||
|
||||
|
||||
uint8_t bad_app_id_buf[128];
|
||||
ANCSAttribute *bad_app_id = (ANCSAttribute *)&bad_app_id_buf;
|
||||
bad_app_id->length = strlen(IOS_MAIL_APP_ID);
|
||||
memcpy(bad_app_id->value, IOS_MAIL_APP_ID, strlen(IOS_MAIL_APP_ID));
|
||||
|
||||
const char *bad_string = "Phil was here";
|
||||
uint8_t bad_message_buf[128];
|
||||
ANCSAttribute *bad_message = (ANCSAttribute *)&bad_message_buf;
|
||||
bad_message->length = strlen(bad_string);
|
||||
memcpy(bad_message->value, bad_string, strlen(bad_string));
|
||||
|
||||
|
||||
cl_assert(nexmo_is_reauth_sms(expected_app_id, expected_message));
|
||||
cl_assert(!nexmo_is_reauth_sms(bad_app_id, expected_message));
|
||||
cl_assert(!nexmo_is_reauth_sms(expected_app_id, bad_message));
|
||||
cl_assert(!nexmo_is_reauth_sms(bad_app_id, bad_message));
|
||||
}
|
||||
|
||||
void test_nexmo__handle_reuath_sms(void) {
|
||||
// UID
|
||||
const uint32_t uid = 42;
|
||||
s_expected_uid = uid;
|
||||
|
||||
// App ID
|
||||
uint8_t app_id_buf[128];
|
||||
ANCSAttribute *app_id = (ANCSAttribute *)&app_id_buf;
|
||||
app_id->length = strlen(IOS_SMS_APP_ID);
|
||||
memcpy(app_id->value, IOS_SMS_APP_ID, strlen(IOS_SMS_APP_ID));
|
||||
|
||||
// Message
|
||||
char valid_message[128];
|
||||
strcpy(valid_message, "possible preamble ");
|
||||
strcat(valid_message, NEXMO_REAUTH_STRING);
|
||||
strcat(valid_message, " possible postamble");
|
||||
|
||||
uint8_t message_buf[128];
|
||||
ANCSAttribute *message = (ANCSAttribute *)&message_buf;
|
||||
message->length = strlen(valid_message);
|
||||
memcpy(message->value, valid_message, strlen(valid_message));
|
||||
|
||||
// Existing prefs
|
||||
iOSNotifPrefs existing_prefs = {
|
||||
.attr_list = {
|
||||
.num_attributes = 3,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Title" },
|
||||
{ .id = AttributeIdBody, .cstring = "Body" },
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Make sure that the prefs we store are the existing ones + the reauth msg
|
||||
AttributeList expected_attr_list = {
|
||||
.num_attributes = 4,
|
||||
.attributes = (Attribute[]) {
|
||||
{ .id = AttributeIdTitle, .cstring = "Title" },
|
||||
{ .id = AttributeIdBody, .cstring = "Body" },
|
||||
{ .id = AttributeIdAppName, .cstring = "Awesome" },
|
||||
{ .id = AttributeIdAuthCode, .cstring = valid_message },
|
||||
},
|
||||
};
|
||||
s_expected_attributes = &expected_attr_list;
|
||||
|
||||
nexmo_handle_reauth_sms(uid, app_id, message, &existing_prefs);
|
||||
cl_assert(s_performed_store);
|
||||
cl_assert(s_performed_dismiss);
|
||||
}
|
||||
@@ -0,0 +1,903 @@
|
||||
/*
|
||||
* 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 "services/normal/notifications/notification_storage.h"
|
||||
#include "services/normal/notifications/notification_storage_private.h"
|
||||
|
||||
#include "flash_region/flash_region.h"
|
||||
#include "services/normal/filesystem/pfs.h"
|
||||
#include "util/size.h"
|
||||
|
||||
#include "clar.h"
|
||||
|
||||
#include "stdbool.h"
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////
|
||||
#include "fake_spi_flash.h"
|
||||
#include "fake_rtc.h"
|
||||
#include "stubs_analytics.h"
|
||||
#include "stubs_hexdump.h"
|
||||
#include "stubs_layout_layer.h"
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_mutex.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_pbl_malloc.h"
|
||||
#include "stubs_pebble_tasks.h"
|
||||
#include "stubs_prompt.h"
|
||||
#include "stubs_rand_ptr.h"
|
||||
#include "stubs_serial.h"
|
||||
#include "stubs_sleep.h"
|
||||
#include "stubs_task_watchdog.h"
|
||||
|
||||
#define TEST_START FLASH_REGION_FILE_TEST_SPACE_BEGIN
|
||||
#define TEST_SIZE (FLASH_REGION_FILE_TEST_SPACE_END - \
|
||||
FLASH_REGION_FILE_TEST_SPACE_BEGIN)
|
||||
|
||||
extern void notification_storage_reset(void);
|
||||
|
||||
typedef void (*SystemTaskEventCallback)(void *data);
|
||||
|
||||
static Attribute action1_attributes[] = {
|
||||
{.id = AttributeIdTitle, .cstring = "Dismiss"},
|
||||
};
|
||||
|
||||
static Attribute action2_attributes[] = {
|
||||
{.id = AttributeIdTitle, .cstring = "Archive"},
|
||||
};
|
||||
|
||||
static StringList string_list = {
|
||||
.serialized_byte_length = 3,
|
||||
.data = "A\0B",
|
||||
};
|
||||
|
||||
static Attribute action3_attributes[] = {
|
||||
{.id = AttributeIdAncsAction, .int8 = 1},
|
||||
{.id = AttributeIdCannedResponses, .string_list = &string_list,},
|
||||
};
|
||||
|
||||
static TimelineItemAction actions[] = {
|
||||
{
|
||||
.id = 0,
|
||||
.type = TimelineItemActionTypeResponse,
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(action1_attributes),
|
||||
.attributes = action1_attributes
|
||||
}
|
||||
},
|
||||
{
|
||||
.id = 1, .type = TimelineItemActionTypeResponse,
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(action2_attributes),
|
||||
.attributes = action2_attributes
|
||||
}
|
||||
},
|
||||
{
|
||||
.id = 2,
|
||||
.type = TimelineItemActionTypeResponse,
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(action3_attributes),
|
||||
.attributes = action3_attributes
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static Attribute attributes[] = {
|
||||
{.id = AttributeIdTitle, .cstring = "Sender"},
|
||||
{.id = AttributeIdBody, .cstring = "Message"},
|
||||
{.id = AttributeIdSubtitle, .cstring = "Subject"},
|
||||
};
|
||||
|
||||
bool system_task_add_callback(SystemTaskEventCallback cb, void *data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PebblePhoneCaller* phone_call_util_create_caller(const char *number, const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Setup
|
||||
////////////////////////////////////
|
||||
|
||||
void test_notification_storage__initialize(void) {
|
||||
fake_spi_flash_init(0, 0x1000000);
|
||||
pfs_init(false);
|
||||
pfs_format(false /* write erase headers */);
|
||||
notification_storage_reset();
|
||||
}
|
||||
|
||||
void test_notification_storage__cleanup(void) {
|
||||
}
|
||||
|
||||
static void compare_attr_list(AttributeList a, AttributeList b) {
|
||||
cl_assert_equal_i(a.num_attributes, b.num_attributes);
|
||||
for (int i = 0; i < a.num_attributes; i++) {
|
||||
cl_assert_equal_i(a.attributes[i].id, b.attributes[i].id);
|
||||
switch (a.attributes[i].id) {
|
||||
case AttributeIdTitle:
|
||||
case AttributeIdSubtitle:
|
||||
case AttributeIdBody:
|
||||
cl_assert_equal_s(a.attributes[i].cstring, b.attributes[i].cstring);
|
||||
break;
|
||||
case AttributeIdAncsAction:
|
||||
cl_assert_equal_i(a.attributes[i].int8, b.attributes[i].int8);
|
||||
break;
|
||||
case AttributeIdCannedResponses: {
|
||||
StringList *list_a = a.attributes[i].string_list;
|
||||
StringList *list_b = b.attributes[i].string_list;
|
||||
cl_assert_equal_i(list_a->serialized_byte_length, list_b->serialized_byte_length);
|
||||
cl_assert_equal_i(
|
||||
string_list_count(list_a),
|
||||
string_list_count(list_b)
|
||||
);
|
||||
uint32_t count = string_list_count(list_a);
|
||||
for (uint32_t idx = 0; i<count; i++) {
|
||||
cl_assert_equal_s(
|
||||
string_list_get_at(list_a, idx),
|
||||
string_list_get_at(list_b, idx)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cl_assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void compare_notifications(TimelineItem *a, TimelineItem *b) {
|
||||
cl_assert(uuid_equal(&a->header.id, &b->header.id));
|
||||
cl_assert_equal_i(a->header.ancs_uid, b->header.ancs_uid);
|
||||
cl_assert_equal_i(a->header.status, b->header.status);
|
||||
cl_assert_equal_i(a->header.timestamp, b->header.timestamp);
|
||||
cl_assert_equal_i(a->header.layout, b->header.layout);
|
||||
compare_attr_list(a->attr_list, b->attr_list);
|
||||
cl_assert_equal_i(a->action_group.num_actions, b->action_group.num_actions);
|
||||
for (int i = 0; i < a->action_group.num_actions; i++) {
|
||||
cl_assert_equal_i(a->action_group.actions[i].id, b->action_group.actions[i].id);
|
||||
cl_assert_equal_i(a->action_group.actions[i].type, b->action_group.actions[i].type);
|
||||
compare_attr_list(a->action_group.actions[i].attr_list, b->action_group.actions[i].attr_list);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
////////////////////////////////////
|
||||
void test_notification_storage__basic(void) {
|
||||
Uuid id = {0x6b, 0xf6, 0x21, 0x5b, 0xc9, 0x7f, 0x40, 0x9e,
|
||||
0x8c, 0x31, 0x4f, 0x55, 0x65, 0x72, 0x22, 0xb4};
|
||||
TimelineItem e = {
|
||||
.header = {
|
||||
.id = id,
|
||||
.status = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.type = TimelineItemTypeNotification,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&id, &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&id, &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
Uuid invalid_uuid;
|
||||
uuid_generate(&invalid_uuid);
|
||||
cl_assert_equal_b(notification_storage_get(&invalid_uuid, &r), false);
|
||||
}
|
||||
|
||||
void test_notification_storage__multiple(void) {
|
||||
Uuid i1 ;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
TimelineItem e2 = {
|
||||
.header = {
|
||||
.id = i2,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda6,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 2,
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 1,
|
||||
.actions = &actions[2],
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i3;
|
||||
uuid_generate(&i3);
|
||||
TimelineItem e3 = {
|
||||
.header = {
|
||||
.id = i3,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda7,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = &attributes[2],
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 2,
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
notification_storage_store(&e2);
|
||||
notification_storage_store(&e3);
|
||||
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&i2, &r));
|
||||
compare_notifications(&e2, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&i3, &r));
|
||||
compare_notifications(&e3, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
}
|
||||
|
||||
void test_notification_storage__remove_single(void) {
|
||||
Uuid i;
|
||||
uuid_generate(&i);
|
||||
TimelineItem e = {
|
||||
.header = {
|
||||
.id = i,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&i, &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
notification_storage_remove(&i);
|
||||
cl_assert_equal_b(notification_storage_get(&i, &r), false);
|
||||
}
|
||||
|
||||
void test_notification_storage__set_actioned_flag(void) {
|
||||
Uuid i;
|
||||
uuid_generate(&i);
|
||||
TimelineItem e = {
|
||||
.header = {
|
||||
.id = i,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&i, &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
notification_storage_set_status(&i, TimelineItemStatusActioned);
|
||||
cl_assert(notification_storage_get(&i, &r));
|
||||
cl_assert(uuid_equal(&e.header.id, &r.header.id));
|
||||
cl_assert_equal_i(e.header.ancs_uid, r.header.ancs_uid);
|
||||
cl_assert_equal_i(TimelineItemStatusActioned, r.header.status);
|
||||
cl_assert_equal_i(e.header.timestamp, r.header.timestamp);
|
||||
cl_assert_equal_i(e.header.layout, r.header.layout);
|
||||
compare_attr_list(e.attr_list, r.attr_list);
|
||||
}
|
||||
|
||||
void test_notification_storage__remove_multiple_first(void) {
|
||||
Uuid i1;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
TimelineItem e2 = {
|
||||
.header = {
|
||||
.id = i2,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda6,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 2,
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 1,
|
||||
.actions = &actions[2],
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
notification_storage_store(&e2);
|
||||
|
||||
notification_storage_remove(&i1);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert_equal_b(notification_storage_get(&i1, &r), false);
|
||||
|
||||
cl_assert(notification_storage_get(&i2, &r));
|
||||
compare_notifications(&e2, &r);
|
||||
free(r.allocated_buffer);
|
||||
}
|
||||
|
||||
void test_notification_storage__remove_add(void) {
|
||||
Uuid i1;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
TimelineItem e2 = {
|
||||
.header = {
|
||||
.id = i2,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda6,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 2,
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 1,
|
||||
.actions = &actions[2],
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i3;
|
||||
uuid_generate(&i3);
|
||||
TimelineItem e3 = {
|
||||
.header = {
|
||||
.id = i3,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda7,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = &attributes[2],
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 2,
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
notification_storage_store(&e2);
|
||||
|
||||
notification_storage_remove(&i2);
|
||||
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert_equal_b(notification_storage_get(&i2, &r), false);
|
||||
|
||||
notification_storage_store(&e3);
|
||||
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert_equal_b(notification_storage_get(&i2, &r), false);
|
||||
|
||||
cl_assert(notification_storage_get(&i3, &r));
|
||||
compare_notifications(&e3, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
e2.header.timestamp = e3.header.timestamp + 1;
|
||||
notification_storage_store(&e2);
|
||||
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&e1, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&i2, &r));
|
||||
compare_notifications(&e2, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&i3, &r));
|
||||
compare_notifications(&e3, &r);
|
||||
free(r.allocated_buffer);
|
||||
}
|
||||
|
||||
void test_notification_storage__remove_add_compress(void) {
|
||||
time_t timestamp = 0x10000000;
|
||||
TimelineItem e = {
|
||||
.header = {
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const size_t notif_size = sizeof(SerializedTimelineItemHeader) +
|
||||
timeline_item_get_serialized_payload_size(&e);
|
||||
const size_t file_size = NOTIFICATION_STORAGE_FILE_SIZE;
|
||||
const size_t count = file_size / notif_size;
|
||||
Uuid uuids[count];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
uuid_generate(&uuids[i]);
|
||||
e.header.id = uuids[i];
|
||||
e.header.timestamp = timestamp + i;
|
||||
notification_storage_store(&e);
|
||||
}
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&uuids[0], &r));
|
||||
e.header.id = uuids[0];
|
||||
e.header.timestamp = timestamp;
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
cl_assert(notification_storage_get(&uuids[i - 1], &r));
|
||||
e.header.id = uuids[i - 1];
|
||||
e.header.timestamp = timestamp + i - 1;
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
// Storage is now full and none have been removed.
|
||||
// As more space is needed, blocks of 4k are freed up
|
||||
Uuid uuid;
|
||||
uuid_generate(&uuid);
|
||||
e.header.id = uuid;
|
||||
e.header.timestamp = timestamp + i;
|
||||
notification_storage_store(&e);
|
||||
cl_assert(notification_storage_get(&uuid, &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
const size_t block_size = file_size / 4;
|
||||
int erase_count = block_size / notif_size + (((block_size % notif_size) > 0) ? 1 : 0);
|
||||
int j;
|
||||
for (j = 0; j < erase_count; j++) {
|
||||
e.header.id = uuids[j];
|
||||
e.header.timestamp = timestamp + j;
|
||||
cl_assert_equal_b(notification_storage_get(&uuids[j], &r), false);
|
||||
}
|
||||
e.header.id = uuids[j];
|
||||
e.header.timestamp = timestamp + j;
|
||||
cl_assert(notification_storage_get(&uuids[j], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
// Fill up storage again
|
||||
for (++i; i < count + erase_count; i++) {
|
||||
e.header.id = uuids[i % count];
|
||||
e.header.timestamp = timestamp + i;
|
||||
notification_storage_store(&e);
|
||||
cl_assert(notification_storage_get(&uuids[i % count], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
}
|
||||
|
||||
//Check that no notifications have been deleted
|
||||
e.header.id = uuids[j];
|
||||
e.header.timestamp = timestamp + j;
|
||||
cl_assert(notification_storage_get(&uuids[j], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
//Free up enough space for one notification by removing one
|
||||
notification_storage_remove(&uuids[i/2]);
|
||||
e.header.id = uuids[i/2];
|
||||
e.header.timestamp = timestamp + i/2;
|
||||
cl_assert_equal_b(notification_storage_get(&uuids[i/2], &r), false);
|
||||
|
||||
//Add another notification. Compression should take place without freeing up a 4k block
|
||||
e.header.id = uuids[i];
|
||||
e.header.timestamp = timestamp + i;
|
||||
notification_storage_store(&e);
|
||||
cl_assert(notification_storage_get(&uuids[i], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
//Ensure that compression does not remove old notifications
|
||||
e.header.id = uuids[j];
|
||||
e.header.timestamp = timestamp + j;
|
||||
cl_assert(notification_storage_get(&uuids[j], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
//Add another notification. Compression should free up another 4k block
|
||||
e.header.id = uuids[i];
|
||||
e.header.timestamp = timestamp + i;
|
||||
notification_storage_store(&e);
|
||||
cl_assert(notification_storage_get(&uuids[i], &r));
|
||||
compare_notifications(&e, &r);
|
||||
free(r.allocated_buffer);
|
||||
|
||||
// Check that an expected number of notifications were removed
|
||||
erase_count += j;
|
||||
for (; j < erase_count; j++) {
|
||||
e.header.id = uuids[j];
|
||||
e.header.timestamp = timestamp + j;
|
||||
cl_assert_equal_b(notification_storage_get(&uuids[j], &r), false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_notification_storage__find_ancs_id(void) {
|
||||
Uuid i1;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
TimelineItem e2 = {
|
||||
.header = {
|
||||
.id = i2,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 1,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda6,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 2,
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 1,
|
||||
.actions = &actions[2],
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i3;
|
||||
uuid_generate(&i3);
|
||||
TimelineItem e3 = {
|
||||
.header = {
|
||||
.id = i3,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 84,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda7,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = &attributes[2],
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 2,
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
notification_storage_store(&e2);
|
||||
notification_storage_store(&e3);
|
||||
|
||||
Uuid u;
|
||||
cl_assert(notification_storage_find_ancs_notification_id(0, &u));
|
||||
cl_assert(uuid_equal(&u, &e1.header.id));
|
||||
cl_assert(notification_storage_find_ancs_notification_id(1, &u));
|
||||
cl_assert(uuid_equal(&u, &e2.header.id));
|
||||
cl_assert(notification_storage_find_ancs_notification_id(84, &u));
|
||||
cl_assert(uuid_equal(&u, &e3.header.id));
|
||||
|
||||
// Add a new notification with the same ANCS UID as an existing notification to make sure we
|
||||
// return the new notification instead of the old one
|
||||
TimelineItem e4 = e3;
|
||||
uuid_generate(&e4.header.id);
|
||||
notification_storage_store(&e4);
|
||||
cl_assert(notification_storage_find_ancs_notification_id(84, &u));
|
||||
cl_assert(uuid_equal(&u, &e4.header.id));
|
||||
}
|
||||
|
||||
void test_notification_storage__find_by_timestamp(void) {
|
||||
Uuid i1;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
TimelineItem e2 = {
|
||||
.header = {
|
||||
.id = i2,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 1,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda6,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 2,
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 1,
|
||||
.actions = &actions[2],
|
||||
}
|
||||
};
|
||||
|
||||
Uuid i3;
|
||||
uuid_generate(&i3);
|
||||
TimelineItem e3 = {
|
||||
.header = {
|
||||
.id = i3,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = 0,
|
||||
.ancs_uid = 84,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda7,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = 1,
|
||||
.attributes = &attributes[2],
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = 2,
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
notification_storage_store(&e2);
|
||||
notification_storage_store(&e3);
|
||||
|
||||
TimelineItem test = e1;
|
||||
test.header.id = UUID_INVALID;
|
||||
test.header.ancs_uid = 51;
|
||||
|
||||
CommonTimelineItemHeader h;
|
||||
cl_assert(notification_storage_find_ancs_notification_by_timestamp(&test, &h));
|
||||
cl_assert_equal_m(&e1.header, &h, sizeof(CommonTimelineItemHeader));
|
||||
|
||||
test.action_group.num_actions = 2;
|
||||
cl_assert_equal_b(notification_storage_find_ancs_notification_by_timestamp(&test, &h),
|
||||
false);
|
||||
|
||||
test = e2;
|
||||
test.header.id = UUID_INVALID;
|
||||
cl_assert(notification_storage_find_ancs_notification_by_timestamp(&test, &h));
|
||||
cl_assert_equal_m(&e2.header, &h, sizeof(CommonTimelineItemHeader));
|
||||
|
||||
test = e3;
|
||||
test.header.id = UUID_INVALID;
|
||||
cl_assert(notification_storage_find_ancs_notification_by_timestamp(&test, &h));
|
||||
cl_assert_equal_m(&e3.header, &h, sizeof(CommonTimelineItemHeader));
|
||||
|
||||
notification_storage_remove(&i2);
|
||||
test = e2;
|
||||
test.header.id = UUID_INVALID;
|
||||
cl_assert_equal_b(notification_storage_find_ancs_notification_by_timestamp(&test, &h),
|
||||
false);
|
||||
|
||||
test = e3;
|
||||
test.header.id = UUID_INVALID;
|
||||
cl_assert(notification_storage_find_ancs_notification_by_timestamp(&test, &h));
|
||||
cl_assert_equal_m(&e3.header, &h, sizeof(CommonTimelineItemHeader));
|
||||
}
|
||||
|
||||
void test_notification_storage__should_detect_corruption(void) {
|
||||
Uuid i1;
|
||||
uuid_generate(&i1);
|
||||
TimelineItem e1 = {
|
||||
.header = {
|
||||
.id = i1,
|
||||
.type = TimelineItemTypeNotification,
|
||||
.status = TimelineItemStatusRead,
|
||||
.ancs_uid = 0,
|
||||
.layout = LayoutIdGeneric,
|
||||
.timestamp = 0x53f0dda5,
|
||||
},
|
||||
.attr_list = {
|
||||
.num_attributes = ARRAY_LENGTH(attributes),
|
||||
.attributes = attributes,
|
||||
},
|
||||
.action_group = {
|
||||
.num_actions = ARRAY_LENGTH(actions),
|
||||
.actions = actions,
|
||||
}
|
||||
};
|
||||
|
||||
notification_storage_store(&e1);
|
||||
TimelineItem r;
|
||||
cl_assert(notification_storage_get(&i1, &r));
|
||||
compare_notifications(&r, &e1);
|
||||
|
||||
TimelineItem e2 = e1;
|
||||
Uuid i2;
|
||||
uuid_generate(&i2);
|
||||
e2.header.id = i2;
|
||||
e2.header.status = 0xC0;
|
||||
notification_storage_store(&e2);
|
||||
cl_assert_equal_b(notification_storage_get(&i2, &r), false);
|
||||
|
||||
TimelineItem e3 = e1;
|
||||
Uuid i3;
|
||||
uuid_generate(&i3);
|
||||
e3.header.id = i3;
|
||||
e3.header.type = TimelineItemTypeOutOfRange;
|
||||
notification_storage_store(&e3);
|
||||
cl_assert_equal_b(notification_storage_get(&i3, &r), false);
|
||||
|
||||
Uuid i4;
|
||||
uuid_generate(&i4);
|
||||
TimelineItem e4 = e1;
|
||||
e4.header.id = i4;
|
||||
e4.header.layout = NumLayoutIds;
|
||||
notification_storage_store(&e4);
|
||||
cl_assert_equal_b(notification_storage_get(&i4, &r), false);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
from waftools.pebble_test import clar
|
||||
|
||||
def build(ctx):
|
||||
clar(ctx,
|
||||
sources_ant_glob = "src/fw/services/normal/notifications/notification_storage.c" \
|
||||
" src/fw/util/rand/rand.c" \
|
||||
" src/fw/vendor/tinymt32/tinymt32.c" \
|
||||
" src/fw/util/stringlist.c" \
|
||||
" src/fw/util/time/time.c" \
|
||||
" src/fw/services/normal/filesystem/flash_translation.c" \
|
||||
" src/fw/services/normal/filesystem/pfs.c" \
|
||||
" src/fw/services/normal/timeline/item.c" \
|
||||
" src/fw/services/normal/timeline/attributes_actions.c" \
|
||||
" src/fw/services/normal/timeline/attribute_group.c" \
|
||||
" src/fw/services/normal/timeline/attribute.c" \
|
||||
" src/fw/flash_region/flash_region.c" \
|
||||
" src/fw/flash_region/filesystem_regions.c" \
|
||||
" src/fw/util/crc8.c" \
|
||||
" src/fw/util/legacy_checksum.c" \
|
||||
" tests/fakes/fake_rtc.c" \
|
||||
" tests/fakes/fake_spi_flash.c",
|
||||
test_sources_ant_glob = "test_notification_storage.c",
|
||||
override_includes=['dummy_board'])
|
||||
|
||||
clar(ctx,
|
||||
sources_ant_glob = \
|
||||
" 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_item.c " \
|
||||
" src/fw/services/normal/notifications/ancs/ancs_phone_call.c " \
|
||||
" src/fw/services/normal/timeline/attribute.c" \
|
||||
" src/fw/services/normal/timeline/attributes_actions.c" \
|
||||
" src/fw/services/normal/timeline/attribute_group.c" \
|
||||
" src/fw/services/normal/timeline/item.c" \
|
||||
" src/fw/services/normal/phone_call_util.c" \
|
||||
" src/fw/applib/fonts/codepoint.c" \
|
||||
" src/fw/applib/graphics/utf8.c" \
|
||||
" src/fw/util/pstring.c" \
|
||||
" src/fw/util/time/time.c" \
|
||||
" tests/fakes/fake_events.c",
|
||||
test_sources_ant_glob = "test_ancs_notifications.c")
|
||||
|
||||
clar(ctx,
|
||||
sources_ant_glob = \
|
||||
" src/fw/services/normal/notifications/ancs/ancs_notifications_util.c " \
|
||||
" src/fw/util/time/mktime.c " \
|
||||
" src/fw/util/pstring.c" \
|
||||
" src/fw/util/time/time.c" \
|
||||
" tests/fakes/fake_rtc.c",
|
||||
test_sources_ant_glob = "test_ancs_notifications_util.c")
|
||||
|
||||
clar(ctx,
|
||||
sources_ant_glob = \
|
||||
" src/fw/services/normal/notifications/ancs/ancs_filtering.c " \
|
||||
" src/fw/services/normal/timeline/attribute.c" \
|
||||
" src/fw/services/normal/timeline/attributes_actions.c" \
|
||||
" src/fw/services/normal/timeline/attribute_group.c" \
|
||||
" src/fw/util/pstring.c" \
|
||||
" src/fw/util/time/time.c",
|
||||
test_sources_ant_glob = "test_ancs_filtering.c")
|
||||
|
||||
clar(ctx,
|
||||
sources_ant_glob = \
|
||||
" src/fw/services/normal/notifications/ancs/nexmo.c " \
|
||||
" src/fw/services/normal/notifications/ancs/ancs_notifications_util.c " \
|
||||
" src/fw/services/normal/timeline/attribute.c" \
|
||||
" src/fw/services/normal/timeline/attributes_actions.c" \
|
||||
" src/fw/services/normal/timeline/attribute_group.c" \
|
||||
" src/fw/util/pstring.c" \
|
||||
" src/fw/util/time/time.c " \
|
||||
" tests/fakes/fake_rtc.c ",
|
||||
test_sources_ant_glob = "test_nexmo.c")
|
||||
# vim:filetype=python
|
||||
Reference in New Issue
Block a user