Merge develop into main (#150)
- Update `Configuration` to use C++ vector instead of C arrays - Rename `Desktop` app to `Launcher` - Fix for hard-coded app start of `Launcher` and `CrashDiagnostics` apps. - Ensure `Launcher` icons are clickable, even if they're not loading. - Don't show error scenario for SD card in statusbar when SD card status is unknown (this happens during Mutex timeout due to LVGL rendering delays) - Cleanup deprecated `Mutex` methods. - `hal::getConfiguration()` now returns a pointer instead of a reference, just like `tt:getConfiguration()`
This commit is contained in:
committed by
GitHub
parent
415096c3b2
commit
4f360741a1
@@ -40,7 +40,6 @@ namespace app {
|
||||
namespace alertdialog { extern const AppManifest manifest; }
|
||||
namespace applist { extern const AppManifest manifest; }
|
||||
namespace boot { extern const AppManifest manifest; }
|
||||
namespace desktop { extern const AppManifest manifest; }
|
||||
namespace files { extern const AppManifest manifest; }
|
||||
namespace gpio { extern const AppManifest manifest; }
|
||||
namespace display { extern const AppManifest manifest; }
|
||||
@@ -48,6 +47,7 @@ namespace app {
|
||||
namespace i2csettings { extern const AppManifest manifest; }
|
||||
namespace imageviewer { extern const AppManifest manifest; }
|
||||
namespace inputdialog { extern const AppManifest manifest; }
|
||||
namespace launcher { extern const AppManifest manifest; }
|
||||
namespace log { extern const AppManifest manifest; }
|
||||
namespace power { extern const AppManifest manifest; }
|
||||
namespace selectiondialog { extern const AppManifest manifest; }
|
||||
@@ -74,7 +74,6 @@ static const std::vector<const app::AppManifest*> system_apps = {
|
||||
&app::alertdialog::manifest,
|
||||
&app::applist::manifest,
|
||||
&app::boot::manifest,
|
||||
&app::desktop::manifest,
|
||||
&app::display::manifest,
|
||||
&app::files::manifest,
|
||||
&app::gpio::manifest,
|
||||
@@ -82,6 +81,7 @@ static const std::vector<const app::AppManifest*> system_apps = {
|
||||
&app::i2csettings::manifest,
|
||||
&app::imageviewer::manifest,
|
||||
&app::inputdialog::manifest,
|
||||
&app::launcher::manifest,
|
||||
&app::log::manifest,
|
||||
&app::settings::manifest,
|
||||
&app::selectiondialog::manifest,
|
||||
@@ -104,7 +104,7 @@ static const std::vector<const app::AppManifest*> system_apps = {
|
||||
|
||||
static void register_system_apps() {
|
||||
TT_LOG_I(TAG, "Registering default apps");
|
||||
for (const auto& app_manifest: system_apps) {
|
||||
for (const auto* app_manifest: system_apps) {
|
||||
addApp(app_manifest);
|
||||
}
|
||||
|
||||
@@ -113,16 +113,11 @@ static void register_system_apps() {
|
||||
}
|
||||
}
|
||||
|
||||
static void register_user_apps(const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT]) {
|
||||
static void register_user_apps(const std::vector<const app::AppManifest*>& apps) {
|
||||
TT_LOG_I(TAG, "Registering user apps");
|
||||
for (size_t i = 0; i < TT_CONFIG_APPS_LIMIT; i++) {
|
||||
const app::AppManifest* manifest = apps[i];
|
||||
if (manifest != nullptr) {
|
||||
addApp(manifest);
|
||||
} else {
|
||||
// reached end of list
|
||||
break;
|
||||
}
|
||||
for (auto* manifest : apps) {
|
||||
assert(manifest != nullptr);
|
||||
addApp(manifest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,17 +129,12 @@ static void register_and_start_system_services() {
|
||||
}
|
||||
}
|
||||
|
||||
static void register_and_start_user_services(const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT]) {
|
||||
static void register_and_start_user_services(const std::vector<const service::ServiceManifest*>& services) {
|
||||
TT_LOG_I(TAG, "Registering and starting user services");
|
||||
for (size_t i = 0; i < TT_CONFIG_SERVICES_LIMIT; i++) {
|
||||
const service::ServiceManifest* manifest = services[i];
|
||||
if (manifest != nullptr) {
|
||||
addService(manifest);
|
||||
tt_check(service::startService(manifest->id));
|
||||
} else {
|
||||
// reached end of list
|
||||
break;
|
||||
}
|
||||
for (auto* manifest : services) {
|
||||
assert(manifest != nullptr);
|
||||
addService(manifest);
|
||||
tt_check(service::startService(manifest->id));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ struct Configuration {
|
||||
/** HAL configuration (drivers) */
|
||||
const hal::Configuration* hardware;
|
||||
/** List of user applications */
|
||||
const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT] = {};
|
||||
const std::vector<const app::AppManifest*> apps;
|
||||
/** List of user services */
|
||||
const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT] = {};
|
||||
const std::vector<const service::ServiceManifest*> services;
|
||||
/** Optional app to start automatically after the splash screen. */
|
||||
const char* _Nullable autoStartAppId = nullptr;
|
||||
};
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
#include "sdkconfig.h"
|
||||
#endif
|
||||
|
||||
#include "TactilityHeadlessConfig.h"
|
||||
|
||||
#define TT_CONFIG_APPS_LIMIT 32
|
||||
#define TT_CONFIG_FORCE_ONSCREEN_KEYBOARD false // for development/debug purposes
|
||||
#define TT_SCREENSHOT_MODE false // for taking screenshots (e.g. forces SD card presence and Files tree on simulator)
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ class AppContext;
|
||||
enum Type {
|
||||
/** Boot screen, shown before desktop is launched. */
|
||||
TypeBoot,
|
||||
/** A desktop app sits at the root of the app stack managed by the Loader service */
|
||||
TypeDesktop,
|
||||
/** A launcher app sits at the root of the app stack after the boot splash is finished */
|
||||
TypeLauncher,
|
||||
/** Apps that generally aren't started from the desktop (e.g. image viewer) */
|
||||
TypeHidden,
|
||||
/** Standard apps, provided by the system. */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "Assets.h"
|
||||
#include "TactilityCore.h"
|
||||
|
||||
#include "app/AppContext.h"
|
||||
#include "app/display/DisplaySettings.h"
|
||||
#include "app/launcher/Launcher.h"
|
||||
#include "hal/Display.h"
|
||||
#include "service/loader/Loader.h"
|
||||
#include "lvgl/Style.h"
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "kernel/PanicHandler.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "app/crashdiagnostics/CrashDiagnostics.h"
|
||||
#else
|
||||
#define CONFIG_TT_SPLASH_DURATION 0
|
||||
#endif
|
||||
@@ -62,32 +63,29 @@ static int32_t bootThreadCallback(TT_UNUSED void* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void startNextApp() {
|
||||
auto config = tt::getConfiguration();
|
||||
std::string next_app;
|
||||
if (config->autoStartAppId) {
|
||||
TT_LOG_I(TAG, "init auto-starting %s", config->autoStartAppId);
|
||||
next_app = config->autoStartAppId;
|
||||
} else {
|
||||
next_app = "Desktop";
|
||||
}
|
||||
|
||||
static void startNextApp() {
|
||||
#ifdef ESP_PLATFORM
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
if (reason == ESP_RST_PANIC) {
|
||||
tt::service::loader::startApp("CrashDiagnostics");
|
||||
} else {
|
||||
tt::service::loader::startApp(next_app);
|
||||
app::crashdiagnostics::start();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
tt::service::loader::startApp(next_app);
|
||||
#endif
|
||||
|
||||
auto* config = tt::getConfiguration();
|
||||
if (config->autoStartAppId) {
|
||||
TT_LOG_I(TAG, "init auto-starting %s", config->autoStartAppId);
|
||||
tt::service::loader::startApp(config->autoStartAppId);
|
||||
} else {
|
||||
app::launcher::start();
|
||||
}
|
||||
}
|
||||
|
||||
static void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) {
|
||||
auto data = std::static_pointer_cast<Data>(app.getData());
|
||||
|
||||
lv_obj_t* image = lv_image_create(parent);
|
||||
auto* image = lv_image_create(parent);
|
||||
lv_obj_set_size(image, LV_PCT(100), LV_PCT(100));
|
||||
|
||||
auto paths = app.getPaths();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
#ifdef ESP_TARGET
|
||||
|
||||
#include <esp_private/panic_internal.h>
|
||||
#include "lvgl.h"
|
||||
#include "lvgl/Statusbar.h"
|
||||
#include "service/loader/Loader.h"
|
||||
#include "app/launcher/Launcher.h"
|
||||
#include "qrcode.h"
|
||||
#include "QrHelpers.h"
|
||||
#include "QrUrl.h"
|
||||
#include "service/loader/Loader.h"
|
||||
|
||||
#define TAG "crash_diagnostics"
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace tt::app::crashdiagnostics {
|
||||
|
||||
void onContinuePressed(TT_UNUSED lv_event_t* event) {
|
||||
tt::service::loader::stopApp();
|
||||
tt::service::loader::startApp("Desktop");
|
||||
tt::app::launcher::start();
|
||||
}
|
||||
|
||||
static void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) {
|
||||
static void onShow(AppContext& app, lv_obj_t* parent) {
|
||||
auto* display = lv_obj_get_display(parent);
|
||||
int32_t parent_height = lv_display_get_vertical_resolution(display) - STATUSBAR_HEIGHT;
|
||||
|
||||
@@ -116,6 +116,10 @@ extern const AppManifest manifest = {
|
||||
.onShow = onShow
|
||||
};
|
||||
|
||||
void start() {
|
||||
service::loader::startApp(manifest.id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_TARGET
|
||||
|
||||
namespace tt::app::crashdiagnostics {
|
||||
|
||||
void start();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+10
-4
@@ -5,7 +5,7 @@
|
||||
#include "service/loader/Loader.h"
|
||||
#include "Assets.h"
|
||||
|
||||
namespace tt::app::desktop {
|
||||
namespace tt::app::launcher {
|
||||
|
||||
static void onAppPressed(TT_UNUSED lv_event_t* e) {
|
||||
auto* appId = (const char*)lv_event_get_user_data(e);
|
||||
@@ -33,6 +33,8 @@ static lv_obj_t* createAppButton(lv_obj_t* parent, const char* title, const char
|
||||
lv_obj_add_event_cb(apps_button, onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)appId);
|
||||
lv_obj_set_style_image_recolor(button_image, lv_theme_get_color_primary(parent), 0);
|
||||
lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, 0);
|
||||
// Ensure buttons are still tappable when asset fails to load
|
||||
lv_obj_set_size(button_image, 64, 64);
|
||||
|
||||
auto* label = lv_label_create(wrapper);
|
||||
lv_label_set_text(label, title);
|
||||
@@ -73,10 +75,14 @@ static void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) {
|
||||
}
|
||||
|
||||
extern const AppManifest manifest = {
|
||||
.id = "Desktop",
|
||||
.name = "Desktop",
|
||||
.type = TypeDesktop,
|
||||
.id = "Launcher",
|
||||
.name = "Launcher",
|
||||
.type = TypeLauncher,
|
||||
.onShow = onShow,
|
||||
};
|
||||
|
||||
void start() {
|
||||
service::loader::startApp(manifest.id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::app::launcher {
|
||||
|
||||
void start();
|
||||
|
||||
}
|
||||
@@ -176,7 +176,7 @@ void ScreenshotUi::createFilePathWidgets(lv_obj_t* parent) {
|
||||
lv_textarea_set_one_line(pathTextArea, true);
|
||||
lv_obj_set_flex_grow(pathTextArea, 1);
|
||||
if (kernel::getPlatform() == kernel::PlatformEsp) {
|
||||
auto sdcard = tt::hal::getConfiguration().sdcard;
|
||||
auto sdcard = tt::hal::getConfiguration()->sdcard;
|
||||
if (sdcard != nullptr && sdcard->getState() == hal::SdCard::StateMounted) {
|
||||
lv_textarea_set_text(pathTextArea, "A:/sdcard");
|
||||
} else {
|
||||
|
||||
@@ -132,20 +132,19 @@ static const char* getSdCardStatusIcon(hal::SdCard::State state) {
|
||||
}
|
||||
|
||||
static void updateSdCardIcon(const service::Paths* paths, const std::shared_ptr<ServiceData>& data) {
|
||||
auto sdcard = tt::hal::getConfiguration().sdcard;
|
||||
auto sdcard = tt::hal::getConfiguration()->sdcard;
|
||||
if (sdcard != nullptr) {
|
||||
auto state = sdcard->getState();
|
||||
const char* desired_icon = getSdCardStatusIcon(state);
|
||||
if (data->sdcard_last_icon != desired_icon) {
|
||||
if (desired_icon != nullptr) {
|
||||
if (state != hal::SdCard::StateUnknown) {
|
||||
auto* desired_icon = getSdCardStatusIcon(state);
|
||||
if (data->sdcard_last_icon != desired_icon) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(data->sdcard_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(data->sdcard_icon_id, true);
|
||||
} else {
|
||||
lvgl::statusbar_icon_set_visibility(data->sdcard_icon_id, false);
|
||||
data->sdcard_last_icon = desired_icon;
|
||||
}
|
||||
data->sdcard_last_icon = desired_icon;
|
||||
}
|
||||
// TODO: Consider tracking how long the SD card has been in unknown status and then show error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user