mirror of
https://github.com/google/pebble.git
synced 2025-06-07 10:43:12 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
279
src/fw/shell/sdk/prefs.c
Normal file
279
src/fw/shell/sdk/prefs.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* 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/preferred_content_size.h"
|
||||
#include "apps/system_app_ids.h"
|
||||
#include "board/board.h"
|
||||
#include "os/mutex.h"
|
||||
#include "process_management/app_install_manager.h"
|
||||
#include "process_management/process_manager.h"
|
||||
#include "services/normal/activity/activity.h"
|
||||
#include "services/normal/activity/activity_insights.h"
|
||||
#include "services/normal/activity/insights_settings.h"
|
||||
#include "services/normal/settings/settings_file.h"
|
||||
#include "shell/prefs.h"
|
||||
#include "shell/prefs_private.h"
|
||||
|
||||
static PebbleMutex *s_mutex;
|
||||
|
||||
#define PREF_KEY_CLOCK_24H "clock24h"
|
||||
static bool s_is_24h_style;
|
||||
|
||||
#define PREF_KEY_DEFAULT_WATCHFACE "watchface"
|
||||
static Uuid s_default_watchface = UUID_INVALID_INIT;
|
||||
|
||||
#define PREF_KEY_CONTENT_SIZE "contentSize"
|
||||
static uint8_t s_content_size;
|
||||
#if !UNITTEST
|
||||
_Static_assert(sizeof(PreferredContentSize) == sizeof(s_content_size),
|
||||
"sizeof(PreferredContentSize) grew, pref needs to be migrated!");
|
||||
#endif
|
||||
|
||||
void shell_prefs_init(void) {
|
||||
s_mutex = mutex_create();
|
||||
mutex_lock(s_mutex);
|
||||
SettingsFile file = {};
|
||||
if (settings_file_open(&file, SHELL_PREFS_FILE_NAME, SHELL_PREFS_FILE_LEN) != S_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (settings_file_get(&file, PREF_KEY_CLOCK_24H, sizeof(PREF_KEY_CLOCK_24H),
|
||||
&s_is_24h_style, sizeof(s_is_24h_style)) != S_SUCCESS) {
|
||||
// The setting likely doesn't exist yet so set it to the default (true)
|
||||
s_is_24h_style = true;
|
||||
}
|
||||
if (settings_file_get(&file, PREF_KEY_DEFAULT_WATCHFACE, sizeof(PREF_KEY_DEFAULT_WATCHFACE),
|
||||
&s_default_watchface, sizeof(s_default_watchface)) != S_SUCCESS) {
|
||||
s_default_watchface = UUID_INVALID;
|
||||
}
|
||||
if (settings_file_get(&file, PREF_KEY_CONTENT_SIZE, sizeof(PREF_KEY_CONTENT_SIZE),
|
||||
&s_content_size, sizeof(s_content_size)) != S_SUCCESS) {
|
||||
s_content_size = PreferredContentSizeDefault;
|
||||
}
|
||||
settings_file_close(&file);
|
||||
cleanup:
|
||||
mutex_unlock(s_mutex);
|
||||
}
|
||||
|
||||
static bool prv_pref_set(const char *key, const void *val, size_t val_len) {
|
||||
SettingsFile file = {};
|
||||
status_t rv;
|
||||
if ((rv = settings_file_open(&file, SHELL_PREFS_FILE_NAME, SHELL_PREFS_FILE_LEN)) != S_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
rv = settings_file_set(&file, key, strnlen(key, SETTINGS_KEY_MAX_LEN) + 1, val, val_len);
|
||||
settings_file_close(&file);
|
||||
cleanup:
|
||||
return (rv == S_SUCCESS);
|
||||
}
|
||||
|
||||
bool shell_prefs_get_clock_24h_style(void) {
|
||||
return s_is_24h_style;
|
||||
}
|
||||
|
||||
void shell_prefs_set_clock_24h_style(bool is_24h_style) {
|
||||
mutex_lock(s_mutex);
|
||||
if (prv_pref_set(PREF_KEY_CLOCK_24H, &s_is_24h_style, sizeof(s_is_24h_style))) {
|
||||
s_is_24h_style = is_24h_style;
|
||||
}
|
||||
mutex_unlock(s_mutex);
|
||||
}
|
||||
|
||||
bool shell_prefs_is_timezone_source_manual(void) {
|
||||
// Force things to automatic
|
||||
return false;
|
||||
}
|
||||
|
||||
void shell_prefs_set_timezone_source_manual(bool manual) {
|
||||
}
|
||||
|
||||
int16_t shell_prefs_get_automatic_timezone_id(void) {
|
||||
// Invalid
|
||||
return -1;
|
||||
}
|
||||
|
||||
void shell_prefs_set_automatic_timezone_id(int16_t timezone_id) {
|
||||
}
|
||||
|
||||
|
||||
// Exported function used by blob_db API to set the backing store for a specific key.
|
||||
// Not used by the SDK shell
|
||||
bool prefs_private_write_backing(const uint8_t *key, size_t key_len, const void *value,
|
||||
int value_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Exported function used by blob_db API to get the length of a value in our backing store
|
||||
// Not used by the SDK shell
|
||||
int prefs_private_get_backing_len(const uint8_t *key, size_t key_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Exported function used by blob_db API to read our backing store
|
||||
// Not used by the SDK shell
|
||||
bool prefs_private_read_backing(const uint8_t *key, size_t key_len, void *value, int value_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
void watchface_set_default_install_id(AppInstallId app_id) {
|
||||
mutex_lock(s_mutex);
|
||||
Uuid uuid;
|
||||
app_install_get_uuid_for_install_id(app_id, &uuid);
|
||||
if (prv_pref_set(PREF_KEY_DEFAULT_WATCHFACE, &uuid, sizeof(uuid))) {
|
||||
s_default_watchface = uuid;
|
||||
}
|
||||
mutex_unlock(s_mutex);
|
||||
}
|
||||
|
||||
static bool prv_set_default_any_watchface_enumerate_callback(AppInstallEntry *entry, void *data) {
|
||||
if (!app_install_entry_is_watchface(entry) ||
|
||||
app_install_entry_is_hidden(entry)) {
|
||||
return true; // continue search
|
||||
}
|
||||
|
||||
watchface_set_default_install_id(entry->install_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
AppInstallId watchface_get_default_install_id(void) {
|
||||
AppInstallId app_id = app_install_get_id_for_uuid(&s_default_watchface);
|
||||
AppInstallEntry entry;
|
||||
if ((app_id == INSTALL_ID_INVALID) ||
|
||||
!app_install_get_entry_for_install_id(app_id, &entry) ||
|
||||
!app_install_entry_is_watchface(&entry)) {
|
||||
app_install_enumerate_entries(prv_set_default_any_watchface_enumerate_callback, NULL);
|
||||
app_id = app_install_get_id_for_uuid(&s_default_watchface);
|
||||
}
|
||||
return app_id;
|
||||
}
|
||||
#else
|
||||
AppInstallId watchface_get_default_install_id(void) {
|
||||
return APP_ID_SDK;
|
||||
}
|
||||
|
||||
void watchface_set_default_install_id(AppInstallId id) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void system_theme_set_content_size(PreferredContentSize content_size) {
|
||||
mutex_lock(s_mutex);
|
||||
const uint8_t content_size_uint = content_size;
|
||||
if (content_size >= NumPreferredContentSizes) {
|
||||
PBL_LOG(LOG_LEVEL_WARNING, "Ignoring attempt to set content size to invalid size %d",
|
||||
content_size);
|
||||
} else if (prv_pref_set(PREF_KEY_CONTENT_SIZE, &content_size_uint, sizeof(content_size_uint))) {
|
||||
s_content_size = content_size;
|
||||
}
|
||||
mutex_unlock(s_mutex);
|
||||
}
|
||||
|
||||
PreferredContentSize system_theme_get_content_size(void) {
|
||||
return system_theme_convert_host_content_size_to_runtime_platform(
|
||||
(PreferredContentSize)s_content_size);
|
||||
}
|
||||
|
||||
bool activity_prefs_tracking_is_enabled(void) {
|
||||
#if CAPABILITY_HAS_HEALTH_TRACKING
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_HEALTH_TRACKING
|
||||
void activity_prefs_tracking_set_enabled(bool enable) {
|
||||
}
|
||||
|
||||
bool activity_prefs_activity_insights_are_enabled(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void activity_prefs_activity_insights_set_enabled(bool enable) {
|
||||
}
|
||||
|
||||
bool activity_prefs_sleep_insights_are_enabled(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void activity_prefs_sleep_insights_set_enabled(bool enable) {
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_get_health_app_opened_version(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activity_prefs_set_height_mm(uint16_t height_mm) {
|
||||
}
|
||||
|
||||
uint16_t activity_prefs_get_height_mm(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activity_prefs_set_weight_dag(uint16_t weight_dag) {
|
||||
}
|
||||
|
||||
uint16_t activity_prefs_get_weight_dag(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activity_prefs_set_gender(ActivityGender gender) {
|
||||
}
|
||||
|
||||
ActivityGender activity_prefs_get_gender(void) {
|
||||
return ActivityGenderOther;
|
||||
}
|
||||
|
||||
void activity_prefs_set_age_years(uint8_t age_years) {
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_get_age_years(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool activity_prefs_heart_rate_is_enabled(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ActivityInsightSettings *activity_prefs_get_sleep_reward_settings(void) {
|
||||
static ActivityInsightSettings s_settings = { 0 };
|
||||
return &s_settings;
|
||||
}
|
||||
|
||||
void activity_prefs_set_activation_delay_insight_fired(ActivationDelayInsightType type) {
|
||||
}
|
||||
|
||||
bool activity_prefs_has_activation_delay_insight_fired(ActivationDelayInsightType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool activity_prefs_get_health_app_opened(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void activity_prefs_set_activated(void) {
|
||||
}
|
||||
|
||||
time_t activity_prefs_get_activation_time(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UnitsDistance shell_prefs_get_units_distance(void) {
|
||||
return UnitsDistance_Miles;
|
||||
}
|
||||
|
||||
#endif
|
30
src/fw/shell/sdk/shell.c
Normal file
30
src/fw/shell/sdk/shell.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "shell/shell.h"
|
||||
|
||||
#include "kernel/events.h"
|
||||
#include "process_management/app_install_types.h"
|
||||
|
||||
const CompositorTransition* shell_get_close_compositor_animation(AppInstallId current_app_id,
|
||||
AppInstallId next_app_id) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CompositorTransition* shell_get_open_compositor_animation(AppInstallId current_app_id,
|
||||
AppInstallId next_app_id) {
|
||||
return NULL;
|
||||
}
|
68
src/fw/shell/sdk/shell_event_loop.c
Normal file
68
src/fw/shell/sdk/shell_event_loop.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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_app_ids.h"
|
||||
#include "apps/system_apps/timeline/timeline.h"
|
||||
#include "kernel/events.h"
|
||||
#include "kernel/pbl_malloc.h"
|
||||
#include "popups/notifications/notification_window.h"
|
||||
#include "popups/timeline/peek.h"
|
||||
#include "process_management/app_manager.h"
|
||||
#include "services/common/compositor/compositor.h"
|
||||
#include "services/normal/activity/activity.h"
|
||||
#include "services/normal/app_inbox_service.h"
|
||||
#include "services/normal/app_outbox_service.h"
|
||||
#include "shell/prefs.h"
|
||||
#include "shell/sdk/watchface.h"
|
||||
#include "shell/shell_event_loop.h"
|
||||
|
||||
extern void shell_prefs_init(void);
|
||||
|
||||
void shell_event_loop_init(void) {
|
||||
shell_prefs_init();
|
||||
notification_window_service_init();
|
||||
app_inbox_service_init();
|
||||
app_outbox_service_init();
|
||||
app_message_sender_init();
|
||||
watchface_init();
|
||||
timeline_peek_init();
|
||||
#if CAPABILITY_HAS_HEALTH_TRACKING
|
||||
// Start activity tracking if enabled
|
||||
if (activity_prefs_tracking_is_enabled()) {
|
||||
activity_start_tracking(false /*test_mode*/);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void shell_event_loop_handle_event(PebbleEvent *e) {
|
||||
switch (e->type) {
|
||||
case PEBBLE_APP_FETCH_REQUEST_EVENT:
|
||||
app_manager_handle_app_fetch_request_event(&e->app_fetch_request);
|
||||
return;
|
||||
|
||||
case PEBBLE_SYS_NOTIFICATION_EVENT:
|
||||
notification_window_handle_notification(&e->sys_notification);
|
||||
return;
|
||||
|
||||
case PEBBLE_REMINDER_EVENT:
|
||||
// This handles incoming Reminders
|
||||
notification_window_handle_reminder(&e->reminder);
|
||||
return;
|
||||
|
||||
default:
|
||||
break; // don't care
|
||||
}
|
||||
}
|
33
src/fw/shell/sdk/shell_sdk.c
Normal file
33
src/fw/shell/sdk/shell_sdk.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 "shell_sdk.h"
|
||||
|
||||
#include "process_management/app_install_manager.h"
|
||||
|
||||
AppInstallId s_last_installed_app = INSTALL_ID_INVALID;
|
||||
|
||||
AppInstallId shell_sdk_get_last_installed_app(void) {
|
||||
return s_last_installed_app;
|
||||
}
|
||||
|
||||
void shell_sdk_set_last_installed_app(AppInstallId app_id) {
|
||||
s_last_installed_app = app_id;
|
||||
}
|
||||
|
||||
bool shell_sdk_last_installed_app_is_watchface() {
|
||||
return app_install_is_watchface(shell_sdk_get_last_installed_app());
|
||||
}
|
28
src/fw/shell/sdk/shell_sdk.h
Normal file
28
src/fw/shell/sdk/shell_sdk.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 "process_management/app_install_types.h"
|
||||
|
||||
//! @file shell_sdk.h
|
||||
//!
|
||||
//! Hooks into system_app_state_machine.c to watch for installed apps to be launched. Latches
|
||||
//! so we can figure out what was the installed app that we've launched most recently.
|
||||
|
||||
AppInstallId shell_sdk_get_last_installed_app(void);
|
||||
|
||||
void shell_sdk_set_last_installed_app(AppInstallId app_id);
|
||||
|
||||
bool shell_sdk_last_installed_app_is_watchface();
|
163
src/fw/shell/sdk/stubs.c
Normal file
163
src/fw/shell/sdk/stubs.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 "drivers/backlight.h"
|
||||
#include "process_management/pebble_process_md.h"
|
||||
#include "services/normal/activity/activity.h"
|
||||
#include "services/normal/timeline/peek.h"
|
||||
#include "shell/prefs.h"
|
||||
#include "util/uuid.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void app_idle_timeout_start(void) {
|
||||
}
|
||||
|
||||
void app_idle_timeout_refresh(void) {
|
||||
}
|
||||
|
||||
void app_idle_timeout_stop(void) {
|
||||
}
|
||||
|
||||
void watchface_start_low_power(bool enable) {
|
||||
}
|
||||
|
||||
uint32_t backlight_get_timeout_ms(void) {
|
||||
return DEFAULT_BACKLIGHT_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
#define SDKSHELL_BACKLIGHT_ON_PERCENT 25 // Same as snowy bb2
|
||||
|
||||
uint16_t backlight_get_intensity(void) {
|
||||
return (BACKLIGHT_BRIGHTNESS_MAX * SDKSHELL_BACKLIGHT_ON_PERCENT / 100);
|
||||
}
|
||||
uint8_t backlight_get_intensity_percent(void) {
|
||||
return (backlight_get_intensity() * 100) / BACKLIGHT_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
void backlight_set_timeout_ms(uint32_t timeout_ms) {
|
||||
}
|
||||
|
||||
BacklightBehaviour backlight_get_behaviour(void) {
|
||||
return BacklightBehaviour_On;
|
||||
}
|
||||
|
||||
bool backlight_is_enabled(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool backlight_is_ambient_sensor_enabled(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool backlight_is_motion_enabled(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "process_management/app_install_types.h"
|
||||
void worker_preferences_set_default_worker(AppInstallId id) {
|
||||
}
|
||||
|
||||
AppInstallId worker_preferences_get_default_worker(void) {
|
||||
return INSTALL_ID_INVALID;
|
||||
}
|
||||
|
||||
#if !CAPABILITY_HAS_SDK_SHELL4
|
||||
const char *app_custom_get_title(AppInstallId id) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void customizable_app_protocol_msg_callback(void *session, const uint8_t* data,
|
||||
size_t length) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Used by the alarm service to add alarm pins to the timeline
|
||||
const PebbleProcessMd* alarms_app_get_info(void) {
|
||||
static const PebbleProcessMdSystem s_alarms_app_info = {
|
||||
.common = {
|
||||
.main_func = NULL,
|
||||
// UUID: 67a32d95-ef69-46d4-a0b9-854cc62f97f9
|
||||
.uuid = {0x67, 0xa3, 0x2d, 0x95, 0xef, 0x69, 0x46, 0xd4,
|
||||
0xa0, 0xb9, 0x85, 0x4c, 0xc6, 0x2f, 0x97, 0xf9},
|
||||
},
|
||||
.name = "Alarms",
|
||||
};
|
||||
return (const PebbleProcessMd*) &s_alarms_app_info;
|
||||
}
|
||||
|
||||
// This stub isn't needed on tintin as it uses a different launcher
|
||||
#if !PLATFORM_TINTIN && !CAPABILITY_HAS_SDK_SHELL4
|
||||
#include "apps/system_apps/launcher/launcher_app.h"
|
||||
const LauncherDrawState *launcher_app_get_draw_state(void) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void analytics_external_update(void) {
|
||||
}
|
||||
|
||||
bool shell_prefs_get_stationary_enabled(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shell_prefs_get_language_english(void) {
|
||||
return true;
|
||||
}
|
||||
void shell_prefs_set_language_english(bool english) {
|
||||
}
|
||||
void shell_prefs_toggle_language_english(void) {
|
||||
}
|
||||
|
||||
void language_ui_display_changed(const char *lang_name) {
|
||||
}
|
||||
|
||||
void timeline_peek_prefs_set_enabled(bool enabled) {}
|
||||
bool timeline_peek_prefs_get_enabled(void) {
|
||||
return true;
|
||||
}
|
||||
void timeline_peek_prefs_set_before_time(uint16_t before_time_m) {}
|
||||
uint16_t timeline_peek_prefs_get_before_time(void) {
|
||||
return (TIMELINE_PEEK_DEFAULT_SHOW_BEFORE_TIME_S / SECONDS_PER_MINUTE);
|
||||
}
|
||||
|
||||
bool workout_utils_find_ongoing_activity_session(ActivitySession *session_out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_resting_hr(void) {
|
||||
return 70;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_elevated_hr(void) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_max_hr(void) {
|
||||
return 190;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_zone1_threshold(void) {
|
||||
return 130;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_zone2_threshold(void) {
|
||||
return 154;
|
||||
}
|
||||
|
||||
uint8_t activity_prefs_heart_get_zone3_threshold(void) {
|
||||
return 172;
|
||||
}
|
51
src/fw/shell/sdk/system_app_registry_list.json
Normal file
51
src/fw/shell/sdk/system_app_registry_list.json
Normal file
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"warning_one": [
|
||||
" 1. DO NOT CHANGE OR REUSE THE ID OF ANY APPLICATION IN THE LIST ",
|
||||
" 2. Read the directions "
|
||||
],
|
||||
"directions": [
|
||||
" - The System Apps are the applications that are actually coded",
|
||||
" into the firmware with static PebbleProcessMd's. ",
|
||||
" - The Resource Apps are the applications that are stored in ",
|
||||
" the resource pack included with the firmware. ",
|
||||
" - The section 'system_apps' only lists the PebbleProcessMd* ",
|
||||
" functions ",
|
||||
" - Resource app entry requires a UUID, then bin_resource_id ",
|
||||
" then an icon_resource_id ",
|
||||
" - To enable only certain applications on a certain ",
|
||||
" add the particular DEFINE variable into the 'ifdefs' field ",
|
||||
" Doing so will add that application to the generated list ",
|
||||
" - To disable applications entirely, add a 'DISABLED' define to",
|
||||
" the list of defines for the application "
|
||||
],
|
||||
"warning_two": [
|
||||
" 1. DO NOT CHANGE OR REUSE THE ID OF ANY APPLICATION IN THE LIST ",
|
||||
" 2. Read the directions "
|
||||
],
|
||||
"system_apps": [
|
||||
{
|
||||
"id": -1,
|
||||
"enum": "SDK",
|
||||
"md_fn": "sdk_app_get_info"
|
||||
},
|
||||
{
|
||||
"id": -2,
|
||||
"enum": "TIMELINE",
|
||||
"md_fn": "timeline_get_app_info"
|
||||
},
|
||||
{
|
||||
"id": -3,
|
||||
"enum": "LAUNCHER_MENU",
|
||||
"md_fn": "launcher_menu_app_get_app_info",
|
||||
"ifdefs": ["CAPABILITY_HAS_SDK_SHELL4=1"]
|
||||
},
|
||||
{
|
||||
"id": -4,
|
||||
"enum": "WATCHFACES",
|
||||
"md_fn": "watchfaces_get_app_info",
|
||||
"ifdefs": ["CAPABILITY_HAS_SDK_SHELL4=1"],
|
||||
"color_argb8": "GColorJazzberryJamARGB8"
|
||||
}
|
||||
],
|
||||
"resource_apps": []
|
||||
}
|
99
src/fw/shell/sdk/system_app_state_machine.c
Normal file
99
src/fw/shell/sdk/system_app_state_machine.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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 "shell_sdk.h"
|
||||
|
||||
#include "apps/core_apps/panic_window_app.h"
|
||||
#include "apps/sdk/sdk_app.h"
|
||||
#include "apps/system_app_ids.h"
|
||||
#include "apps/system_apps/launcher/launcher_app.h"
|
||||
#include "kernel/panic.h"
|
||||
#include "process_management/app_install_manager.h"
|
||||
#include "process_management/app_manager.h"
|
||||
#include "shell/system_app_state_machine.h"
|
||||
#include "shell/sdk/watchface.h"
|
||||
|
||||
//! Whether to return to the watchface instead of the launcher upon exiting an app.
|
||||
static bool s_rooted_in_watchface = false;
|
||||
|
||||
const PebbleProcessMd *system_app_state_machine_system_start(void) {
|
||||
if (launcher_panic_get_current_error() != 0) {
|
||||
return panic_app_get_app_info();
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
const AppInstallId watchface_app_id = watchface_get_default_install_id();
|
||||
if (watchface_app_id != INSTALL_ID_INVALID) {
|
||||
return app_install_get_md(watchface_app_id, false /* worker */);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sdk_app_get_info();
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
//! @return True if the currently running app is an installed watchface
|
||||
static bool prv_current_app_is_watchface(void) {
|
||||
return app_install_is_watchface(app_manager_get_current_app_id());
|
||||
}
|
||||
|
||||
AppInstallId system_app_state_machine_get_last_registered_app(void) {
|
||||
// If we're rooted in the watchface but we're not the watchface itself, or the launcher
|
||||
// is closing, we should launch the watchface.
|
||||
if ((s_rooted_in_watchface && !prv_current_app_is_watchface()) ||
|
||||
(app_manager_get_current_app_md() == launcher_menu_app_get_app_info())) {
|
||||
return watchface_get_default_install_id();
|
||||
}
|
||||
|
||||
return APP_ID_LAUNCHER_MENU;
|
||||
}
|
||||
|
||||
const PebbleProcessMd* system_app_state_machine_get_default_app(void) {
|
||||
return launcher_menu_app_get_app_info();
|
||||
}
|
||||
|
||||
#else
|
||||
AppInstallId system_app_state_machine_get_last_registered_app(void) {
|
||||
return APP_ID_SDK;
|
||||
}
|
||||
|
||||
const PebbleProcessMd* system_app_state_machine_get_default_app(void) {
|
||||
return sdk_app_get_info();
|
||||
}
|
||||
#endif
|
||||
|
||||
void system_app_state_machine_register_app_launch(AppInstallId app_id) {
|
||||
if (app_install_id_from_app_db(app_id)) {
|
||||
shell_sdk_set_last_installed_app(app_id);
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
if (app_id == APP_ID_LAUNCHER_MENU) {
|
||||
s_rooted_in_watchface = false;
|
||||
} else if (app_install_is_watchface(app_id)) {
|
||||
s_rooted_in_watchface = true;
|
||||
}
|
||||
// Other app launches don't modify our root so just ignore them.
|
||||
#endif
|
||||
}
|
||||
|
||||
void system_app_state_machine_panic(void) {
|
||||
if (app_manager_is_initialized()) {
|
||||
app_manager_launch_new_app(&(AppLaunchConfig) {
|
||||
.md = panic_app_get_app_info(),
|
||||
});
|
||||
}
|
||||
}
|
140
src/fw/shell/sdk/watchface.c
Normal file
140
src/fw/shell/sdk/watchface.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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 "watchface.h"
|
||||
|
||||
#include "applib/ui/dialogs/expandable_dialog.h"
|
||||
#include "apps/system_app_ids.h"
|
||||
#include "apps/system_apps/launcher/launcher_app.h"
|
||||
#include "apps/system_apps/timeline/timeline.h"
|
||||
#include "kernel/event_loop.h"
|
||||
#include "kernel/ui/modals/modal_manager.h"
|
||||
#include "popups/timeline/peek.h"
|
||||
#include "process_management/app_manager.h"
|
||||
#include "process_management/pebble_process_md.h"
|
||||
#include "services/common/analytics/analytics.h"
|
||||
#include "services/common/compositor/compositor_transitions.h"
|
||||
#include "shell/sdk/shell_sdk.h"
|
||||
#include "shell/system_app_state_machine.h"
|
||||
#include "system/logging.h"
|
||||
#include "system/passert.h"
|
||||
|
||||
typedef struct WatchfaceData {
|
||||
ClickManager click_manager;
|
||||
ButtonId button_pressed;
|
||||
AppInstallId active_watchface;
|
||||
} WatchfaceData;
|
||||
|
||||
static WatchfaceData s_watchface_data;
|
||||
|
||||
void watchface_launch_default(const CompositorTransition *animation) {
|
||||
app_manager_put_launch_app_event(&(AppLaunchEventConfig) {
|
||||
.id = watchface_get_default_install_id(),
|
||||
.common.transition = animation,
|
||||
});
|
||||
}
|
||||
|
||||
static void prv_launch_app_via_button(AppLaunchEventConfig *config,
|
||||
ClickRecognizerRef recognizer) {
|
||||
config->common.button = click_recognizer_get_button_id(recognizer);
|
||||
app_manager_put_launch_app_event(config);
|
||||
}
|
||||
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
static void prv_launch_launcher(ClickRecognizerRef recognizer, void *data) {
|
||||
static const LauncherMenuArgs s_launcher_args = { .reset_scroll = true };
|
||||
prv_launch_app_via_button(&(AppLaunchEventConfig) {
|
||||
.id = APP_ID_LAUNCHER_MENU,
|
||||
.common.args = &s_launcher_args,
|
||||
}, recognizer);
|
||||
}
|
||||
|
||||
static void prv_launch_timeline(ClickRecognizerRef recognizer, void *data) {
|
||||
static TimelineArgs s_timeline_args = {
|
||||
.pin_id = UUID_INVALID_INIT,
|
||||
};
|
||||
switch (click_recognizer_get_button_id(recognizer)) {
|
||||
case BUTTON_ID_DOWN:
|
||||
s_timeline_args.direction = TimelineIterDirectionFuture;
|
||||
break;
|
||||
case BUTTON_ID_UP:
|
||||
s_timeline_args.direction = TimelineIterDirectionPast;
|
||||
break;
|
||||
default:
|
||||
WTF;
|
||||
}
|
||||
|
||||
prv_launch_app_via_button(&(AppLaunchEventConfig) {
|
||||
.id = APP_ID_TIMELINE,
|
||||
.common.args = &s_timeline_args,
|
||||
}, recognizer);
|
||||
}
|
||||
|
||||
static void prv_configure_click(ButtonId button_id, ClickHandler click_handler) {
|
||||
WatchfaceData *data = &s_watchface_data;
|
||||
ClickConfig *cfg = &data->click_manager.recognizers[button_id].config;
|
||||
cfg->click.handler = click_handler;
|
||||
}
|
||||
|
||||
static void prv_watchface_configure_click_handlers(void) {
|
||||
prv_configure_click(BUTTON_ID_SELECT, prv_launch_launcher);
|
||||
prv_configure_click(BUTTON_ID_DOWN, prv_launch_timeline);
|
||||
prv_configure_click(BUTTON_ID_UP, prv_launch_timeline);
|
||||
}
|
||||
#endif
|
||||
|
||||
void watchface_init(void) {
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
WatchfaceData *data = &s_watchface_data;
|
||||
click_manager_init(&data->click_manager);
|
||||
prv_watchface_configure_click_handlers();
|
||||
#endif
|
||||
}
|
||||
|
||||
void watchface_handle_button_event(PebbleEvent *e) {
|
||||
#if CAPABILITY_HAS_SDK_SHELL4
|
||||
// Only handle button press if app state indicates that the app is still running
|
||||
// which is not in the process of closing
|
||||
WatchfaceData *data = &s_watchface_data;
|
||||
if (app_manager_get_task_context()->closing_state == ProcessRunState_Running) {
|
||||
data->button_pressed = e->button.button_id;
|
||||
switch (e->type) {
|
||||
case PEBBLE_BUTTON_DOWN_EVENT:
|
||||
click_recognizer_handle_button_down(&data->click_manager.recognizers[e->button.button_id]);
|
||||
break;
|
||||
case PEBBLE_BUTTON_UP_EVENT:
|
||||
click_recognizer_handle_button_up(&data->click_manager.recognizers[e->button.button_id]);
|
||||
break;
|
||||
default:
|
||||
PBL_CROAK("Invalid event type: %u", e->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((e->button.button_id == BUTTON_ID_SELECT) && (e->type == PEBBLE_BUTTON_DOWN_EVENT)) {
|
||||
app_manager_put_launch_app_event(&(AppLaunchEventConfig) {
|
||||
.id = system_app_state_machine_get_last_registered_app(),
|
||||
.common.reason = APP_LAUNCH_USER,
|
||||
.common.button = e->button.button_id,
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void watchface_reset_click_manager(void) {
|
||||
WatchfaceData *data = &s_watchface_data;
|
||||
click_manager_reset(&data->click_manager);
|
||||
}
|
33
src/fw/shell/sdk/watchface.h
Normal file
33
src/fw/shell/sdk/watchface.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
#include "kernel/events.h"
|
||||
#include "process_management/app_install_manager.h"
|
||||
#include "services/common/compositor/compositor.h"
|
||||
|
||||
void watchface_init(void);
|
||||
|
||||
void watchface_handle_button_event(PebbleEvent *e);
|
||||
|
||||
AppInstallId watchface_get_default_install_id(void);
|
||||
|
||||
void watchface_launch_default(const CompositorTransition *animation);
|
||||
|
||||
void watchface_set_timeline_peek_enabled(bool visible);
|
||||
|
||||
void watchface_reset_click_manager(void);
|
Loading…
Add table
Add a link
Reference in a new issue