add local app discovery: scan apps folder, render on home screen

This commit is contained in:
2026-01-19 13:20:21 +01:00
parent bb31dcee00
commit ad28cf2360
5 changed files with 466 additions and 3 deletions

View File

@@ -566,12 +566,93 @@ bool AppManager::DownloadFile(const std::string& url, const std::string& dest_pa
return false;
}
void AppManager::ScanAppsDirectory() {
std::string apps_dir = m_data_root + "/apps";
if (!fs::exists(apps_dir)) {
return;
}
LOG_INFO("Scanning apps directory: %s", apps_dir.c_str());
for (const auto& entry : fs::directory_iterator(apps_dir)) {
if (!entry.is_directory()) {
continue;
}
std::string package_id = entry.path().filename().string();
// Skip if already registered
if (m_installed_apps.find(package_id) != m_installed_apps.end()) {
continue;
}
// Look for manifest.json in direct folder or package/ subfolder
std::string manifest_path = entry.path().string() + "/manifest.json";
std::string manifest_path_pkg = entry.path().string() + "/package/manifest.json";
std::string actual_manifest;
std::string app_base_path;
if (fs::exists(manifest_path)) {
actual_manifest = manifest_path;
app_base_path = entry.path().string();
} else if (fs::exists(manifest_path_pkg)) {
actual_manifest = manifest_path_pkg;
app_base_path = entry.path().string() + "/package";
} else {
continue;
}
// Parse manifest
std::ifstream mf(actual_manifest);
if (!mf) {
continue;
}
try {
json j;
mf >> j;
InstalledApp app;
app.package_id = j.value("id", package_id);
app.name = j.value("name", package_id);
app.version_name = j.value("version", "1.0.0");
app.version_code = j.value("version_code", 1);
app.install_path = entry.path().string();
app.entry_point = j.value("entry", "main.rml");
app.icon_path = j.value("icon", "");
app.is_system_app = false;
if (j.contains("developer")) {
app.developer_name = j["developer"].value("name", "");
}
if (j.contains("permissions") && j["permissions"].is_array()) {
for (const auto& perm : j["permissions"]) {
app.permissions.push_back(perm.get<std::string>());
}
}
app.installed_at = std::chrono::system_clock::now();
app.updated_at = std::chrono::system_clock::now();
m_installed_apps[app.package_id] = app;
LOG_INFO("Discovered app: %s (%s)", app.name.c_str(), app.package_id.c_str());
} catch (const std::exception& e) {
LOG_WARN("Failed to parse manifest for %s: %s", package_id.c_str(), e.what());
}
}
}
void AppManager::LoadInstalledApps() {
std::string registry_path = m_data_root + "/config/apps.json";
std::ifstream file(registry_path);
if (!file) {
LOG_INFO("No existing app registry found");
LOG_INFO("No existing app registry found, scanning directory...");
ScanAppsDirectory();
return;
}
@@ -618,11 +699,15 @@ void AppManager::LoadInstalledApps() {
}
}
LOG_INFO("Loaded %zu installed apps", m_installed_apps.size());
LOG_INFO("Loaded %zu apps from registry", m_installed_apps.size());
} catch (const std::exception& e) {
LOG_ERROR("Error loading app registry: %s", e.what());
}
// Always scan directory to discover newly copied apps
ScanAppsDirectory();
LOG_INFO("Total installed apps: %zu", m_installed_apps.size());
}
void AppManager::SaveInstalledApps() {

View File

@@ -152,6 +152,9 @@ private:
void LoadInstalledApps();
void SaveInstalledApps();
// Directory scanning for app discovery
void ScanAppsDirectory();
// Directory size calculation
int64_t CalculateDirectorySize(const std::string& path) const;