mirror of
https://github.com/google/pebble.git
synced 2025-06-20 00:00:36 +00:00
146 lines
4.2 KiB
C
146 lines
4.2 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 "applib/ui/animation_private.h"
|
|
#include "applib/app_logging.h"
|
|
|
|
#include "kernel/events.h"
|
|
#include "kernel/kernel_applib_state.h"
|
|
|
|
#include "process_management/process_manager.h"
|
|
#include "process_state/app_state/app_state.h"
|
|
|
|
#include "services/common/new_timer/new_timer.h"
|
|
|
|
#include "system/passert.h"
|
|
|
|
#include "syscall/syscall.h"
|
|
#include "syscall/syscall_internal.h"
|
|
|
|
|
|
// The timer ID used for each task that we support
|
|
static TimerID s_kernel_main_timer_id = TIMER_INVALID_ID;
|
|
static TimerID s_app_timer_id = TIMER_INVALID_ID;
|
|
|
|
static bool s_kernel_main_event_pending;
|
|
static bool s_app_event_pending;
|
|
|
|
// ------------------------------------------------------------------------------------------
|
|
void animation_service_cleanup(PebbleTask task) {
|
|
PBL_ASSERT_TASK(PebbleTask_KernelMain);
|
|
|
|
if (task == PebbleTask_KernelMain) {
|
|
if (s_kernel_main_timer_id != TIMER_INVALID_ID) {
|
|
new_timer_delete(s_kernel_main_timer_id);
|
|
s_kernel_main_timer_id = TIMER_INVALID_ID;
|
|
}
|
|
s_kernel_main_event_pending = false;
|
|
} else if (task == PebbleTask_App) {
|
|
if (s_app_timer_id != TIMER_INVALID_ID) {
|
|
new_timer_delete(s_app_timer_id);
|
|
s_app_timer_id = TIMER_INVALID_ID;
|
|
}
|
|
s_app_event_pending = false;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------
|
|
static void prv_timer_callback(void * context) {
|
|
PebbleTask task = (PebbleTask)context;
|
|
|
|
PebbleEvent e = {
|
|
.type = PEBBLE_CALLBACK_EVENT,
|
|
.callback = {
|
|
.callback = animation_private_timer_callback
|
|
}
|
|
};
|
|
|
|
switch (task) {
|
|
case PebbleTask_KernelMain:
|
|
if (!s_kernel_main_event_pending) {
|
|
s_kernel_main_event_pending = true;
|
|
e.callback.data = (void *)kernel_applib_get_animation_state();
|
|
event_put(&e);
|
|
}
|
|
break;
|
|
case PebbleTask_App:
|
|
if (!s_app_event_pending) {
|
|
e.callback.data = (void *)app_state_get_animation_state();
|
|
s_app_event_pending = process_manager_send_event_to_process(task, &e);
|
|
}
|
|
break;
|
|
default:
|
|
PBL_CROAK("Invalid task %s", pebble_task_get_name(pebble_task_get_current()));
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------
|
|
DEFINE_SYSCALL(void, animation_service_timer_event_received, void) {
|
|
PebbleTask task = pebble_task_get_current();
|
|
|
|
if (task == PebbleTask_KernelMain) {
|
|
s_kernel_main_event_pending = false;
|
|
} else if (task == PebbleTask_App) {
|
|
s_app_event_pending = false;
|
|
} else {
|
|
if (PRIVILEGE_WAS_ELEVATED) {
|
|
syscall_failed();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------
|
|
DEFINE_SYSCALL(void, animation_service_timer_schedule, uint32_t ms) {
|
|
PebbleTask task = pebble_task_get_current();
|
|
TimerID *timer_id;
|
|
|
|
if (task == PebbleTask_KernelMain) {
|
|
timer_id = &s_kernel_main_timer_id;
|
|
} else if (task == PebbleTask_App) {
|
|
timer_id = &s_app_timer_id;
|
|
} else {
|
|
if (PRIVILEGE_WAS_ELEVATED) {
|
|
syscall_failed();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Need to create the timer?
|
|
bool success = false;
|
|
if (*timer_id == TIMER_INVALID_ID) {
|
|
*timer_id = new_timer_create();
|
|
}
|
|
|
|
// Schedule/reschedule it
|
|
if (*timer_id != TIMER_INVALID_ID) {
|
|
success = new_timer_start(*timer_id, ms, prv_timer_callback, (void *)(uintptr_t)task,
|
|
0 /*flags */);
|
|
}
|
|
if (!success) {
|
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Error scheduling timer");
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Used for unit tests only
|
|
TimerID animation_service_test_get_timer_id(void) {
|
|
return s_kernel_main_timer_id;
|
|
}
|