Refactor services into classes (#183)
This commit is contained in:
committed by
GitHub
parent
bb7e79886f
commit
3be251d8fb
@@ -142,30 +142,36 @@ static int32_t guiMain(TT_UNUSED void* p) {
|
||||
|
||||
// region AppManifest
|
||||
|
||||
static void start(TT_UNUSED ServiceContext& service) {
|
||||
gui = gui_alloc();
|
||||
class GuiService : public Service {
|
||||
|
||||
gui->thread->setPriority(THREAD_PRIORITY_SERVICE);
|
||||
gui->thread->start();
|
||||
}
|
||||
public:
|
||||
|
||||
static void stop(TT_UNUSED ServiceContext& service) {
|
||||
lock();
|
||||
void onStart(TT_UNUSED ServiceContext& service) override {
|
||||
tt_assert(gui == nullptr);
|
||||
gui = gui_alloc();
|
||||
|
||||
ThreadId thread_id = gui->thread->getId();
|
||||
thread_flags_set(thread_id, GUI_THREAD_FLAG_EXIT);
|
||||
gui->thread->join();
|
||||
delete gui->thread;
|
||||
gui->thread->setPriority(THREAD_PRIORITY_SERVICE);
|
||||
gui->thread->start();
|
||||
}
|
||||
|
||||
unlock();
|
||||
void onStop(TT_UNUSED ServiceContext& service) override {
|
||||
tt_assert(gui != nullptr);
|
||||
lock();
|
||||
|
||||
gui_free(gui);
|
||||
}
|
||||
ThreadId thread_id = gui->thread->getId();
|
||||
thread_flags_set(thread_id, GUI_THREAD_FLAG_EXIT);
|
||||
gui->thread->join();
|
||||
delete gui->thread;
|
||||
|
||||
unlock();
|
||||
|
||||
gui_free(gui);
|
||||
}
|
||||
};
|
||||
|
||||
extern const ServiceManifest manifest = {
|
||||
.id = "Gui",
|
||||
.onStart = &start,
|
||||
.onStop = &stop
|
||||
.createService = create<GuiService>
|
||||
};
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -295,31 +295,35 @@ static void stopAppInternal() {
|
||||
|
||||
// region AppManifest
|
||||
|
||||
static void loader_start(TT_UNUSED ServiceContext& service) {
|
||||
tt_check(loader_singleton == nullptr);
|
||||
loader_singleton = loader_alloc();
|
||||
loader_singleton->dispatcherThread->start();
|
||||
}
|
||||
class LoaderService final : public Service {
|
||||
|
||||
static void loader_stop(TT_UNUSED ServiceContext& service) {
|
||||
tt_check(loader_singleton != nullptr);
|
||||
public:
|
||||
|
||||
// Send stop signal to thread and wait for thread to finish
|
||||
if (!loader_singleton->mutex.lock(2000 / portTICK_PERIOD_MS)) {
|
||||
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "loader_stop");
|
||||
void onStart(TT_UNUSED ServiceContext& service) final {
|
||||
tt_check(loader_singleton == nullptr);
|
||||
loader_singleton = loader_alloc();
|
||||
loader_singleton->dispatcherThread->start();
|
||||
}
|
||||
loader_singleton->dispatcherThread->stop();
|
||||
|
||||
loader_singleton->mutex.unlock();
|
||||
void onStop(TT_UNUSED ServiceContext& service) final {
|
||||
tt_check(loader_singleton != nullptr);
|
||||
|
||||
loader_free();
|
||||
loader_singleton = nullptr;
|
||||
}
|
||||
// Send stop signal to thread and wait for thread to finish
|
||||
if (!loader_singleton->mutex.lock(2000 / portTICK_PERIOD_MS)) {
|
||||
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "loader_stop");
|
||||
}
|
||||
loader_singleton->dispatcherThread->stop();
|
||||
|
||||
loader_singleton->mutex.unlock();
|
||||
|
||||
loader_free();
|
||||
loader_singleton = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
extern const ServiceManifest manifest = {
|
||||
.id = "Loader",
|
||||
.onStart = &loader_start,
|
||||
.onStop = &loader_stop
|
||||
.createService = create<LoaderService>
|
||||
};
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -15,12 +15,7 @@ namespace tt::service::screenshot {
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
std::shared_ptr<ScreenshotService> _Nullable optScreenshotService() {
|
||||
ServiceContext* context = service::findServiceById(manifest.id);
|
||||
if (context != nullptr) {
|
||||
return std::static_pointer_cast<ScreenshotService>(context->getData());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
return service::findServiceById<ScreenshotService>(manifest.id);
|
||||
}
|
||||
|
||||
void ScreenshotService::startApps(const char* path) {
|
||||
@@ -89,14 +84,9 @@ bool ScreenshotService::isTaskStarted() {
|
||||
}
|
||||
}
|
||||
|
||||
static void onStart(ServiceContext& serviceContext) {
|
||||
auto service = std::make_shared<ScreenshotService>();
|
||||
serviceContext.setData(service);
|
||||
}
|
||||
|
||||
extern const ServiceManifest manifest = {
|
||||
.id = "Screenshot",
|
||||
.onStart = onStart
|
||||
.createService = create<ScreenshotService>
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Mutex.h"
|
||||
#include "ScreenshotTask.h"
|
||||
#include "TactilityConfig.h"
|
||||
|
||||
#if TT_FEATURE_SCREENSHOT_ENABLED
|
||||
|
||||
#include "Mutex.h"
|
||||
#include "ScreenshotTask.h"
|
||||
#include "service/Service.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace tt::service::screenshot {
|
||||
@@ -16,7 +17,7 @@ enum class Mode {
|
||||
Apps
|
||||
};
|
||||
|
||||
class ScreenshotService {
|
||||
class ScreenshotService final : public Service {
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -41,35 +41,6 @@ namespace tt::service::statusbar {
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
struct ServiceData {
|
||||
Mutex mutex;
|
||||
std::unique_ptr<Timer> updateTimer;
|
||||
int8_t wifi_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* wifi_last_icon = nullptr;
|
||||
int8_t sdcard_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* sdcard_last_icon = nullptr;
|
||||
int8_t power_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* power_last_icon = nullptr;
|
||||
|
||||
std::unique_ptr<service::Paths> paths;
|
||||
|
||||
~ServiceData() {
|
||||
lvgl::statusbar_icon_remove(wifi_icon_id);
|
||||
lvgl::statusbar_icon_remove(sdcard_icon_id);
|
||||
lvgl::statusbar_icon_remove(power_icon_id);
|
||||
}
|
||||
|
||||
void lock() const {
|
||||
tt_check(mutex.acquire(TtWaitForever) == TtStatusOk);
|
||||
}
|
||||
|
||||
void unlock() const {
|
||||
tt_check(mutex.release() == TtStatusOk);
|
||||
}
|
||||
};
|
||||
|
||||
// region wifi
|
||||
|
||||
const char* getWifiStatusIconForRssi(int rssi) {
|
||||
if (rssi >= -60) {
|
||||
return STATUSBAR_ICON_WIFI_SIGNAL_STRONG_WHITE;
|
||||
@@ -98,26 +69,6 @@ static const char* getWifiStatusIcon(wifi::RadioState state, bool secure) {
|
||||
}
|
||||
}
|
||||
|
||||
static void updateWifiIcon(const service::Paths* paths, const std::shared_ptr<ServiceData>& data) {
|
||||
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) {
|
||||
if (desired_icon != nullptr) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(data->wifi_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(data->wifi_icon_id, true);
|
||||
} else {
|
||||
lvgl::statusbar_icon_set_visibility(data->wifi_icon_id, false);
|
||||
}
|
||||
data->wifi_last_icon = desired_icon;
|
||||
}
|
||||
}
|
||||
|
||||
// endregion wifi
|
||||
|
||||
// region sdcard
|
||||
|
||||
static const char* getSdCardStatusIcon(hal::SdCard::State state) {
|
||||
switch (state) {
|
||||
case hal::SdCard::State::Mounted:
|
||||
@@ -131,27 +82,6 @@ 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;
|
||||
if (sdcard != nullptr) {
|
||||
auto state = sdcard->getState();
|
||||
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);
|
||||
lvgl::statusbar_icon_set_image(data->sdcard_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(data->sdcard_icon_id, true);
|
||||
data->sdcard_last_icon = desired_icon;
|
||||
}
|
||||
}
|
||||
// TODO: Consider tracking how long the SD card has been in unknown status and then show error
|
||||
}
|
||||
}
|
||||
|
||||
// endregion sdcard
|
||||
|
||||
// region power
|
||||
|
||||
static _Nullable const char* getPowerStatusIcon() {
|
||||
auto get_power = getConfiguration()->hardware->power;
|
||||
if (get_power == nullptr) {
|
||||
@@ -192,69 +122,120 @@ static _Nullable const char* getPowerStatusIcon() {
|
||||
}
|
||||
}
|
||||
|
||||
static void updatePowerStatusIcon(const service::Paths* paths, const std::shared_ptr<ServiceData>& data) {
|
||||
const char* desired_icon = getPowerStatusIcon();
|
||||
if (data->power_last_icon != desired_icon) {
|
||||
if (desired_icon != nullptr) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(data->power_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(data->power_icon_id, true);
|
||||
} else {
|
||||
lvgl::statusbar_icon_set_visibility(data->power_icon_id, false);
|
||||
}
|
||||
data->power_last_icon = desired_icon;
|
||||
class StatusbarService final : public Service {
|
||||
|
||||
private:
|
||||
|
||||
Mutex mutex;
|
||||
std::unique_ptr<Timer> updateTimer;
|
||||
int8_t wifi_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* wifi_last_icon = nullptr;
|
||||
int8_t sdcard_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* sdcard_last_icon = nullptr;
|
||||
int8_t power_icon_id = lvgl::statusbar_icon_add();
|
||||
const char* power_last_icon = nullptr;
|
||||
|
||||
std::unique_ptr<service::Paths> paths;
|
||||
|
||||
void lock() const {
|
||||
tt_check(mutex.acquire(TtWaitForever) == TtStatusOk);
|
||||
}
|
||||
}
|
||||
|
||||
// endregion power
|
||||
void unlock() const {
|
||||
tt_check(mutex.release() == TtStatusOk);
|
||||
}
|
||||
|
||||
// region service
|
||||
void updateWifiIcon() {
|
||||
wifi::RadioState radio_state = wifi::getRadioState();
|
||||
bool is_secure = wifi::isConnectionSecure();
|
||||
const char* desired_icon = getWifiStatusIcon(radio_state, is_secure);
|
||||
if (wifi_last_icon != desired_icon) {
|
||||
if (desired_icon != nullptr) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(wifi_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(wifi_icon_id, true);
|
||||
} else {
|
||||
lvgl::statusbar_icon_set_visibility(wifi_icon_id, false);
|
||||
}
|
||||
wifi_last_icon = desired_icon;
|
||||
}
|
||||
}
|
||||
|
||||
static void service_data_free(ServiceData* data) {
|
||||
free(data);
|
||||
}
|
||||
void updatePowerStatusIcon() {
|
||||
const char* desired_icon = getPowerStatusIcon();
|
||||
if (power_last_icon != desired_icon) {
|
||||
if (desired_icon != nullptr) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(power_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(power_icon_id, true);
|
||||
} else {
|
||||
lvgl::statusbar_icon_set_visibility(power_icon_id, false);
|
||||
}
|
||||
power_last_icon = desired_icon;
|
||||
}
|
||||
}
|
||||
|
||||
static void onUpdate(std::shared_ptr<void> parameter) {
|
||||
auto data = std::static_pointer_cast<ServiceData>(parameter);
|
||||
// TODO: Make thread-safe for LVGL
|
||||
auto* paths = data->paths.get();
|
||||
updateWifiIcon(paths, data);
|
||||
updateSdCardIcon(paths, data);
|
||||
updatePowerStatusIcon(paths, data);
|
||||
}
|
||||
void updateSdCardIcon() {
|
||||
auto sdcard = tt::hal::getConfiguration()->sdcard;
|
||||
if (sdcard != nullptr) {
|
||||
auto state = sdcard->getState();
|
||||
if (state != hal::SdCard::State::Unknown) {
|
||||
auto* desired_icon = getSdCardStatusIcon(state);
|
||||
if (sdcard_last_icon != desired_icon) {
|
||||
auto icon_path = paths->getSystemPathLvgl(desired_icon);
|
||||
lvgl::statusbar_icon_set_image(sdcard_icon_id, icon_path);
|
||||
lvgl::statusbar_icon_set_visibility(sdcard_icon_id, true);
|
||||
sdcard_last_icon = desired_icon;
|
||||
}
|
||||
}
|
||||
// TODO: Consider tracking how long the SD card has been in unknown status and then show error
|
||||
}
|
||||
}
|
||||
|
||||
static void onStart(ServiceContext& service) {
|
||||
lvgl::lock(TtWaitForever);
|
||||
auto data = std::make_shared<ServiceData>();
|
||||
lvgl::unlock();
|
||||
void update() {
|
||||
// TODO: Make thread-safe for LVGL
|
||||
updateWifiIcon();
|
||||
updateSdCardIcon();
|
||||
updatePowerStatusIcon();
|
||||
}
|
||||
|
||||
data->paths = service.getPaths();
|
||||
static void onUpdate(std::shared_ptr<void> parameter) {
|
||||
auto service = std::static_pointer_cast<StatusbarService>(parameter);
|
||||
service->update();
|
||||
}
|
||||
|
||||
service.setData(data);
|
||||
public:
|
||||
|
||||
// TODO: Make thread-safe for LVGL
|
||||
lvgl::statusbar_icon_set_visibility(data->wifi_icon_id, true);
|
||||
updateWifiIcon(data->paths.get(), data);
|
||||
updateSdCardIcon(data->paths.get(), data); // also updates visibility
|
||||
updatePowerStatusIcon(data->paths.get(), data);
|
||||
~StatusbarService() final {
|
||||
lvgl::statusbar_icon_remove(wifi_icon_id);
|
||||
lvgl::statusbar_icon_remove(sdcard_icon_id);
|
||||
lvgl::statusbar_icon_remove(power_icon_id);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
void onStart(ServiceContext& serviceContext) override {
|
||||
paths = serviceContext.getPaths();
|
||||
|
||||
static void onStop(ServiceContext& service) {
|
||||
auto data = std::static_pointer_cast<ServiceData>(service.getData());
|
||||
// TODO: Make thread-safe for LVGL
|
||||
lvgl::statusbar_icon_set_visibility(wifi_icon_id, true);
|
||||
|
||||
// Stop thread
|
||||
data->updateTimer->stop();
|
||||
data->updateTimer = nullptr;
|
||||
}
|
||||
auto service = findServiceById(manifest.id);
|
||||
assert(service);
|
||||
onUpdate(service);
|
||||
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, onUpdate, service);
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
updateTimer->start(1000);
|
||||
}
|
||||
|
||||
void onStop(ServiceContext& service) override{
|
||||
updateTimer->stop();
|
||||
updateTimer = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
extern const ServiceManifest manifest = {
|
||||
.id = "Statusbar",
|
||||
.onStart = onStart,
|
||||
.onStop = onStop
|
||||
.createService = create<StatusbarService>
|
||||
};
|
||||
|
||||
// endregion service
|
||||
|
||||
Reference in New Issue
Block a user