diff --git a/Data/system/app/TimeZone/search.png b/Data/system/app/TimeZone/assets/search.png similarity index 100% rename from Data/system/app/TimeZone/search.png rename to Data/system/app/TimeZone/assets/search.png diff --git a/Data/system/service/Statusbar/location.png b/Data/system/service/Statusbar/assets/location.png similarity index 100% rename from Data/system/service/Statusbar/location.png rename to Data/system/service/Statusbar/assets/location.png diff --git a/Data/system/service/Statusbar/power_0.png b/Data/system/service/Statusbar/assets/power_0.png similarity index 100% rename from Data/system/service/Statusbar/power_0.png rename to Data/system/service/Statusbar/assets/power_0.png diff --git a/Data/system/service/Statusbar/power_10.png b/Data/system/service/Statusbar/assets/power_10.png similarity index 100% rename from Data/system/service/Statusbar/power_10.png rename to Data/system/service/Statusbar/assets/power_10.png diff --git a/Data/system/service/Statusbar/power_100.png b/Data/system/service/Statusbar/assets/power_100.png similarity index 100% rename from Data/system/service/Statusbar/power_100.png rename to Data/system/service/Statusbar/assets/power_100.png diff --git a/Data/system/service/Statusbar/power_20.png b/Data/system/service/Statusbar/assets/power_20.png similarity index 100% rename from Data/system/service/Statusbar/power_20.png rename to Data/system/service/Statusbar/assets/power_20.png diff --git a/Data/system/service/Statusbar/power_30.png b/Data/system/service/Statusbar/assets/power_30.png similarity index 100% rename from Data/system/service/Statusbar/power_30.png rename to Data/system/service/Statusbar/assets/power_30.png diff --git a/Data/system/service/Statusbar/power_40.png b/Data/system/service/Statusbar/assets/power_40.png similarity index 100% rename from Data/system/service/Statusbar/power_40.png rename to Data/system/service/Statusbar/assets/power_40.png diff --git a/Data/system/service/Statusbar/power_50.png b/Data/system/service/Statusbar/assets/power_50.png similarity index 100% rename from Data/system/service/Statusbar/power_50.png rename to Data/system/service/Statusbar/assets/power_50.png diff --git a/Data/system/service/Statusbar/power_60.png b/Data/system/service/Statusbar/assets/power_60.png similarity index 100% rename from Data/system/service/Statusbar/power_60.png rename to Data/system/service/Statusbar/assets/power_60.png diff --git a/Data/system/service/Statusbar/power_70.png b/Data/system/service/Statusbar/assets/power_70.png similarity index 100% rename from Data/system/service/Statusbar/power_70.png rename to Data/system/service/Statusbar/assets/power_70.png diff --git a/Data/system/service/Statusbar/power_80.png b/Data/system/service/Statusbar/assets/power_80.png similarity index 100% rename from Data/system/service/Statusbar/power_80.png rename to Data/system/service/Statusbar/assets/power_80.png diff --git a/Data/system/service/Statusbar/power_90.png b/Data/system/service/Statusbar/assets/power_90.png similarity index 100% rename from Data/system/service/Statusbar/power_90.png rename to Data/system/service/Statusbar/assets/power_90.png diff --git a/Data/system/service/Statusbar/sdcard.png b/Data/system/service/Statusbar/assets/sdcard.png similarity index 100% rename from Data/system/service/Statusbar/sdcard.png rename to Data/system/service/Statusbar/assets/sdcard.png diff --git a/Data/system/service/Statusbar/sdcard_alert.png b/Data/system/service/Statusbar/assets/sdcard_alert.png similarity index 100% rename from Data/system/service/Statusbar/sdcard_alert.png rename to Data/system/service/Statusbar/assets/sdcard_alert.png diff --git a/Data/system/service/Statusbar/wifi_off_white.png b/Data/system/service/Statusbar/assets/wifi_off_white.png similarity index 100% rename from Data/system/service/Statusbar/wifi_off_white.png rename to Data/system/service/Statusbar/assets/wifi_off_white.png diff --git a/Data/system/service/Statusbar/wifi_scan_white.png b/Data/system/service/Statusbar/assets/wifi_scan_white.png similarity index 100% rename from Data/system/service/Statusbar/wifi_scan_white.png rename to Data/system/service/Statusbar/assets/wifi_scan_white.png diff --git a/Data/system/service/Statusbar/wifi_signal_medium_white.png b/Data/system/service/Statusbar/assets/wifi_signal_medium_white.png similarity index 100% rename from Data/system/service/Statusbar/wifi_signal_medium_white.png rename to Data/system/service/Statusbar/assets/wifi_signal_medium_white.png diff --git a/Data/system/service/Statusbar/wifi_signal_strong_white.png b/Data/system/service/Statusbar/assets/wifi_signal_strong_white.png similarity index 100% rename from Data/system/service/Statusbar/wifi_signal_strong_white.png rename to Data/system/service/Statusbar/assets/wifi_signal_strong_white.png diff --git a/Data/system/service/Statusbar/wifi_signal_weak_white.png b/Data/system/service/Statusbar/assets/wifi_signal_weak_white.png similarity index 100% rename from Data/system/service/Statusbar/wifi_signal_weak_white.png rename to Data/system/service/Statusbar/assets/wifi_signal_weak_white.png diff --git a/Tactility/Include/Tactility/app/AppPaths.h b/Tactility/Include/Tactility/app/AppPaths.h index 694a54cb..621dd58a 100644 --- a/Tactility/Include/Tactility/app/AppPaths.h +++ b/Tactility/Include/Tactility/app/AppPaths.h @@ -17,37 +17,31 @@ public: explicit AppPaths(const AppManifest& manifest) : manifest(manifest) {} /** - * Returns the directory path for the data location for an app. - * The data directory is intended to survive OS upgrades. + * The user data directory is intended to survive OS upgrades. * The path will not end with a "/". */ - std::string getDataDirectory() const; + std::string getUserDataPath() const; /** - * Returns the full path for an entry inside the data location for an app. - * The data directory is intended to survive OS upgrades. + * The user data directory is intended to survive OS upgrades. * Configuration data should be stored here. * @param[in] childPath the path without a "/" prefix */ - std::string getDataPath(const std::string& childPath) const; + std::string getUserDataPath(const std::string& childPath) const; /** - * Returns the directory path for the system location for an app. - * The system directory is not intended to survive OS upgrades. * You should not store configuration data here. * The path will not end with a "/". * This is mainly used for core apps (system/boot/settings type). */ - std::string getSystemDirectory() const; + std::string getAssetsDirectory() const; /** - * Returns the full path for an entry inside the system location for an app. - * The data directory is not intended to survive OS upgrades. * You should not store configuration data here. * This is mainly used for core apps (system/boot/settings type). * @param[in] childPath the path without a "/" prefix */ - std::string getSystemPath(const std::string& childPath) const; + std::string getAssetsPath(const std::string& childPath) const; }; } \ No newline at end of file diff --git a/Tactility/Include/Tactility/service/ServicePaths.h b/Tactility/Include/Tactility/service/ServicePaths.h index 4f2b68c7..b9cbd524 100644 --- a/Tactility/Include/Tactility/service/ServicePaths.h +++ b/Tactility/Include/Tactility/service/ServicePaths.h @@ -17,37 +17,29 @@ public: explicit ServicePaths(std::shared_ptr manifest) : manifest(std::move(manifest)) {} /** - * Returns the directory path for the data location for a service. - * The data directory is intended to survive OS upgrades. + * The user data directory is intended to survive OS upgrades. * The path will not end with a "/". */ - std::string getDataDirectory() const; + std::string getUserDataDirectory() const; /** - * Returns the full path for an entry inside the data location for a service. - * The data directory is intended to survive OS upgrades. + * The user data directory is intended to survive OS upgrades. * Configuration data should be stored here. * @param[in] childPath the path without a "/" prefix */ - std::string getDataPath(const std::string& childPath) const; + std::string getUserDataPath(const std::string& childPath) const; /** - * Returns the directory path for the system location for a service. - * The system directory is not intended to survive OS upgrades. * You should not store configuration data here. * The path will not end with a "/". - * This is mainly used for core services. */ - std::string getSystemDirectory() const; + std::string getAssetsDirectory() const; /** - * Returns the full path for an entry inside the system location for an app. - * The data directory is not intended to survive OS upgrades. * You should not store configuration data here. - * This is mainly used for core apps (system/boot/settings type). * @param[in] childPath the path without a "/" prefix */ - std::string getSystemPath(const std::string& childPath) const; + std::string getAssetsPath(const std::string& childPath) const; }; } \ No newline at end of file diff --git a/Tactility/Source/app/AppPaths.cpp b/Tactility/Source/app/AppPaths.cpp index 1134c0a0..711e57db 100644 --- a/Tactility/Source/app/AppPaths.cpp +++ b/Tactility/Source/app/AppPaths.cpp @@ -2,36 +2,43 @@ #include #include +#include + +#include -#define LVGL_PATH_PREFIX std::string("A:/") #ifdef ESP_PLATFORM -#define PARTITION_PREFIX std::string("/") +constexpr auto PARTITION_PREFIX = std::string("/"); #else -#define PARTITION_PREFIX std::string("") +constexpr auto PARTITION_PREFIX = std::string(""); #endif namespace tt::app { -std::string AppPaths::getDataDirectory() const { +std::string AppPaths::getUserDataPath() const { if (manifest.appLocation.isInternal()) { - + return std::format("{}{}/app/{}", PARTITION_PREFIX, file::DATA_PARTITION_NAME, manifest.appId); + } else { + return std::format("{}/user/{}", file::getFirstPathSegment(manifest.appLocation.getPath()), manifest.appId); } - return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/app/" + manifest.appId; } -std::string AppPaths::getDataPath(const std::string& childPath) const { +std::string AppPaths::getUserDataPath(const std::string& childPath) const { assert(!childPath.starts_with('/')); - return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/app/" + manifest.appId + '/' + childPath; + return getUserDataPath() + '/' + childPath; } -std::string AppPaths::getSystemDirectory() const { - return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/app/" + manifest.appId; +std::string AppPaths::getAssetsDirectory() const { + if (manifest.appLocation.isInternal()) { + return std::format("{}{}/app/{}/assets", PARTITION_PREFIX, file::SYSTEM_PARTITION_NAME, manifest.appId); + } else { + return std::format("{}/assets", manifest.appLocation.getPath()); + } } -std::string AppPaths::getSystemPath(const std::string& childPath) const { +std::string AppPaths::getAssetsPath(const std::string& childPath) const { assert(!childPath.starts_with('/')); - return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/app/" + manifest.appId + '/' + childPath; + return std::format("{}/{}", getAssetsDirectory(), childPath); } } diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index d22dcd7f..cfff1a46 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -164,11 +164,11 @@ public: const char* logo; // TODO: Replace with automatic asset buckets like on Android if (getSmallestDimension() < 150) { // e.g. Cardputer - logo = hal::usb::isUsbBootMode() ? "assets/logo_usb.png" : "assets/logo_small.png"; + logo = hal::usb::isUsbBootMode() ? "logo_usb.png" : "logo_small.png"; } else { - logo = hal::usb::isUsbBootMode() ? "assets/logo_usb.png" : "assets/logo.png"; + logo = hal::usb::isUsbBootMode() ? "logo_usb.png" : "logo.png"; } - const auto logo_path = "A:" + paths->getSystemPath(logo); + const auto logo_path = "A:" + paths->getAssetsPath(logo); TT_LOG_I(TAG, "%s", logo_path.c_str()); lv_image_set_src(image, logo_path.c_str()); } diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index 4946e70e..ec4a0f8d 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -113,9 +113,9 @@ public: const int32_t margin = is_landscape_display ? std::min(available_width / 16, button_size) : 0; const auto paths = app.getPaths(); - const auto apps_icon_path = "A:" + paths->getSystemPath("assets/icon_apps.png"); - const auto files_icon_path = "A:" + paths->getSystemPath("assets/icon_files.png"); - const auto settings_icon_path = "A:" + paths->getSystemPath("assets/icon_settings.png"); + const auto apps_icon_path = "A:" + paths->getAssetsPath("icon_apps.png"); + const auto files_icon_path = "A:" + paths->getAssetsPath("icon_files.png"); + const auto settings_icon_path = "A:" + paths->getAssetsPath("icon_settings.png"); createAppButton(buttons_wrapper, ui_scale, apps_icon_path.c_str(), "AppList", margin); createAppButton(buttons_wrapper, ui_scale, files_icon_path.c_str(), "Files", margin); diff --git a/Tactility/Source/app/timezone/TimeZone.cpp b/Tactility/Source/app/timezone/TimeZone.cpp index c5fec8ae..33acf794 100644 --- a/Tactility/Source/app/timezone/TimeZone.cpp +++ b/Tactility/Source/app/timezone/TimeZone.cpp @@ -201,7 +201,7 @@ public: lv_obj_set_style_image_recolor_opa(icon, 255, 0); lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0); - std::string icon_path = "A:" + app.getPaths()->getSystemPath("search.png"); + std::string icon_path = "A:" + app.getPaths()->getAssetsPath("search.png"); lv_image_set_src(icon, icon_path.c_str()); lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0); diff --git a/Tactility/Source/service/ServicePaths.cpp b/Tactility/Source/service/ServicePaths.cpp index cdbf9b7f..eb5db903 100644 --- a/Tactility/Source/service/ServicePaths.cpp +++ b/Tactility/Source/service/ServicePaths.cpp @@ -3,32 +3,33 @@ #include #include -#define LVGL_PATH_PREFIX std::string("A:/") +#include +#include #ifdef ESP_PLATFORM -#define PARTITION_PREFIX std::string("/") +constexpr auto PARTITION_PREFIX = std::string("/"); #else -#define PARTITION_PREFIX std::string("") +constexpr auto PARTITION_PREFIX = std::string(""); #endif namespace tt::service { -std::string ServicePaths::getDataDirectory() const { - return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/service/" + manifest->id; +std::string ServicePaths::getUserDataDirectory() const { + return std::format("{}{}/service/{}", PARTITION_PREFIX, file::DATA_PARTITION_NAME, manifest->id); } -std::string ServicePaths::getDataPath(const std::string& childPath) const { +std::string ServicePaths::getUserDataPath(const std::string& childPath) const { assert(!childPath.starts_with('/')); - return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/service/" + manifest->id + '/' + childPath; + return std::format("{}/{}", getUserDataDirectory(), childPath); } -std::string ServicePaths::getSystemDirectory() const { - return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/service/" + manifest->id; +std::string ServicePaths::getAssetsDirectory() const { + return std::format("{}{}/service/{}/assets", PARTITION_PREFIX, file::SYSTEM_PARTITION_NAME, manifest->id); } -std::string ServicePaths::getSystemPath(const std::string& childPath) const { +std::string ServicePaths::getAssetsPath(const std::string& childPath) const { assert(!childPath.starts_with('/')); - return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/service/" + manifest->id + '/' + childPath; + return std::format("{}/{}", getAssetsDirectory(), childPath); } } diff --git a/Tactility/Source/service/gps/GpsConfiguration.cpp b/Tactility/Source/service/gps/GpsConfiguration.cpp index 63328ab7..e1414e54 100644 --- a/Tactility/Source/service/gps/GpsConfiguration.cpp +++ b/Tactility/Source/service/gps/GpsConfiguration.cpp @@ -17,12 +17,12 @@ bool GpsService::getConfigurationFilePath(std::string& output) const { return false; } - if (!file::findOrCreateDirectory(paths->getDataDirectory(), 0777)) { - TT_LOG_E(TAG, "Failed to find or create path %s", paths->getDataDirectory().c_str()); + if (!file::findOrCreateDirectory(paths->getUserDataDirectory(), 0777)) { + TT_LOG_E(TAG, "Failed to find or create path %s", paths->getUserDataDirectory().c_str()); return false; } - output = paths->getDataPath("config.bin"); + output = paths->getUserDataPath("config.bin"); return true; } diff --git a/Tactility/Source/service/statusbar/Statusbar.cpp b/Tactility/Source/service/statusbar/Statusbar.cpp index 2b8b1b32..2130f320 100644 --- a/Tactility/Source/service/statusbar/Statusbar.cpp +++ b/Tactility/Source/service/statusbar/Statusbar.cpp @@ -163,7 +163,7 @@ class StatusbarService final : public Service { bool show_icon = (gps_state == gps::State::OnPending) || (gps_state == gps::State::On); if (gps_last_state != show_icon) { if (show_icon) { - auto icon_path = "A:" + paths->getSystemPath(STATUSBAR_ICON_GPS); + auto icon_path = "A:" + paths->getAssetsPath(STATUSBAR_ICON_GPS); lvgl::statusbar_icon_set_image(gps_icon_id, icon_path); lvgl::statusbar_icon_set_visibility(gps_icon_id, true); } else { @@ -179,7 +179,7 @@ class StatusbarService final : public Service { const char* desired_icon = getWifiStatusIcon(radio_state, is_secure); if (wifi_last_icon != desired_icon) { if (desired_icon != nullptr) { - auto icon_path = "A:" + paths->getSystemPath(desired_icon); + auto icon_path = "A:" + paths->getAssetsPath(desired_icon); lvgl::statusbar_icon_set_image(wifi_icon_id, icon_path); lvgl::statusbar_icon_set_visibility(wifi_icon_id, true); } else { @@ -193,7 +193,7 @@ class StatusbarService final : public Service { const char* desired_icon = getPowerStatusIcon(); if (power_last_icon != desired_icon) { if (desired_icon != nullptr) { - auto icon_path = "A:" + paths->getSystemPath(desired_icon); + auto icon_path = "A:" + paths->getAssetsPath(desired_icon); lvgl::statusbar_icon_set_image(power_icon_id, icon_path); lvgl::statusbar_icon_set_visibility(power_icon_id, true); } else { @@ -212,7 +212,7 @@ class StatusbarService final : public Service { if (state != hal::sdcard::SdCardDevice::State::Timeout) { auto* desired_icon = getSdCardStatusIcon(state); if (sdcard_last_icon != desired_icon) { - auto icon_path = "A:" + paths->getSystemPath(desired_icon); + auto icon_path = "A:" + paths->getAssetsPath(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; diff --git a/Tactility/Source/service/wifi/WifiMock.cpp b/Tactility/Source/service/wifi/WifiMock.cpp index ceaba01f..1e45277c 100644 --- a/Tactility/Source/service/wifi/WifiMock.cpp +++ b/Tactility/Source/service/wifi/WifiMock.cpp @@ -1,24 +1,19 @@ -#include "Tactility/service/wifi/Wifi.h" - #ifndef ESP_PLATFORM -#include "Tactility/service/ServiceContext.h" +#include #include #include #include #include +#include +#include namespace tt::service::wifi { -#define TAG "wifi" -#define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 +constexpr auto* TAG = "Wifi"; struct Wifi { - Wifi() = default; - ~Wifi() = default; - /** @brief Locking mechanism for modifying the Wifi instance */ Mutex mutex = Mutex(Mutex::Type::Recursive); /** @brief The public event bus */ @@ -144,13 +139,13 @@ class WifiService final : public Service { public: - bool onStart(TT_UNUSED ServiceContext& service) final { + bool onStart(TT_UNUSED ServiceContext& service) override { tt_check(wifi == nullptr); wifi = new Wifi(); return true; } - void onStop(TT_UNUSED ServiceContext& service) final { + void onStop(TT_UNUSED ServiceContext& service) override { tt_check(wifi != nullptr); delete wifi; wifi = nullptr; diff --git a/TactilityC/Source/tt_app.cpp b/TactilityC/Source/tt_app.cpp index 1ee071a9..09471f9f 100644 --- a/TactilityC/Source/tt_app.cpp +++ b/TactilityC/Source/tt_app.cpp @@ -39,7 +39,7 @@ void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t* size assert(size != nullptr); assert(*size > 0); auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths(); - auto data_path = paths->getDataDirectory(); + auto data_path = paths->getUserDataPath(); auto expected_length = data_path.length() + 1; if (*size < expected_length) { TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", *size, expected_length); diff --git a/TactilityCore/Include/Tactility/file/File.h b/TactilityCore/Include/Tactility/file/File.h index dd84ffc1..e3bb94a3 100644 --- a/TactilityCore/Include/Tactility/file/File.h +++ b/TactilityCore/Include/Tactility/file/File.h @@ -83,6 +83,8 @@ std::string getChildPath(const std::string& basePath, const std::string& childPa std::string getLastPathSegment(const std::string& path); +std::string getFirstPathSegment(const std::string& path); + typedef int (*ScandirFilter)(const dirent*); typedef bool (*ScandirSort)(const dirent&, const dirent&); diff --git a/TactilityCore/Source/file/File.cpp b/TactilityCore/Source/file/File.cpp index 1fb5bf76..ce15e5bc 100644 --- a/TactilityCore/Source/file/File.cpp +++ b/TactilityCore/Source/file/File.cpp @@ -216,6 +216,19 @@ std::string getLastPathSegment(const std::string& path) { } } +std::string getFirstPathSegment(const std::string& path) { + if (path.empty()) { + return path; + } + auto start_index = path[0] == SEPARATOR ? 1 : 0; + auto index = path.find_first_of(SEPARATOR, start_index); + if (index != std::string::npos) { + return path.substr(0, index); + } else { + return path; + } +} + bool findOrCreateDirectory(const std::string& path, mode_t mode) { if (path.empty()) { return true;