Boot splash and more (#98)
* Boot splash and more - Added developer sdkconfig - Refactored the way FreeRTOS includes are included - Improved Gui/Loader logic - Implemented boot app with splash screen * Updated naming for Gui and Loader services * Renamed Screenshot service methods * Renames * Service renames
This commit is contained in:
committed by
GitHub
parent
3f62ec2efa
commit
0188ce721c
@@ -1,14 +1,9 @@
|
||||
#include "Tactility.h"
|
||||
#include "service/gui/Gui_i.h"
|
||||
#include "service/loader/Loader.h"
|
||||
#include "service/loader/Loader_i.h"
|
||||
#include "lvgl/LvglKeypad.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#endif
|
||||
#include "RtosCompat.h"
|
||||
|
||||
namespace tt::service::gui {
|
||||
|
||||
@@ -25,9 +20,9 @@ void loader_callback(const void* message, TT_UNUSED void* context) {
|
||||
if (event->type == loader::LoaderEventTypeApplicationShowing) {
|
||||
app::App& app = event->app_showing.app;
|
||||
const app::Manifest& app_manifest = app.getManifest();
|
||||
show_app(app, app_manifest.onShow, app_manifest.onHide);
|
||||
showApp(app, app_manifest.onShow, app_manifest.onHide);
|
||||
} else if (event->type == loader::LoaderEventTypeApplicationHiding) {
|
||||
hide_app();
|
||||
hideApp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +38,7 @@ Gui* gui_alloc() {
|
||||
);
|
||||
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||
instance->keyboard = nullptr;
|
||||
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::get_pubsub(), &loader_callback, instance);
|
||||
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::getPubsub(), &loader_callback, instance);
|
||||
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
||||
instance->keyboard_group = lv_group_create();
|
||||
instance->lvgl_parent = lv_scr_act();
|
||||
@@ -76,21 +71,21 @@ void unlock() {
|
||||
tt_check(tt_mutex_release(gui->mutex) == TtStatusOk);
|
||||
}
|
||||
|
||||
void request_draw() {
|
||||
void requestDraw() {
|
||||
tt_assert(gui);
|
||||
ThreadId thread_id = gui->thread->getId();
|
||||
thread_flags_set(thread_id, GUI_THREAD_FLAG_DRAW);
|
||||
}
|
||||
|
||||
void show_app(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide) {
|
||||
void showApp(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide) {
|
||||
lock();
|
||||
tt_check(gui->app_view_port == nullptr);
|
||||
gui->app_view_port = view_port_alloc(app, on_show, on_hide);
|
||||
unlock();
|
||||
request_draw();
|
||||
requestDraw();
|
||||
}
|
||||
|
||||
void hide_app() {
|
||||
void hideApp() {
|
||||
lock();
|
||||
ViewPort* view_port = gui->app_view_port;
|
||||
tt_check(view_port != nullptr);
|
||||
|
||||
@@ -14,26 +14,26 @@ typedef struct Gui Gui;
|
||||
* @param on_show
|
||||
* @param on_hide
|
||||
*/
|
||||
void show_app(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide);
|
||||
void showApp(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide);
|
||||
|
||||
/**
|
||||
* Hide the current app's viewport.
|
||||
* Does not request a re-draw because after hiding the current app,
|
||||
* we always show the previous app, and there is always at least 1 app running.
|
||||
*/
|
||||
void hide_app();
|
||||
void hideApp();
|
||||
|
||||
/**
|
||||
* Show the on-screen keyboard.
|
||||
* @param textarea the textarea to focus the input for
|
||||
*/
|
||||
void keyboard_show(lv_obj_t* textarea);
|
||||
void keyboardShow(lv_obj_t* textarea);
|
||||
|
||||
/**
|
||||
* Hide the on-screen keyboard.
|
||||
* Has no effect when the keyboard is not visible.
|
||||
*/
|
||||
void keyboard_hide();
|
||||
void keyboardHide();
|
||||
|
||||
/**
|
||||
* The on-screen keyboard is only shown when both of these conditions are true:
|
||||
@@ -41,7 +41,7 @@ void keyboard_hide();
|
||||
* - TT_CONFIG_FORCE_ONSCREEN_KEYBOARD is set to true in tactility_config.h
|
||||
* @return if we should show a on-screen keyboard for text input inside our apps
|
||||
*/
|
||||
bool keyboard_is_enabled();
|
||||
bool keyboardIsEnabled();
|
||||
|
||||
/**
|
||||
* Glue code for the on-screen keyboard and the hardware keyboard:
|
||||
@@ -49,6 +49,6 @@ bool keyboard_is_enabled();
|
||||
* - Registers the textarea to the default lv_group_t for hardware keyboards.
|
||||
* @param textarea
|
||||
*/
|
||||
void keyboard_add_textarea(lv_obj_t* textarea);
|
||||
void keyboardAddTextArea(lv_obj_t* textarea);
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -28,7 +28,7 @@ static lv_obj_t* create_app_views(Gui* gui, lv_obj_t* parent, app::App& app) {
|
||||
lv_obj_set_width(child_container, LV_PCT(100));
|
||||
lv_obj_set_flex_grow(child_container, 1);
|
||||
|
||||
if (keyboard_is_enabled()) {
|
||||
if (keyboardIsEnabled()) {
|
||||
gui->keyboard = lv_keyboard_create(vertical_container);
|
||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
|
||||
@@ -10,19 +10,19 @@ extern Gui* gui;
|
||||
|
||||
static void show_keyboard(lv_event_t* event) {
|
||||
lv_obj_t* target = lv_event_get_current_target_obj(event);
|
||||
keyboard_show(target);
|
||||
keyboardShow(target);
|
||||
lv_obj_scroll_to_view(target, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
static void hide_keyboard(TT_UNUSED lv_event_t* event) {
|
||||
keyboard_hide();
|
||||
keyboardHide();
|
||||
}
|
||||
|
||||
bool keyboard_is_enabled() {
|
||||
bool keyboardIsEnabled() {
|
||||
return !lvgl::keypad_is_available() || TT_CONFIG_FORCE_ONSCREEN_KEYBOARD;
|
||||
}
|
||||
|
||||
void keyboard_show(lv_obj_t* textarea) {
|
||||
void keyboardShow(lv_obj_t* textarea) {
|
||||
lock();
|
||||
|
||||
if (gui->keyboard) {
|
||||
@@ -33,7 +33,7 @@ void keyboard_show(lv_obj_t* textarea) {
|
||||
unlock();
|
||||
}
|
||||
|
||||
void keyboard_hide() {
|
||||
void keyboardHide() {
|
||||
lock();
|
||||
|
||||
if (gui->keyboard) {
|
||||
@@ -43,11 +43,11 @@ void keyboard_hide() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
void keyboard_add_textarea(lv_obj_t* textarea) {
|
||||
void keyboardAddTextArea(lv_obj_t* textarea) {
|
||||
lock();
|
||||
tt_check(lvgl::lock(0), "lvgl should already be locked before calling this method");
|
||||
|
||||
if (keyboard_is_enabled()) {
|
||||
if (keyboardIsEnabled()) {
|
||||
lv_obj_add_event_cb(textarea, show_keyboard, LV_EVENT_FOCUSED, nullptr);
|
||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_DEFOCUSED, nullptr);
|
||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_READY, nullptr);
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
#include "service/Manifest.h"
|
||||
#include "service/gui/Gui.h"
|
||||
#include "service/loader/Loader_i.h"
|
||||
#include "RtosCompat.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_heap_caps.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
|
||||
#endif
|
||||
|
||||
namespace tt::service::loader {
|
||||
@@ -65,7 +63,7 @@ static void loader_unlock() {
|
||||
tt_check(tt_mutex_release(loader_singleton->mutex) == TtStatusOk);
|
||||
}
|
||||
|
||||
LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundle) {
|
||||
LoaderStatus startApp(const std::string& id, bool blocking, const Bundle& arguments) {
|
||||
TT_LOG_I(TAG, "Start app %s", id.c_str());
|
||||
tt_assert(loader_singleton);
|
||||
|
||||
@@ -73,7 +71,7 @@ LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundl
|
||||
.value = LoaderStatusOk
|
||||
};
|
||||
|
||||
auto* start_message = new LoaderMessageAppStart(id, bundle);
|
||||
auto* start_message = new LoaderMessageAppStart(id, arguments);
|
||||
LoaderMessage message(start_message, result);
|
||||
|
||||
EventFlag* event_flag = blocking ? new EventFlag() : nullptr;
|
||||
@@ -94,14 +92,14 @@ LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundl
|
||||
return result.value;
|
||||
}
|
||||
|
||||
void stop_app() {
|
||||
void stopApp() {
|
||||
TT_LOG_I(TAG, "Stop app");
|
||||
tt_check(loader_singleton);
|
||||
LoaderMessage message(LoaderMessageTypeAppStop);
|
||||
loader_singleton->queue.put(&message, TtWaitForever);
|
||||
}
|
||||
|
||||
app::App* _Nullable get_current_app() {
|
||||
app::App* _Nullable getCurrentApp() {
|
||||
tt_assert(loader_singleton);
|
||||
loader_lock();
|
||||
app::AppInstance* app = loader_singleton->app_stack.top();
|
||||
@@ -109,7 +107,7 @@ app::App* _Nullable get_current_app() {
|
||||
return dynamic_cast<app::App*>(app);
|
||||
}
|
||||
|
||||
PubSub* get_pubsub() {
|
||||
PubSub* getPubsub() {
|
||||
tt_assert(loader_singleton);
|
||||
// it's safe to return pubsub without locking
|
||||
// because it's never freed and loader is never exited
|
||||
@@ -160,7 +158,7 @@ static void app_transition_to_state(app::AppInstance& app, app::State state) {
|
||||
LoaderEvent event_showing = {
|
||||
.type = LoaderEventTypeApplicationShowing,
|
||||
.app_showing = {
|
||||
.app = dynamic_cast<app::App&>(app)
|
||||
.app = app
|
||||
}
|
||||
};
|
||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_showing);
|
||||
@@ -171,7 +169,7 @@ static void app_transition_to_state(app::AppInstance& app, app::State state) {
|
||||
LoaderEvent event_hiding = {
|
||||
.type = LoaderEventTypeApplicationHiding,
|
||||
.app_hiding = {
|
||||
.app = dynamic_cast<app::App&>(app)
|
||||
.app = app
|
||||
}
|
||||
};
|
||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_hiding);
|
||||
@@ -198,6 +196,8 @@ static LoaderStatus loader_do_start_app_with_manifest(
|
||||
|
||||
auto previous_app = !loader_singleton->app_stack.empty() ? loader_singleton->app_stack.top() : nullptr;
|
||||
auto new_app = new app::AppInstance(*manifest, bundle);
|
||||
new_app->mutableFlags().showStatusbar = (manifest->type != app::TypeBoot);
|
||||
|
||||
loader_singleton->app_stack.push(new_app);
|
||||
app_transition_to_state(*new_app, app::StateInitial);
|
||||
app_transition_to_state(*new_app, app::StateStarted);
|
||||
@@ -217,7 +217,7 @@ static LoaderStatus loader_do_start_app_with_manifest(
|
||||
LoaderEvent event_external = {
|
||||
.type = LoaderEventTypeApplicationStarted,
|
||||
.app_started = {
|
||||
.app = dynamic_cast<app::App&>(*new_app)
|
||||
.app = *new_app
|
||||
}
|
||||
};
|
||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_external);
|
||||
@@ -233,6 +233,7 @@ static LoaderStatus do_start_by_id(
|
||||
|
||||
const app::Manifest* manifest = app::findAppById(id);
|
||||
if (manifest == nullptr) {
|
||||
TT_LOG_E(TAG, "App not found: %s", id.c_str());
|
||||
return LoaderStatusErrorUnknownApp;
|
||||
} else {
|
||||
return loader_do_start_app_with_manifest(manifest, bundle);
|
||||
@@ -251,14 +252,15 @@ static void do_stop_app() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (original_stack_size == 1) {
|
||||
// Stop current app
|
||||
app::AppInstance* app_to_stop = loader_singleton->app_stack.top();
|
||||
|
||||
if (original_stack_size == 1 && app_to_stop->getManifest().type != app::TypeBoot) {
|
||||
loader_unlock();
|
||||
TT_LOG_E(TAG, "Stop app: can't stop root app");
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop current app
|
||||
app::AppInstance* app_to_stop = loader_singleton->app_stack.top();
|
||||
std::unique_ptr<app::ResultHolder> result_holder = std::move(app_to_stop->getResult());
|
||||
|
||||
const app::Manifest& manifest = app_to_stop->getManifest();
|
||||
@@ -272,35 +274,38 @@ static void do_stop_app() {
|
||||
TT_LOG_I(TAG, "Free heap: %zu", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
#endif
|
||||
|
||||
app::AppInstance* app_to_resume = loader_singleton->app_stack.top();
|
||||
tt_assert(app_to_resume);
|
||||
app_transition_to_state(*app_to_resume, app::StateShowing);
|
||||
// If there's a previous app, resume it
|
||||
if (!loader_singleton->app_stack.empty()) {
|
||||
app::AppInstance* app_to_resume = loader_singleton->app_stack.top();
|
||||
tt_assert(app_to_resume);
|
||||
app_transition_to_state(*app_to_resume, app::StateShowing);
|
||||
|
||||
auto on_result = app_to_resume->getManifest().onResult;
|
||||
if (on_result != nullptr) {
|
||||
if (result_holder != nullptr) {
|
||||
Bundle* result_bundle = result_holder->resultData;
|
||||
if (result_bundle != nullptr) {
|
||||
on_result(
|
||||
*app_to_resume,
|
||||
result_holder->result,
|
||||
*result_bundle
|
||||
);
|
||||
auto on_result = app_to_resume->getManifest().onResult;
|
||||
if (on_result != nullptr) {
|
||||
if (result_holder != nullptr) {
|
||||
Bundle* result_bundle = result_holder->resultData;
|
||||
if (result_bundle != nullptr) {
|
||||
on_result(
|
||||
*app_to_resume,
|
||||
result_holder->result,
|
||||
*result_bundle
|
||||
);
|
||||
} else {
|
||||
const Bundle empty_bundle;
|
||||
on_result(
|
||||
*app_to_resume,
|
||||
result_holder->result,
|
||||
empty_bundle
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const Bundle empty_bundle;
|
||||
on_result(
|
||||
*app_to_resume,
|
||||
result_holder->result,
|
||||
empty_bundle
|
||||
*app_to_resume,
|
||||
app::ResultCancelled,
|
||||
empty_bundle
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const Bundle empty_bundle;
|
||||
on_result(
|
||||
*app_to_resume,
|
||||
app::ResultCancelled,
|
||||
empty_bundle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,58 +16,26 @@ typedef enum {
|
||||
LoaderStatusErrorInternal,
|
||||
} LoaderStatus;
|
||||
|
||||
typedef enum {
|
||||
LoaderEventTypeApplicationStarted,
|
||||
LoaderEventTypeApplicationShowing,
|
||||
LoaderEventTypeApplicationHiding,
|
||||
LoaderEventTypeApplicationStopped
|
||||
} LoaderEventType;
|
||||
|
||||
typedef struct {
|
||||
app::App& app;
|
||||
} LoaderEventAppStarted;
|
||||
|
||||
typedef struct {
|
||||
app::App& app;
|
||||
} LoaderEventAppShowing;
|
||||
|
||||
typedef struct {
|
||||
app::App& app;
|
||||
} LoaderEventAppHiding;
|
||||
|
||||
typedef struct {
|
||||
const app::Manifest& manifest;
|
||||
} LoaderEventAppStopped;
|
||||
|
||||
typedef struct {
|
||||
LoaderEventType type;
|
||||
union {
|
||||
LoaderEventAppStarted app_started;
|
||||
LoaderEventAppShowing app_showing;
|
||||
LoaderEventAppHiding app_hiding;
|
||||
LoaderEventAppStopped app_stopped;
|
||||
};
|
||||
} LoaderEvent;
|
||||
|
||||
/**
|
||||
* @brief Start an app
|
||||
* @param[in] id application name or id
|
||||
* @param[in] blocking application arguments
|
||||
* @param[in] bundle optional bundle. Ownership is transferred to Loader.
|
||||
* @param[in] blocking whether this call is blocking or not. You cannot call this from an LVGL thread.
|
||||
* @param[in] arguments optional parameters to pass onto the application
|
||||
* @return LoaderStatus
|
||||
*/
|
||||
LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundle);
|
||||
LoaderStatus startApp(const std::string& id, bool blocking = false, const Bundle& arguments = Bundle());
|
||||
|
||||
/**
|
||||
* @brief Stop the currently showing app. Show the previous app if any app was still running.
|
||||
*/
|
||||
void stop_app();
|
||||
void stopApp();
|
||||
|
||||
app::App* _Nullable get_current_app();
|
||||
app::App* _Nullable getCurrentApp();
|
||||
|
||||
/**
|
||||
* @brief PubSub for LoaderEvent
|
||||
*/
|
||||
PubSub* get_pubsub();
|
||||
PubSub* getPubsub();
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -15,8 +15,8 @@ extern const Manifest manifest;
|
||||
|
||||
typedef struct {
|
||||
Mutex* mutex;
|
||||
ScreenshotTask* task;
|
||||
ScreenshotMode mode;
|
||||
task::ScreenshotTask* task;
|
||||
Mode mode;
|
||||
} ServiceData;
|
||||
|
||||
static ServiceData* service_data_alloc() {
|
||||
@@ -49,14 +49,14 @@ static void on_start(Service& service) {
|
||||
static void on_stop(Service& service) {
|
||||
auto* data = static_cast<ServiceData*>(service.getData());
|
||||
if (data->task) {
|
||||
task_free(data->task);
|
||||
task::free(data->task);
|
||||
data->task = nullptr;
|
||||
}
|
||||
tt_mutex_free(data->mutex);
|
||||
service_data_free(data);
|
||||
}
|
||||
|
||||
void start_apps(const char* path) {
|
||||
void startApps(const char* path) {
|
||||
_Nullable auto* service = findServiceById(manifest.id);
|
||||
if (service == nullptr) {
|
||||
TT_LOG_E(TAG, "Service not found");
|
||||
@@ -66,16 +66,16 @@ void start_apps(const char* path) {
|
||||
auto* data = static_cast<ServiceData*>(service->getData());
|
||||
service_data_lock(data);
|
||||
if (data->task == nullptr) {
|
||||
data->task = task_alloc();
|
||||
data->task = task::alloc();
|
||||
data->mode = ScreenshotModeApps;
|
||||
task_start_apps(data->task, path);
|
||||
task::startApps(data->task, path);
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Screenshot task already running");
|
||||
}
|
||||
service_data_unlock(data);
|
||||
}
|
||||
|
||||
void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||
_Nullable auto* service = findServiceById(manifest.id);
|
||||
if (service == nullptr) {
|
||||
TT_LOG_E(TAG, "Service not found");
|
||||
@@ -85,9 +85,9 @@ void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||
auto* data = static_cast<ServiceData*>(service->getData());
|
||||
service_data_lock(data);
|
||||
if (data->task == nullptr) {
|
||||
data->task = task_alloc();
|
||||
data->task = task::alloc();
|
||||
data->mode = ScreenshotModeTimed;
|
||||
task_start_timed(data->task, path, delay_in_seconds, amount);
|
||||
task::startTimed(data->task, path, delay_in_seconds, amount);
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Screenshot task already running");
|
||||
}
|
||||
@@ -104,8 +104,8 @@ void stop() {
|
||||
auto data = static_cast<ServiceData*>(service->getData());
|
||||
service_data_lock(data);
|
||||
if (data->task != nullptr) {
|
||||
task_stop(data->task);
|
||||
task_free(data->task);
|
||||
task::stop(data->task);
|
||||
task::free(data->task);
|
||||
data->task = nullptr;
|
||||
data->mode = ScreenshotModeNone;
|
||||
} else {
|
||||
@@ -114,7 +114,7 @@ void stop() {
|
||||
service_data_unlock(data);
|
||||
}
|
||||
|
||||
ScreenshotMode get_mode() {
|
||||
Mode getMode() {
|
||||
_Nullable auto* service = findServiceById(manifest.id);
|
||||
if (service == nullptr) {
|
||||
TT_LOG_E(TAG, "Service not found");
|
||||
@@ -122,14 +122,14 @@ ScreenshotMode get_mode() {
|
||||
} else {
|
||||
auto* data = static_cast<ServiceData*>(service->getData());
|
||||
service_data_lock(data);
|
||||
ScreenshotMode mode = data->mode;
|
||||
Mode mode = data->mode;
|
||||
service_data_unlock(data);
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_started() {
|
||||
return get_mode() != ScreenshotModeNone;
|
||||
bool isStarted() {
|
||||
return getMode() != ScreenshotModeNone;
|
||||
}
|
||||
|
||||
extern const Manifest manifest = {
|
||||
|
||||
@@ -8,24 +8,24 @@ typedef enum {
|
||||
ScreenshotModeNone,
|
||||
ScreenshotModeTimed,
|
||||
ScreenshotModeApps
|
||||
} ScreenshotMode;
|
||||
} Mode;
|
||||
|
||||
/** @brief Starts taking screenshot with a timer
|
||||
* @param path the path to store the screenshots in
|
||||
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
||||
* @param amount 0 = indefinite, >0 for a specific
|
||||
*/
|
||||
void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||
|
||||
/** @brief Starts taking screenshot when an app is started
|
||||
* @param path the path to store the screenshots in
|
||||
*/
|
||||
void start_apps(const char* path);
|
||||
void startApps(const char* path);
|
||||
|
||||
void stop();
|
||||
|
||||
ScreenshotMode get_mode();
|
||||
Mode getMode();
|
||||
|
||||
bool is_started();
|
||||
bool isStarted();
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "service/loader/Loader.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
|
||||
namespace tt::service::screenshot {
|
||||
namespace tt::service::screenshot::task {
|
||||
|
||||
#define TAG "screenshot_task"
|
||||
|
||||
@@ -39,7 +39,7 @@ static void task_unlock(ScreenshotTaskData* data) {
|
||||
tt_check(tt_mutex_release(data->mutex) == TtStatusOk);
|
||||
}
|
||||
|
||||
ScreenshotTask* task_alloc() {
|
||||
ScreenshotTask* alloc() {
|
||||
auto* data = static_cast<ScreenshotTaskData*>(malloc(sizeof(ScreenshotTaskData)));
|
||||
*data = (ScreenshotTaskData) {
|
||||
.thread = nullptr,
|
||||
@@ -49,10 +49,10 @@ ScreenshotTask* task_alloc() {
|
||||
return data;
|
||||
}
|
||||
|
||||
void task_free(ScreenshotTask* task) {
|
||||
void free(ScreenshotTask* task) {
|
||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||
if (data->thread) {
|
||||
task_stop(data);
|
||||
stop(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ static int32_t screenshot_task(void* context) {
|
||||
break; // Interrupted loop
|
||||
}
|
||||
} else if (data->work.type == TASK_WORK_TYPE_APPS) {
|
||||
app::App* _Nullable app = loader::get_current_app();
|
||||
app::App* _Nullable app = loader::getCurrentApp();
|
||||
if (app) {
|
||||
const app::Manifest& manifest = app->getManifest();
|
||||
if (manifest.id != last_app_id) {
|
||||
@@ -136,7 +136,7 @@ static void task_start(ScreenshotTaskData* data) {
|
||||
task_unlock(data);
|
||||
}
|
||||
|
||||
void task_start_apps(ScreenshotTask* task, const char* path) {
|
||||
void startApps(ScreenshotTask* task, const char* path) {
|
||||
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||
task_lock(data);
|
||||
@@ -151,7 +151,7 @@ void task_start_apps(ScreenshotTask* task, const char* path) {
|
||||
task_unlock(data);
|
||||
}
|
||||
|
||||
void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||
void startTimed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||
task_lock(data);
|
||||
@@ -168,7 +168,7 @@ void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_s
|
||||
task_unlock(data);
|
||||
}
|
||||
|
||||
void task_stop(ScreenshotTask* task) {
|
||||
void stop(ScreenshotTask* task) {
|
||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||
if (data->thread != nullptr) {
|
||||
task_lock(data);
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace tt::service::screenshot {
|
||||
namespace tt::service::screenshot::task {
|
||||
|
||||
typedef void ScreenshotTask;
|
||||
|
||||
ScreenshotTask* task_alloc();
|
||||
ScreenshotTask* alloc();
|
||||
|
||||
void task_free(ScreenshotTask* task);
|
||||
void free(ScreenshotTask* task);
|
||||
|
||||
/** @brief Start taking screenshots after a certain delay
|
||||
* @param task the screenshot task
|
||||
@@ -16,17 +16,17 @@ void task_free(ScreenshotTask* task);
|
||||
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
||||
* @param amount 0 = indefinite, >0 for a specific
|
||||
*/
|
||||
void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||
void startTimed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||
|
||||
/** @brief Start taking screenshot whenever an app is started
|
||||
* @param task the screenshot task
|
||||
* @param path the path to store the screenshots at
|
||||
*/
|
||||
void task_start_apps(ScreenshotTask* task, const char* path);
|
||||
void startApps(ScreenshotTask* task, const char* path);
|
||||
|
||||
/** @brief Stop taking screenshots
|
||||
* @param task the screenshot task
|
||||
*/
|
||||
void task_stop(ScreenshotTask* task);
|
||||
void stop(ScreenshotTask* task);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef struct {
|
||||
|
||||
// region wifi
|
||||
|
||||
const char* get_status_icon_for_rssi(int rssi, bool secured) {
|
||||
const char* getWifiStatusIconForRssi(int rssi, bool secured) {
|
||||
if (rssi > 0) {
|
||||
return TT_ASSETS_ICON_WIFI_CONNECTION_ISSUE;
|
||||
} else if (rssi >= -30) {
|
||||
@@ -52,16 +52,16 @@ static const char* wifi_get_status_icon(wifi::WifiRadioState state, bool secure)
|
||||
case wifi::WIFI_RADIO_CONNECTION_PENDING:
|
||||
return TT_ASSETS_ICON_WIFI_FIND;
|
||||
case wifi::WIFI_RADIO_CONNECTION_ACTIVE:
|
||||
rssi = wifi::get_rssi();
|
||||
return get_status_icon_for_rssi(rssi, secure);
|
||||
rssi = wifi::getRssi();
|
||||
return getWifiStatusIconForRssi(rssi, secure);
|
||||
default:
|
||||
tt_crash("not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
static void update_wifi_icon(ServiceData* data) {
|
||||
wifi::WifiRadioState radio_state = wifi::get_radio_state();
|
||||
bool is_secure = wifi::is_connection_secure();
|
||||
wifi::WifiRadioState radio_state = wifi::getRadioState();
|
||||
bool is_secure = wifi::isConnectionSecure();
|
||||
const char* desired_icon = wifi_get_status_icon(radio_state, is_secure);
|
||||
if (data->wifi_last_icon != desired_icon) {
|
||||
lvgl::statusbar_icon_set_image(data->wifi_icon_id, desired_icon);
|
||||
|
||||
@@ -8,6 +8,6 @@ namespace tt::service::statusbar {
|
||||
* @param secured whether the access point is a secured one (as in: not an open one)
|
||||
* @return
|
||||
*/
|
||||
const char* get_status_icon_for_rssi(int rssi, bool secured);
|
||||
const char* getWifiStatusIconForRssi(int rssi, bool secured);
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user