mirror of
https://github.com/google/pebble.git
synced 2025-03-22 03:32:20 +00:00
304 lines
9.9 KiB
C
304 lines
9.9 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "services/normal/timeline/reminders.h"
|
|
|
|
#include "kernel/events.h"
|
|
#include "services/normal/filesystem/pfs.h"
|
|
|
|
#include "clar.h"
|
|
|
|
// Fixture
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Fakes
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#include "fake_new_timer.h"
|
|
#include "fake_pbl_malloc.h"
|
|
#include "fake_pebble_tasks.h"
|
|
#include "fake_spi_flash.h"
|
|
#include "fake_system_task.h"
|
|
#include "stubs_layout_layer.h"
|
|
static time_t now = 0;
|
|
static int num_events_put = 0;
|
|
|
|
|
|
time_t rtc_get_time(void) {
|
|
return now;
|
|
}
|
|
|
|
RtcTicks rtc_get_ticks(void) {
|
|
return 0;
|
|
}
|
|
|
|
typedef void (*CallbackEventCallback)(void *data);
|
|
|
|
void launcher_task_add_callback(CallbackEventCallback callback, void *data) {
|
|
callback(data);
|
|
}
|
|
|
|
void event_put(PebbleEvent* event) {
|
|
num_events_put++;
|
|
}
|
|
|
|
// Stubs
|
|
////////////////////////////////////////////////////////////////
|
|
#include "stubs_analytics.h"
|
|
#include "stubs_hexdump.h"
|
|
#include "stubs_logging.h"
|
|
#include "stubs_mutex.h"
|
|
#include "stubs_passert.h"
|
|
#include "stubs_prompt.h"
|
|
#include "stubs_regular_timer.h"
|
|
#include "stubs_sleep.h"
|
|
#include "stubs_task_watchdog.h"
|
|
|
|
extern TimerID get_reminder_timer_id(void);
|
|
|
|
static TimelineItem item1 = {
|
|
.header = {
|
|
.id = {0x6b, 0xf6, 0x21, 0x5b, 0xc9, 0x7f, 0x40, 0x9e,
|
|
0x8c, 0x31, 0x4f, 0x55, 0x65, 0x72, 0x22, 0xb4},
|
|
.timestamp = 0,
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
} // don't care about the rest
|
|
};
|
|
|
|
static TimelineItem item2 = {
|
|
.header = {
|
|
.id = {0x55, 0xcb, 0x7c, 0x75, 0x8a, 0x35, 0x44, 0x87,
|
|
0x90, 0xa4, 0x91, 0x3f, 0x1f, 0xa6, 0x76, 0x01},
|
|
.timestamp = 100,
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
}
|
|
};
|
|
|
|
static TimelineItem item3 = {
|
|
.header = {
|
|
.id = {0x7c, 0x65, 0x2e, 0xb9, 0x26, 0xd6, 0x44, 0x2c,
|
|
0x98, 0x68, 0xa4, 0x36, 0x79, 0x7d, 0xe2, 0x05},
|
|
.timestamp = 300,
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
}
|
|
};
|
|
|
|
static TimelineItem item4 = {
|
|
.header = {
|
|
.id = {0x8c, 0x65, 0x2e, 0xb9, 0x26, 0xd6, 0x44, 0x2c,
|
|
0x98, 0x68, 0xa4, 0x36, 0x79, 0x7d, 0xe2, 0x05},
|
|
.timestamp = 1337,
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
}
|
|
};
|
|
|
|
// Setup
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
void test_reminders__initialize(void) {
|
|
now = 0;
|
|
num_events_put = 0;
|
|
|
|
fake_spi_flash_init(0, 0x1000000);
|
|
pfs_init(false);
|
|
reminder_db_init();
|
|
|
|
// add all four explicitly out of order
|
|
cl_assert(S_SUCCESS == reminders_insert(&item4));
|
|
|
|
cl_assert(S_SUCCESS == reminders_insert(&item2));
|
|
|
|
cl_assert(S_SUCCESS == reminders_insert(&item1));
|
|
|
|
cl_assert(S_SUCCESS == reminders_insert(&item3));
|
|
}
|
|
|
|
void test_reminders__cleanup(void) {
|
|
//nada
|
|
}
|
|
|
|
// Tests
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
void test_reminders__timer_test(void) {
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 0);
|
|
cl_assert(memcmp(&item1.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId)) == 0);
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
cl_assert_equal_i(num_events_put, 1);
|
|
|
|
// item 2 is now the top reminder...
|
|
cl_assert_equal_m(&item2.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId));
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 100 * 1000);
|
|
// ...until we insert item 1 back
|
|
cl_assert(S_SUCCESS == reminders_insert(&item1));
|
|
cl_assert_equal_m(&item1.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId));
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 0);
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
cl_assert_equal_i(num_events_put, 2);
|
|
|
|
cl_assert_equal_m(&item2.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId));
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 100 * 1000);
|
|
now = 100;
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
cl_assert_equal_i(num_events_put, 3);
|
|
|
|
cl_assert_equal_m(&item3.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId));
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 200 * 1000);
|
|
now += 200;
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
cl_assert_equal_i(num_events_put, 4);
|
|
|
|
cl_assert_equal_m(&item4.header.id, stub_new_timer_callback_data(get_reminder_timer_id()), sizeof(TimelineItemId));
|
|
cl_assert(stub_new_timer_timeout(get_reminder_timer_id()) == 1037 * 1000);
|
|
now += 1037;
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
cl_assert_equal_i(num_events_put, 5);
|
|
|
|
cl_assert(!new_timer_scheduled(get_reminder_timer_id(), NULL));
|
|
}
|
|
|
|
void test_reminders__first_init_test(void) {
|
|
cl_assert_equal_i(reminders_init(), 0);
|
|
test_reminders__timer_test();
|
|
}
|
|
|
|
static TimelineItem s_stale_reminder = {
|
|
.header = {
|
|
.id = {0x3C, 0xAF, 0x17, 0xD5, 0xBE, 0x15, 0x4B, 0xFD, 0xAE, 0x2A,
|
|
0xAE, 0x44, 0xC0, 0x96, 0xCB, 0x7D},
|
|
.timestamp = 60 * 60,
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
}
|
|
};
|
|
|
|
void test_reminders__stale_item_insert(void) {
|
|
now = 3 * 60 * 60; // 3 hours after stale_reminder
|
|
cl_assert_equal_i(reminders_insert(&s_stale_reminder), E_INVALID_OPERATION);
|
|
}
|
|
|
|
void test_reminders__stale_item_init(void) {
|
|
cl_assert_equal_i(reminders_insert(&s_stale_reminder), S_SUCCESS);
|
|
stub_new_timer_stop(get_reminder_timer_id());
|
|
|
|
now = 1 * 60 * 60;
|
|
reminders_init();
|
|
cl_assert(new_timer_scheduled(get_reminder_timer_id(), NULL));
|
|
|
|
now = 3 * 60 * 60;
|
|
reminders_init();
|
|
cl_assert(!new_timer_scheduled(get_reminder_timer_id(), NULL));
|
|
}
|
|
|
|
static TimezoneInfo s_tz = {
|
|
.tm_gmtoff = -8 * 60 * 60, // PST
|
|
};
|
|
|
|
static TimelineItem s_all_day_reminder = {
|
|
.header = {
|
|
.id = {0x6b, 0xf6, 0x21, 0x5b, 0xc9, 0x7f, 0x40, 0x9e,
|
|
0x8c, 0x31, 0x4f, 0x55, 0x65, 0x72, 0x67, 0xb4},
|
|
.timestamp = 1425511800, // 23:30 UTC March 4
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
.all_day = true,
|
|
} // don't care about the rest
|
|
};
|
|
|
|
// should show up before s_all_day_reminder even though its timestamp is after due to tz adjustment
|
|
static TimelineItem s_reminder_before_all_day_reminder = {
|
|
.header = {
|
|
.id = {0x6b, 0xf6, 0x21, 0x5b, 0xc9, 0x7f, 0x40, 0x9e,
|
|
0x8d, 0x31, 0x4f, 0x55, 0x65, 0x72, 0x67, 0xb4},
|
|
.timestamp = 1425531600, // 21:00 PST March 4
|
|
.duration = 0,
|
|
.type = TimelineItemTypeReminder,
|
|
.all_day = false,
|
|
}
|
|
};
|
|
|
|
void test_reminders__all_day(void) {
|
|
time_util_update_timezone(&s_tz);
|
|
cl_assert_equal_i(reminders_insert(&s_all_day_reminder), S_SUCCESS);
|
|
cl_assert_equal_i(reminders_insert(&s_reminder_before_all_day_reminder), S_SUCCESS);
|
|
|
|
// set time to 16:00 PST March 4
|
|
now = 1425513600;
|
|
reminders_init();
|
|
cl_assert_equal_i(stub_new_timer_timeout(get_reminder_timer_id()), 5 * 60 * 60 * 1000);
|
|
cl_assert(uuid_equal(&s_reminder_before_all_day_reminder.header.id,
|
|
(Uuid *)stub_new_timer_callback_data(get_reminder_timer_id())));
|
|
// set time to 21:00 PST March 4
|
|
now = 1425531600;
|
|
stub_pebble_tasks_set_current(PebbleTask_NewTimers);
|
|
cl_assert(stub_new_timer_fire(get_reminder_timer_id()));
|
|
stub_pebble_tasks_set_current(PebbleTask_KernelBackground);
|
|
fake_system_task_callbacks_invoke(1);
|
|
|
|
cl_assert_equal_i(stub_new_timer_timeout(get_reminder_timer_id()), (2 * 60 + 30) * 60 * 1000);
|
|
cl_assert(uuid_equal(&s_all_day_reminder.header.id,
|
|
(Uuid *)stub_new_timer_callback_data(get_reminder_timer_id())));
|
|
}
|
|
|
|
void test_reminders__stale_all_day(void) {
|
|
time_util_update_timezone(&s_tz);
|
|
// set time to 21:00 PST March 5, when s_all_day_reminder should be rejected for being stale
|
|
now = 1425618000;
|
|
cl_assert_equal_i(reminders_insert(&s_all_day_reminder), E_INVALID_OPERATION);
|
|
|
|
// set time to 21:00 PST March 4
|
|
now = 1425531600;
|
|
// if the timestamp of s_all_day_reminder isn't adjusted, it would be rejected for being stale
|
|
// since it "seems" to be timestamped at 15:30 PST, but it should be accepted
|
|
cl_assert_equal_i(reminders_insert(&s_all_day_reminder), S_SUCCESS);
|
|
}
|
|
|
|
void test_reminders__calculate_snooze_time(void) {
|
|
// Test half-time snooze
|
|
now = 0;
|
|
cl_assert_equal_i(50, reminders_calculate_snooze_time(&item2));
|
|
now = 50;
|
|
cl_assert_equal_i(25, reminders_calculate_snooze_time(&item2));
|
|
|
|
// Test constant snooze
|
|
now = 80;
|
|
cl_assert_equal_i(600, reminders_calculate_snooze_time(&item2));
|
|
now = 100 + 48 * 60 * 60;
|
|
cl_assert_equal_i(600, reminders_calculate_snooze_time(&item2));
|
|
|
|
// Test no snooze
|
|
now = 100 + 48 * 60 * 60 + 1;
|
|
cl_assert_equal_i(0, reminders_calculate_snooze_time(&item2));
|
|
}
|