diff --git a/Tactility/Include/Tactility/Paths.h b/Tactility/Include/Tactility/Paths.h index 1b24abf3..005bd6e5 100644 --- a/Tactility/Include/Tactility/Paths.h +++ b/Tactility/Include/Tactility/Paths.h @@ -1,8 +1,21 @@ -// -// Created by ken on 20/09/2025. -// +#pragma once -#ifndef TACTILITY_PATHS_H -#define TACTILITY_PATHS_H +#include -#endif //TACTILITY_PATHS_H +namespace tt { + +bool findFirstMountedSdCardPath(std::string& path); + +std::string getSystemRootPath(); + +std::string getTempPath(); + +std::string getAppInstallPath(); + +std::string getAppInstallPath(const std::string& appId); + +std::string getUserPath(); + +std::string getAppUserPath(const std::string& appId); + +} diff --git a/Tactility/Include/Tactility/app/App.h b/Tactility/Include/Tactility/app/App.h index cf98611b..d38ad473 100644 --- a/Tactility/Include/Tactility/app/App.h +++ b/Tactility/Include/Tactility/app/App.h @@ -94,9 +94,7 @@ std::shared_ptr _Nullable getCurrentAppContext(); /** @return the currently running app (it is only ever null before the splash screen is shown) */ std::shared_ptr _Nullable getCurrentApp(); -std::string getTempPath(); - -std::string getInstallPath(); +bool isValidId(const std::string& id); bool install(const std::string& path); diff --git a/Tactility/Include/Tactility/app/AppManifest.h b/Tactility/Include/Tactility/app/AppManifest.h index 63f74d5f..17892dba 100644 --- a/Tactility/Include/Tactility/app/AppManifest.h +++ b/Tactility/Include/Tactility/app/AppManifest.h @@ -72,6 +72,15 @@ struct AppManifest { /** Optional icon. */ std::string icon = {}; + /** Optional description */ + std::string description = {}; + + /** Optional author name */ + std::string authorName = {}; + + /** Optional author website */ + std::string authorWebsite = {}; + /** App category helps with listing apps in Launcher, app list or settings apps. */ Category category = Category::User; diff --git a/Tactility/Source/Paths.cpp b/Tactility/Source/Paths.cpp index 376ce540..de7aee0a 100644 --- a/Tactility/Source/Paths.cpp +++ b/Tactility/Source/Paths.cpp @@ -1,3 +1,54 @@ -// -// Created by ken on 20/09/2025. -// +#include + +#include +#include +#include + +namespace tt { + +bool findFirstMountedSdCardPath(std::string& path) { + // const auto sdcards = hal::findDevices(hal::Device::Type::SdCard); + bool is_set = false; + hal::findDevices(hal::Device::Type::SdCard, [&is_set, &path](const auto& device) { + if (device->isMounted()) { + path = device->getMountPath(); + is_set = true; + return false; // stop iterating + } else { + return true; + } + }); + return is_set; +} + +std::string getSystemRootPath() { + std::string root_path; + if (!findFirstMountedSdCardPath(root_path)) { + root_path = file::MOUNT_POINT_DATA; + } + return root_path; +} + +std::string getTempPath() { + return getSystemRootPath() + "/tmp"; +} + +std::string getAppInstallPath() { + return getSystemRootPath() + "/app"; +} + +std::string getUserPath() { + return getSystemRootPath() + "/user"; +} + +std::string getAppInstallPath(const std::string& appId) { + assert(app::isValidId(appId)); + return std::format("{}/{}", getAppInstallPath(), appId); +} + +std::string getAppUserPath(const std::string& appId) { + assert(app::isValidId(appId)); + return std::format("{}/app/{}", getUserPath(), appId); +} + +} \ No newline at end of file diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index f56decf7..9c7dd4be 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -194,7 +194,7 @@ static void registerInstalledApps(const std::string& path) { static void registerInstalledAppsFromSdCard(const std::shared_ptr& sdcard) { auto sdcard_root_path = sdcard->getMountPath(); - auto app_path = std::format("{}/apps", sdcard_root_path); + auto app_path = std::format("{}/app", sdcard_root_path); sdcard->getLock()->lock(); if (file::isDirectory(app_path)) { registerInstalledApps(app_path); diff --git a/Tactility/Source/app/App.cpp b/Tactility/Source/app/App.cpp index 806b2be5..0d929bf2 100644 --- a/Tactility/Source/app/App.cpp +++ b/Tactility/Source/app/App.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -19,4 +20,9 @@ std::shared_ptr _Nullable getCurrentApp() { return service::loader::getCurrentApp(); } +bool isValidId(const std::string& id) { + const auto pattern = std::regex("^[a-zA-Z0-9_-\\.]+$"); + return std::regex_match(id, pattern); +} + } diff --git a/Tactility/Source/app/AppInstall.cpp b/Tactility/Source/app/AppInstall.cpp index 61ee3f33..db660843 100644 --- a/Tactility/Source/app/AppInstall.cpp +++ b/Tactility/Source/app/AppInstall.cpp @@ -1,3 +1,5 @@ +#include "Tactility/Paths.h" + #include #include @@ -103,44 +105,13 @@ static bool untar(const std::string& tarPath, const std::string& destinationPath return success; } -bool findFirstMountedSdCardPath(std::string& path) { - // const auto sdcards = hal::findDevices(hal::Device::Type::SdCard); - bool is_set = false; - hal::findDevices(hal::Device::Type::SdCard, [&is_set, &path](const auto& device) { - if (device->isMounted()) { - path = device->getMountPath(); - is_set = true; - return false; // stop iterating - } else { - return true; - } - }); - return is_set; -} - -std::string getTempPath() { - std::string root_path; - if (!findFirstMountedSdCardPath(root_path)) { - root_path = file::MOUNT_POINT_DATA; - } - return root_path + "/tmp"; -} - -std::string getInstallPath() { - std::string root_path; - if (!findFirstMountedSdCardPath(root_path)) { - root_path = file::MOUNT_POINT_DATA; - } - return root_path + "/apps"; -} - bool install(const std::string& path) { // TODO: Make better: lock for each path type properly (source vs target) // We lock and unlock frequently because SPI SD card devices share // the lock with the display. We don't want to lock the display for very long. - auto app_parent_path = getInstallPath(); + auto app_parent_path = getAppInstallPath(); TT_LOG_I(TAG, "Installing app %s to %s", path.c_str(), app_parent_path.c_str()); auto lock = file::getLock(app_parent_path)->asScopedLock(); @@ -225,8 +196,8 @@ bool install(const std::string& path) { bool uninstall(const std::string& appId) { TT_LOG_I(TAG, "Uninstalling app %s", appId.c_str()); - auto app_path = getInstallPath() + "/" + appId; - return file::withLock(app_path, [&app_path, &appId]() { + auto app_path = getAppInstallPath(appId); + return file::withLock(app_path, [&app_path, &appId] { if (!file::isDirectory(app_path)) { TT_LOG_E(TAG, "App %s not found at ", app_path.c_str()); return false; diff --git a/Tactility/Source/hal/sdcard/SdCardMounting.cpp b/Tactility/Source/hal/sdcard/SdCardMounting.cpp index 1a3079e0..e66b4a1e 100644 --- a/Tactility/Source/hal/sdcard/SdCardMounting.cpp +++ b/Tactility/Source/hal/sdcard/SdCardMounting.cpp @@ -15,24 +15,18 @@ static void mount(const std::shared_ptr& sdcard, const std::string }); } +static std::string getMountPath(int index, int count) { + return (count == 1) ? TT_SDCARD_MOUNT_POINT : std::format("{}{}", TT_SDCARD_MOUNT_POINT, index); +} + void mountAll() { auto sdcards = hal::findDevices(Device::Type::SdCard); - if (!sdcards.empty()) { - if (sdcards.size() == 1) { - // Fixed mount path name - auto sdcard = sdcards[0]; - if (!sdcard->isMounted()) { - mount(sdcard, TT_SDCARD_MOUNT_POINT); - } - } else { - // Numbered mount path name - for (int i = 0; i < sdcards.size(); i++) { - auto sdcard = sdcards[i]; - if (!sdcard->isMounted()) { - std::string mount_path = TT_SDCARD_MOUNT_POINT + std::to_string(i); - mount(sdcard, mount_path); - } - } + // Numbered mount path name + for (int i = 0; i < sdcards.size(); i++) { + auto sdcard = sdcards[i]; + if (!sdcard->isMounted() && sdcard->getMountBehaviour() == SdCardDevice::MountBehaviour::AtBoot) { + std::string mount_path = getMountPath(i, sdcards.size()); + mount(sdcard, mount_path); } } } diff --git a/Tactility/Source/service/development/DevelopmentService.cpp b/Tactility/Source/service/development/DevelopmentService.cpp index 889ad15f..ae1a22a8 100644 --- a/Tactility/Source/service/development/DevelopmentService.cpp +++ b/Tactility/Source/service/development/DevelopmentService.cpp @@ -4,10 +4,10 @@ #include #include -#include #include #include #include +#include #include #include #include @@ -247,7 +247,7 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) { } content_left -= content_read; - const std::string tmp_path = app::getTempPath(); + const std::string tmp_path = getTempPath(); auto lock = file::getLock(tmp_path)->asScopedLock(); lock.lock();