Merge develop into main (#167)

- WiFi Connect app is now hidden by default, but accessible at the bottom of the WiFi Manage app when WiFi is turned on.
- WiFi service now turns on WiFi when calling connect() and WiFi is not on.
- Removed `blocking` option for `service::loader::startApp()`. This feature was unused and complex.
- Various apps: Moved private headers into Private/ folder.
- Various apps: created start() function for easy starting.
- Added documentation to all TactilityC APIs
- Refactored various `enum` into `class enum`
- Refactor M5Stack `initBoot()` (but VBus is still 0V for some reason)
This commit is contained in:
Ken Van Hoeylandt
2025-01-17 19:37:42 +01:00
committed by GitHub
parent 3ca0f8cf97
commit 3ea02d912f
147 changed files with 1538 additions and 739 deletions
+11 -13
View File
@@ -17,6 +17,13 @@ namespace tt::service::loader {
#define TAG "loader"
enum class LoaderStatus {
Ok,
ErrorAppStarted,
ErrorUnknownApp,
ErrorInternal,
};
typedef struct {
LoaderEventType type;
} LoaderEventInternal;
@@ -41,20 +48,11 @@ static void loader_free() {
loader_singleton = nullptr;
}
void startApp(const std::string& id, bool blocking, const std::shared_ptr<const Bundle>& parameters) {
void startApp(const std::string& id, const std::shared_ptr<const Bundle>& parameters) {
TT_LOG_I(TAG, "Start app %s", id.c_str());
tt_assert(loader_singleton);
auto message = std::make_shared<LoaderMessageAppStart>(id, parameters);
loader_singleton->dispatcherThread->dispatch(onStartAppMessage, message);
auto event_flag = message->getApiLockEventFlag();
if (blocking) {
/* TODO: Check if task id is not the LVGL one,
because otherwise this fails as the apps starting logic will try to lock lvgl
to update the UI and fail. */
event_flag->wait(message->getApiLockEventFlagValue());
}
}
void stopApp() {
@@ -163,7 +161,7 @@ static LoaderStatus startAppWithManifestInternal(
auto scoped_lock = loader_singleton->mutex.scoped();
if (!scoped_lock->lock(50 / portTICK_PERIOD_MS)) {
return LoaderStatusErrorInternal;
return LoaderStatus::ErrorInternal;
}
auto previous_app = !loader_singleton->appStack.empty() ? loader_singleton->appStack.top() : nullptr;
@@ -192,7 +190,7 @@ static LoaderStatus startAppWithManifestInternal(
};
tt_pubsub_publish(loader_singleton->pubsubExternal, &event_external);
return LoaderStatusOk;
return LoaderStatus::Ok;
}
static void onStartAppMessage(std::shared_ptr<void> message) {
@@ -213,7 +211,7 @@ static LoaderStatus startAppInternal(
const app::AppManifest* manifest = app::findAppById(id);
if (manifest == nullptr) {
TT_LOG_E(TAG, "App not found: %s", id.c_str());
return LoaderStatusErrorUnknownApp;
return LoaderStatus::ErrorUnknownApp;
} else {
return startAppWithManifestInternal(manifest, parameters);
}
+1 -9
View File
@@ -10,21 +10,13 @@ namespace tt::service::loader {
typedef struct Loader Loader;
typedef enum {
LoaderStatusOk,
LoaderStatusErrorAppStarted,
LoaderStatusErrorUnknownApp,
LoaderStatusErrorInternal,
} LoaderStatus;
/**
* @brief Start an app
* @param[in] id application name or id
* @param[in] blocking whether this call is blocking or not. You cannot call this from an LVGL thread.
* @param[in] parameters optional parameters to pass onto the application
*/
void startApp(const std::string& id, bool blocking = false, const std::shared_ptr<const Bundle>& _Nullable parameters = nullptr);
void startApp(const std::string& id, const std::shared_ptr<const Bundle>& _Nullable parameters = nullptr);
/** @brief Stop the currently showing app. Show the previous app if any app was still running. */
void stopApp();
@@ -32,7 +32,7 @@ void ScreenshotService::startApps(const char* path) {
if (task == nullptr || task->isFinished()) {
task = std::make_unique<ScreenshotTask>();
mode = ScreenshotModeApps;
mode = Mode::Apps;
task->startApps(path);
} else {
TT_LOG_W(TAG, "Screenshot task already running");
@@ -48,7 +48,7 @@ void ScreenshotService::startTimed(const char* path, uint8_t delayInSeconds, uin
if (task == nullptr || task->isFinished()) {
task = std::make_unique<ScreenshotTask>();
mode = ScreenshotModeTimed;
mode = Mode::Timed;
task->startTimed(path, delayInSeconds, amount);
} else {
TT_LOG_W(TAG, "Screenshot task already running");
@@ -64,17 +64,17 @@ void ScreenshotService::stop() {
if (task != nullptr) {
task = nullptr;
mode = ScreenshotModeNone;
mode = Mode::None;
} else {
TT_LOG_W(TAG, "Screenshot task not running");
}
}
Mode ScreenshotService::getMode() {
Mode ScreenshotService::getMode() const {
auto scoped_lockable = mutex.scoped();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return ScreenshotModeNone;
return Mode::None;
}
return mode;
@@ -10,11 +10,11 @@
namespace tt::service::screenshot {
typedef enum {
ScreenshotModeNone,
ScreenshotModeTimed,
ScreenshotModeApps
} Mode;
enum class Mode {
None,
Timed,
Apps
};
class ScreenshotService {
@@ -22,14 +22,14 @@ private:
Mutex mutex;
std::unique_ptr<ScreenshotTask> task;
Mode mode = ScreenshotModeNone;
Mode mode = Mode::None;
public:
bool isTaskStarted();
/** The state of the service. */
Mode getMode();
Mode getMode() const;
/** @brief Start taking screenshot whenever an app is started
* @param[in] path the path to store the screenshots at
@@ -25,7 +25,7 @@ class ScreenshotTask {
};
Thread* thread = nullptr;
Mutex mutex = Mutex(Mutex::TypeRecursive);
Mutex mutex = Mutex(Mutex::Type::Recursive);
bool interrupted = false;
bool finished = false;
ScreenshotTaskWork work;
@@ -80,17 +80,17 @@ const char* getWifiStatusIconForRssi(int rssi) {
}
}
static const char* getWifiStatusIcon(wifi::WifiRadioState state, bool secure) {
static const char* getWifiStatusIcon(wifi::RadioState state, bool secure) {
int rssi;
switch (state) {
case wifi::WIFI_RADIO_ON:
case wifi::WIFI_RADIO_ON_PENDING:
case wifi::WIFI_RADIO_CONNECTION_PENDING:
case wifi::RadioState::On:
case wifi::RadioState::OnPending:
case wifi::RadioState::ConnectionPending:
return STATUSBAR_ICON_WIFI_SCAN_WHITE;
case wifi::WIFI_RADIO_OFF_PENDING:
case wifi::WIFI_RADIO_OFF:
case wifi::RadioState::OffPending:
case wifi::RadioState::Off:
return STATUSBAR_ICON_WIFI_OFF_WHITE;
case wifi::WIFI_RADIO_CONNECTION_ACTIVE:
case wifi::RadioState::ConnectionActive:
rssi = wifi::getRssi();
return getWifiStatusIconForRssi(rssi);
default:
@@ -99,7 +99,7 @@ static const char* getWifiStatusIcon(wifi::WifiRadioState state, bool secure) {
}
static void updateWifiIcon(const service::Paths* paths, const std::shared_ptr<ServiceData>& data) {
wifi::WifiRadioState radio_state = wifi::getRadioState();
wifi::RadioState radio_state = wifi::getRadioState();
bool is_secure = wifi::isConnectionSecure();
const char* desired_icon = getWifiStatusIcon(radio_state, is_secure);
if (data->wifi_last_icon != desired_icon) {
@@ -120,11 +120,11 @@ static void updateWifiIcon(const service::Paths* paths, const std::shared_ptr<Se
static const char* getSdCardStatusIcon(hal::SdCard::State state) {
switch (state) {
case hal::SdCard::StateMounted:
case hal::SdCard::State::Mounted:
return STATUSBAR_ICON_SDCARD;
case hal::SdCard::StateError:
case hal::SdCard::StateUnmounted:
case hal::SdCard::StateUnknown:
case hal::SdCard::State::Error:
case hal::SdCard::State::Unmounted:
case hal::SdCard::State::Unknown:
return STATUSBAR_ICON_SDCARD_ALERT;
default:
tt_crash("Unhandled SdCard state");
@@ -135,7 +135,7 @@ static void updateSdCardIcon(const service::Paths* paths, const std::shared_ptr<
auto sdcard = tt::hal::getConfiguration()->sdcard;
if (sdcard != nullptr) {
auto state = sdcard->getState();
if (state != hal::SdCard::StateUnknown) {
if (state != hal::SdCard::State::Unknown) {
auto* desired_icon = getSdCardStatusIcon(state);
if (data->sdcard_last_icon != desired_icon) {
auto icon_path = paths->getSystemPathLvgl(desired_icon);
@@ -161,7 +161,7 @@ static _Nullable const char* getPowerStatusIcon() {
auto power = get_power();
hal::Power::MetricData charge_level;
if (!power->getMetric(hal::Power::MetricType::CHARGE_LEVEL, charge_level)) {
if (!power->getMetric(hal::Power::MetricType::ChargeLevel, charge_level)) {
return nullptr;
}
@@ -228,7 +228,7 @@ static void onStart(ServiceContext& service) {
auto data = std::make_shared<ServiceData>();
lvgl::unlock();
data->paths = std::move(service.getPaths());
data->paths = service.getPaths();
service.setData(data);
@@ -238,7 +238,7 @@ static void onStart(ServiceContext& service) {
updateSdCardIcon(data->paths.get(), data); // also updates visibility
updatePowerStatusIcon(data->paths.get(), data);
data->updateTimer = std::make_unique<Timer>(Timer::TypePeriodic, onUpdate, data);
data->updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, onUpdate, data);
// We want to try and scan more often in case of startup or scan lock failure
data->updateTimer->start(1000);
}