Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson
2025-01-27 11:38:16 -08:00
committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions
@@ -0,0 +1,98 @@
/*
* 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 "applib/ui/window_private.h"
#include "util/size.h"
#include "clar.h"
// Fakes
/////////////////////
#include "fake_animation.h"
#include "fake_app_state.h"
#include "fake_content_indicator.h"
#include "fake_evented_timer.h"
#include "fake_graphics_context.h"
#include "fake_rtc.h"
#include "fake_spi_flash.h"
#include "fixtures/load_test_resources.h"
// Stubs
/////////////////////
#include "stubs_action_menu.h"
#include "stubs_activity.h"
#include "stubs_analytics.h"
#include "stubs_ancs.h"
#include "stubs_animation_timing.h"
#include "stubs_animation_timing.h"
#include "stubs_app.h"
#include "stubs_app_cache.h"
#include "stubs_app_install_manager.h"
#include "stubs_app_launch_reason.h"
#include "stubs_app_manager.h"
#include "stubs_app_timer.h"
#include "stubs_app_window_stack.h"
#include "stubs_blob_db.h"
#include "stubs_blob_db_sync.h"
#include "stubs_blob_db_sync_util.h"
#include "stubs_bootbits.h"
#include "stubs_click.h"
#include "stubs_compositor_transitions.h"
#include "stubs_event_loop.h"
#include "stubs_event_service_client.h"
#include "stubs_events.h"
#include "stubs_i18n.h"
#include "stubs_layer.h"
#include "stubs_logging.h"
#include "stubs_memory_layout.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_process_info.h"
#include "stubs_pebble_tasks.h"
#include "stubs_phone_call_util.h"
#include "stubs_process_manager.h"
#include "stubs_prompt.h"
#include "stubs_property_animation.h"
#include "stubs_regular_timer.h"
#include "stubs_reminder_db.h"
#include "stubs_serial.h"
#include "stubs_session.h"
#include "stubs_shell_prefs.h"
#include "stubs_sleep.h"
#include "stubs_syscalls.h"
#include "stubs_system_theme.h"
#include "stubs_task_watchdog.h"
#include "stubs_timeline.h"
#include "stubs_timeline_actions.h"
#include "stubs_timeline_layout.h"
#include "stubs_timeline_layout_animations.h"
#include "stubs_timeline_peek.h"
#include "stubs_timezone_database.h"
#include "stubs_wakeup.h"
#include "stubs_watchface.h"
#include "stubs_window_manager.h"
#include "stubs_window_stack.h"
// Helper Functions
/////////////////////
#include "fw/graphics/util.h"
@@ -0,0 +1,271 @@
/*
* 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 "apps/system_apps/timeline/timeline.h"
#include "resource/resource.h"
#include "resource/resource_ids.auto.h"
#include "services/normal/timeline/timeline_resources.h"
#include "test_timeline_app_includes.h"
// Setup and Teardown
////////////////////////////////////
typedef struct TimelineTestData {
TimelineModel model;
} TimelineTestData;
TimelineTestData s_data;
void test_timeline_list_view__initialize(void) {
fake_app_state_init();
load_system_resources_fixture();
s_data = (TimelineTestData) {};
rtc_set_time(3 * SECONDS_PER_DAY);
}
void test_timeline_list_view__cleanup(void) {
}
// Helpers
//////////////////////
typedef struct TimelineItemConfig {
time_t relative_timestamp;
uint16_t duration;
const char *title;
const char *subtitle;
TimelineResourceId icon;
} TimelineItemConfig;
typedef struct ListViewConfig {
TimelineItemConfig *pins[2];
bool past;
bool day_separator;
} ListViewConfig;
static void prv_add_timeline_item(const TimelineItemConfig *config, bool past) {
PBL_ASSERTN(config);
TimelineItem *item = NULL;
const time_t now = rtc_get_time();
const time_t timestamp = now + ((past ? -1 : 1) * config->relative_timestamp);
if (config) {
AttributeList list;
attribute_list_init_list(0 /* num_attributes */, &list);
attribute_list_add_cstring(&list, AttributeIdTitle, config->title);
if (config->subtitle) {
attribute_list_add_cstring(&list, AttributeIdSubtitle, config->subtitle);
}
attribute_list_add_uint32(&list, AttributeIdIconPin, config->icon);
item = timeline_item_create_with_attributes(timestamp, config->duration,
TimelineItemTypePin, LayoutIdGeneric,
&list, NULL);
attribute_list_destroy_list(&list);
PBL_ASSERTN(item);
}
if (item) {
pin_db_insert_item(item);
timeline_item_destroy(item);
}
}
static void prv_create_list_view_and_render(ListViewConfig *config) {
pin_db_init();
for (int i = 0; i < (int)ARRAY_LENGTH(config->pins); i++) {
if (config->pins[i]) {
prv_add_timeline_item(config->pins[i], config->past);
}
}
s_data.model = (TimelineModel) {};
s_data.model.direction = config->past ? TimelineIterDirectionPast : TimelineIterDirectionFuture;
timeline_model_init(rtc_get_time(), &s_data.model);
Window window;
window_init(&window, "Timeline");
TimelineLayer timeline_layer = {};
const TimelineScrollDirection scroll_direction =
config->past ? TimelineScrollDirectionUp : TimelineScrollDirectionDown;
timeline_layer_init(&timeline_layer, &window.layer.frame, scroll_direction);
const GColor color = config->past ? TIMELINE_PAST_COLOR : TIMELINE_FUTURE_COLOR;
timeline_layer_set_sidebar_color(&timeline_layer, color);
timeline_layer_set_sidebar_width(&timeline_layer, timeline_layer_get_ideal_sidebar_width());
layer_add_child(&window.layer, &timeline_layer.layer);
timeline_layer_reset(&timeline_layer);
if (config->day_separator) {
// Simulate showing the day separator
int new_idx;
bool has_new;
cl_assert(timeline_model_iter_next(&new_idx, &has_new));
if (has_new) {
timeline_layer_set_next_item(&timeline_layer, new_idx);
}
timeline_layer_move_data(&timeline_layer, 1);
cl_assert(timeline_layer_should_animate_day_separator(&timeline_layer));
fake_animation_complete(timeline_layer_create_day_sep_show(&timeline_layer));
fake_animation_complete(timeline_layer.day_separator.kino_layer.player.animation);
timeline_layer_set_layouts_hidden(&timeline_layer, true);
}
window_set_on_screen(&window, true, true);
window_render(&window, fake_graphics_context_get_context());
timeline_layer_deinit(&timeline_layer);
timeline_model_deinit();
pin_db_flush();
}
// Tests
//////////////////////
static void prv_create_and_render_title_and_subtitle(bool past, uint16_t first_duration_m) {
prv_create_list_view_and_render(&(ListViewConfig) {
.pins = {
&(TimelineItemConfig) {
.relative_timestamp = (11 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE),
.duration = first_duration_m,
.title = "Jon Byrd birthday party",
.subtitle = "Kaboom, Redwood City",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}, &(TimelineItemConfig) {
.relative_timestamp = 12 * SECONDS_PER_HOUR,
.duration = MINUTES_PER_HOUR,
.title = "Design Review Meeting",
.subtitle = "Batavia, Palo Alto",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}
},
.past = past,
});
}
void test_timeline_list_view__title_and_subtitle_overlap_future(void) {
#if !PLATFORM_SPALDING
prv_create_and_render_title_and_subtitle(false /* past */, MINUTES_PER_HOUR);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
#endif
}
void test_timeline_list_view__title_and_subtitle_back_to_back_future(void) {
#if !PLATFORM_SPALDING
prv_create_and_render_title_and_subtitle(false /* past */, MINUTES_PER_HOUR / 2);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
#endif
}
void test_timeline_list_view__title_and_subtitle_free_time_future(void) {
prv_create_and_render_title_and_subtitle(false /* past */, 5 /* first_duration_m */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_timeline_list_view__title_and_subtitle_free_time_past(void) {
prv_create_and_render_title_and_subtitle(true /* past */, 5 /* first_duration_m */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP(TEST_PBI_FILE);
}
void prv_create_and_render_pin_and_dot(bool past) {
prv_create_list_view_and_render(&(ListViewConfig) {
.pins = {
&(TimelineItemConfig) {
.relative_timestamp = (11 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE),
.duration = MINUTES_PER_HOUR,
.title = "Jon Byrd birthday party",
.subtitle = "Kaboom, Redwood City",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}, &(TimelineItemConfig) {
.relative_timestamp = SECONDS_PER_DAY + SECONDS_PER_HOUR,
.duration = MINUTES_PER_HOUR,
.title = "Design Review Meeting",
.subtitle = "Batavia, Palo Alto",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}
},
.past = past,
});
}
void test_timeline_list_view__pin_and_dot_future(void) {
prv_create_and_render_pin_and_dot(false /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_timeline_list_view__pin_and_dot_past(void) {
prv_create_and_render_pin_and_dot(true /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void prv_create_and_render_day_sep_tomorrow(bool past) {
prv_create_list_view_and_render(&(ListViewConfig) {
.pins = {
&(TimelineItemConfig) {
.relative_timestamp = (11 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE),
.duration = MINUTES_PER_HOUR,
.title = "Jon Byrd birthday party",
.subtitle = "Kaboom, Redwood City",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}, &(TimelineItemConfig) {
.relative_timestamp = ((11 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE) +
SECONDS_PER_DAY),
.duration = MINUTES_PER_HOUR,
.title = "Design Review Meeting",
.subtitle = "Batavia, Palo Alto",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}
},
.past = past,
.day_separator = true,
});
}
void test_timeline_list_view__day_sep_tomorrow_future(void) {
prv_create_and_render_day_sep_tomorrow(false /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_timeline_list_view__day_sep_tomorrow_past(void) {
prv_create_and_render_day_sep_tomorrow(true /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void prv_create_and_render_pin_and_fin(bool past) {
prv_create_list_view_and_render(&(ListViewConfig) {
.pins = {
&(TimelineItemConfig) {
.relative_timestamp = (11 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE),
.title = "Jon Byrd birthday party",
.duration = MINUTES_PER_HOUR,
.subtitle = "Kaboom, Redwood City",
.icon = TIMELINE_RESOURCE_TIMELINE_CALENDAR,
}
},
.past = past,
});
}
void test_timeline_list_view__pin_and_fin_future(void) {
prv_create_and_render_pin_and_fin(false /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_timeline_list_view__pin_and_fin_past(void) {
prv_create_and_render_pin_and_fin(true /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
@@ -0,0 +1,77 @@
/*
* 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 "apps/system_apps/timeline/timeline.h"
#include "resource/resource.h"
#include "resource/resource_ids.auto.h"
#include "services/normal/timeline/timeline_resources.h"
#include "test_timeline_app_includes.h"
// Setup and Teardown
////////////////////////////////////
typedef struct TimelineTestData {
TimelineAppData app;
} TimelineTestData;
TimelineTestData s_data;
void test_timeline_no_events__initialize(void) {
fake_app_state_init();
load_system_resources_fixture();
s_data = (TimelineTestData) {};
}
void test_timeline_no_events__cleanup(void) {
}
// Helpers
//////////////////////
void prv_init_peek_layer(TimelineAppData *data);
void prv_setup_no_events_peek(TimelineAppData *data);
static void prv_create_no_events_and_render(bool past) {
Window *window = &s_data.app.timeline_window;
window_init(window, "Timeline");
const GColor color = past ? TIMELINE_PAST_COLOR : TIMELINE_FUTURE_COLOR;
window_set_background_color(window, color);
prv_init_peek_layer(&s_data.app);
prv_setup_no_events_peek(&s_data.app);
peek_layer_play(&s_data.app.peek_layer);
fake_animation_complete(s_data.app.peek_layer.kino_layer.player.animation);
fake_evented_timer_trigger(s_data.app.peek_layer.hidden_fields_timer);
window_set_on_screen(window, true, true);
window_render(window, fake_graphics_context_get_context());
}
// Tests
//////////////////////
void test_timeline_no_events__future(void) {
prv_create_no_events_and_render(false /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_timeline_no_events__past(void) {
prv_create_no_events_and_render(true /* past */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
+148
View File
@@ -0,0 +1,148 @@
from waftools.pebble_test import clar
def build(ctx):
rendering_sources = (
"src/fw/applib/fonts/codepoint.c "
"src/fw/applib/graphics/${BITDEPTH}_bit/bitblt_private.c "
"src/fw/applib/graphics/${BITDEPTH}_bit/framebuffer.c "
"src/fw/applib/graphics/bitblt.c "
"src/fw/applib/graphics/framebuffer.c "
"src/fw/applib/graphics/gbitmap.c "
"src/fw/applib/graphics/gbitmap_png.c "
"src/fw/applib/graphics/gbitmap_sequence.c "
"src/fw/applib/graphics/gcolor_definitions.c "
"src/fw/applib/graphics/gdraw_command.c "
"src/fw/applib/graphics/gdraw_command_frame.c "
"src/fw/applib/graphics/gdraw_command_image.c "
"src/fw/applib/graphics/gdraw_command_list.c "
"src/fw/applib/graphics/gdraw_command_sequence.c "
"src/fw/applib/graphics/gpath.c "
"src/fw/applib/graphics/graphics.c "
"src/fw/applib/graphics/graphics_bitmap.c "
"src/fw/applib/graphics/graphics_circle.c "
"src/fw/applib/graphics/graphics_line.c "
"src/fw/applib/graphics/graphics_private.c "
"src/fw/applib/graphics/graphics_private_raw.c "
"src/fw/applib/graphics/gtransform.c "
"src/fw/applib/graphics/gtypes.c "
"src/fw/applib/graphics/perimeter.c "
"src/fw/applib/graphics/text_layout.c "
"src/fw/applib/graphics/text_render.c "
"src/fw/applib/graphics/text_resources.c "
"src/fw/applib/graphics/utf8.c "
"src/fw/applib/ui/kino/kino_reel.c "
"src/fw/applib/ui/kino/kino_reel_gbitmap.c "
"src/fw/applib/ui/kino/kino_reel_gbitmap_sequence.c "
"src/fw/applib/ui/kino/kino_reel_pdci.c "
"src/fw/applib/ui/kino/kino_reel_pdcs.c "
"src/fw/applib/ui/layer.c "
"src/fw/applib/ui/menu_layer_system_cells.c "
"src/fw/applib/vendor/tinflate/tinflate.c "
"src/fw/applib/vendor/uPNG/upng.c "
"src/fw/board/displays/display_spalding.c "
"src/fw/drivers/flash/flash_crc.c "
"src/fw/flash_region/filesystem_regions.c "
"src/fw/flash_region/flash_region.c "
"src/fw/resource/resource.c "
"src/fw/resource/resource_storage.c "
"src/fw/resource/resource_storage_builtin.c "
"src/fw/resource/resource_storage_file.c "
"src/fw/resource/resource_storage_flash.c "
"src/fw/services/normal/filesystem/app_file.c "
"src/fw/services/normal/filesystem/flash_translation.c "
"src/fw/services/normal/filesystem/pfs.c "
"src/fw/system/hexdump.c "
"src/fw/util/crc8.c "
"src/fw/util/legacy_checksum.c "
"tests/fakes/fake_animation.c "
"tests/fakes/fake_applib_resource.c "
"tests/fakes/fake_display.c "
"tests/fakes/fake_gbitmap_get_data_row.c "
"tests/fakes/fake_graphics_context.c "
"tests/fakes/fake_property_animation.c "
"tests/fakes/fake_rtc.c "
"tests/fakes/fake_spi_flash.c "
"tests/fixtures/resources/builtin_resources.auto.c "
"tests/fixtures/resources/pfs_resource_table.c "
"tests/stubs/stubs_animation.c "
)
timeline_app_sources = (
"src/fw/applib/graphics/gdraw_command_transforms.c "
"src/fw/applib/graphics/gpath_builder.c "
"src/fw/applib/ui/action_button.c "
"src/fw/applib/ui/animation_interpolate.c "
"src/fw/applib/ui/content_indicator.c "
"src/fw/applib/ui/inverter_layer.c "
"src/fw/applib/ui/kino/kino_layer.c "
"src/fw/applib/ui/kino/kino_player.c "
"src/fw/applib/ui/kino/kino_reel/scale_segmented.c "
"src/fw/applib/ui/kino/kino_reel/transform.c "
"src/fw/applib/ui/kino/kino_reel/unfold.c "
"src/fw/applib/ui/kino/kino_reel_custom.c "
"src/fw/applib/ui/menu_layer.c "
"src/fw/applib/ui/scroll_layer.c "
"src/fw/applib/ui/shadows.c "
"src/fw/applib/ui/status_bar_layer.c "
"src/fw/applib/ui/text_layer.c "
"src/fw/applib/ui/text_layer_flow.c "
"src/fw/applib/ui/window.c "
"src/fw/apps/system_apps/timeline/peek_layer.c "
"src/fw/apps/system_apps/timeline/pin_window.c "
"src/fw/apps/system_apps/timeline/text_node.c "
"src/fw/apps/system_apps/timeline/timeline.c "
"src/fw/apps/system_apps/timeline/timeline_animations.c "
"src/fw/apps/system_apps/timeline/timeline_layer.c "
"src/fw/apps/system_apps/timeline/timeline_model.c "
"src/fw/apps/system_apps/timeline/timeline_relbar.c "
"src/fw/popups/timeline/timeline_item_layer.c "
"src/fw/services/common/clock.c "
"src/fw/services/normal/blob_db/pin_db.c "
"src/fw/services/normal/blob_db/timeline_item_storage.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/generic_layout.c "
"src/fw/services/normal/timeline/item.c "
"src/fw/services/normal/timeline/layout_layer.c "
"src/fw/services/normal/timeline/layout_node.c "
"src/fw/services/normal/timeline/timeline.c "
"src/fw/services/normal/timeline/timeline_layout.c "
"src/fw/services/normal/timeline/timeline_resources.c "
"src/fw/shell/system_theme.c "
"src/fw/util/buffer.c "
"src/fw/util/stats.c "
"src/fw/util/stringlist.c "
"src/fw/util/time/mktime.c "
"src/fw/util/time/time.c "
"tests/fakes/fake_fonts.c "
"tests/fakes/fake_settings_file.c "
"tests/fixtures/resources/timeline_resource_table.auto.c "
"tests/stubs/stubs_evented_timer.c "
)
clar(ctx,
sources_ant_glob=(
rendering_sources +
timeline_app_sources
),
test_sources_ant_glob="test_timeline_list_view.c",
defines=ctx.env.test_image_defines + ["USE_DISPLAY_PERIMETER_ON_FONT_LAYOUT=1"],
runtime_deps=ctx.env.test_pngs + ctx.env.test_pbis + ctx.env.test_pfos,
override_includes=['dummy_board'],
platforms=['snowy', 'spalding', 'silk', 'robert'])
clar(ctx,
sources_ant_glob=(
rendering_sources +
timeline_app_sources
),
test_sources_ant_glob="test_timeline_no_events.c",
defines=ctx.env.test_image_defines + ["USE_DISPLAY_PERIMETER_ON_FONT_LAYOUT=1"],
runtime_deps=ctx.env.test_pngs + ctx.env.test_pbis + ctx.env.test_pfos,
override_includes=['dummy_board'],
# The no events is a builtin on silk and thus cannot be used in a unit test currently
platforms=['snowy', 'spalding', 'robert'])
# vim:filetype=python