fix Android: load shell.rml, add loadAppContent function, fallback to built-in apps

This commit is contained in:
2026-01-20 10:56:58 +01:00
parent 41fc6fdd86
commit 2134a53921
3 changed files with 188 additions and 39 deletions

70
install-device.bat Normal file
View File

@@ -0,0 +1,70 @@
@echo off
setlocal enabledelayedexpansion
echo ========================================
echo Mosis Device Installation Script
echo ========================================
echo.
:: Package name
set PACKAGE=com.omixlab.mosis
set DEVICE_APPS_DIR=files/apps
:: Step 1: Build and install APK
echo [1/3] Building and installing debug APK...
call gradlew installDebug
if errorlevel 1 (
echo ERROR: Failed to install APK
exit /b 1
)
echo.
:: Step 2: Push base-apps to temp location
echo [2/3] Pushing base-apps to temp location...
adb shell "rm -rf /data/local/tmp/mosis-apps" 2>nul
adb push base-apps /data/local/tmp/mosis-apps
if errorlevel 1 (
echo ERROR: Failed to push base-apps
exit /b 1
)
echo.
:: Step 3: Copy to private data using run-as
echo [3/3] Installing apps to internal storage...
echo Using run-as for /data/data/%PACKAGE%/%DEVICE_APPS_DIR%/
echo.
:: Create apps directory
adb shell "run-as %PACKAGE% mkdir -p %DEVICE_APPS_DIR%"
:: List of apps to install
for /d %%A in (base-apps\com.mosis.*) do (
set APP_ID=%%~nxA
echo Installing !APP_ID!...
:: Create app directory structure
adb shell "run-as %PACKAGE% mkdir -p %DEVICE_APPS_DIR%/!APP_ID!"
:: Copy files using tar through run-as (faster than individual files)
adb shell "cd /data/local/tmp/mosis-apps/!APP_ID! && tar cf - . | run-as %PACKAGE% tar xf - -C %DEVICE_APPS_DIR%/!APP_ID!/"
)
:: Cleanup temp files
echo.
echo Cleaning up temp files...
adb shell "rm -rf /data/local/tmp/mosis-apps"
echo.
echo ========================================
echo Installation complete!
echo ========================================
echo.
echo APK: %PACKAGE%
echo Apps: /data/data/%PACKAGE%/%DEVICE_APPS_DIR%/
echo.
echo Verify with:
echo adb shell "run-as %PACKAGE% ls -la %DEVICE_APPS_DIR%"
echo.
echo Launch with:
echo adb shell am start -n %PACKAGE%/.MainActivity
echo.

View File

@@ -385,17 +385,31 @@ function getAppColor(package_id)
return color
end
-- Built-in system apps (fallback when mosis.apps not available or empty)
local builtin_apps = {
{package_id = "com.mosis.browser", name = "Browser", icon = "../../icons/browser.tga"},
{package_id = "com.mosis.camera", name = "Camera", icon = "../../icons/camera.tga"},
{package_id = "com.mosis.contacts", name = "Contacts", icon = "../../icons/contacts.tga"},
{package_id = "com.mosis.dialer", name = "Phone", icon = "../../icons/phone.tga"},
{package_id = "com.mosis.messages", name = "Messages", icon = "../../icons/message.tga"},
{package_id = "com.mosis.music", name = "Music", icon = "../../icons/music.tga"},
{package_id = "com.mosis.settings", name = "Settings", icon = "../../icons/settings.tga"},
{package_id = "com.mosis.store", name = "Store", icon = "../../icons/store.tga"},
}
-- Populate home screen with discovered apps
function populateHomeApps()
if not mosis or not mosis.apps then
print("[Shell] mosis.apps not available")
return
local apps = nil
-- Try to get installed apps from mosis.apps API
if mosis and mosis.apps then
apps = mosis.apps.getInstalled()
end
local apps = mosis.apps.getInstalled()
-- Fall back to built-in apps if none discovered
if not apps or #apps == 0 then
print("[Shell] No apps discovered")
return
print("[Shell] Using built-in system apps")
apps = builtin_apps
end
print("[Shell] Populating home with " .. #apps .. " apps")
@@ -468,37 +482,48 @@ end
-- Launch a discovered app by package_id
function launchDiscoveredApp(package_id)
if not mosis or not mosis.apps then
print("[Shell] mosis.apps not available")
showToast("Cannot launch app", "error")
return
print("[Shell] Launching app: " .. package_id)
-- Check if it's a built-in system app
local app_id = package_id:gsub("com.mosis.", "")
local builtin_ids = {
browser = true, camera = true, contacts = true, dialer = true,
messages = true, music = true, settings = true, store = true
}
if builtin_ids[app_id] then
-- Use shellNavigateTo for built-in apps
return shellNavigateTo(app_id)
end
local apps = mosis.apps.getInstalled()
for _, app in ipairs(apps) do
if app.package_id == package_id then
print("[Shell] Launching discovered app: " .. package_id)
-- Try to find in installed apps
if mosis and mosis.apps then
local apps = mosis.apps.getInstalled()
for _, app in ipairs(apps) do
if app.package_id == package_id then
print("[Shell] Launching installed app: " .. package_id)
-- Push current to history
if current_app then
table.insert(nav_history, {
app_id = current_app,
app_path = current_app_path
})
print("[Shell] Pushed to history: " .. current_app .. " (depth: " .. #nav_history .. ")")
-- Push current to history
if current_app then
table.insert(nav_history, {
app_id = current_app,
app_path = current_app_path
})
print("[Shell] Pushed to history: " .. current_app .. " (depth: " .. #nav_history .. ")")
end
-- Build content path - convert entry.rml to entry_content.rml
local entry = app.entry_point or "main.rml"
local content_entry = entry:gsub("%.rml$", "_content.rml")
local content_path = "apps/" .. package_id:gsub("com.mosis.", "") .. "/" .. content_entry
-- Switch sandbox if available
if switchAppSandbox then
switchAppSandbox(package_id, app.install_path)
end
return loadAppContent_internal(package_id, content_path)
end
-- Build content path - convert entry.rml to entry_content.rml
local entry = app.entry_point or "main.rml"
local content_entry = entry:gsub("%.rml$", "_content.rml")
local content_path = "apps/" .. package_id:gsub("com.mosis.", "") .. "/" .. content_entry
-- Switch sandbox if available
if switchAppSandbox then
switchAppSandbox(package_id, app.install_path)
end
return loadAppContent_internal(package_id, content_path)
end
end

View File

@@ -20,6 +20,7 @@
#include <chrono>
#include <format>
#include <fstream>
#include <sstream>
#include <filesystem>
// Sandbox API includes for RmlUi integration
@@ -390,8 +391,8 @@ static int LuaGoHome(lua_State* L)
// Switch sandbox context back to home screen
SwitchAppSandbox("com.mosis.home", g_data_root);
// Load home screen
const char* home_path = "apps/home/home.rml";
// Load shell (which shows home by default)
const char* home_path = "apps/shell/shell.rml";
// Unload current document
if (g_document)
@@ -525,6 +526,57 @@ static int LuaSwitchAppSandbox(lua_State* L)
return 1;
}
// Load app content fragment into a container element
static int LuaLoadAppContent(lua_State* L)
{
// Get element from first argument
Rml::Element* element = Rml::Lua::LuaType<Rml::Element>::check(L, 1);
if (!element) {
Logger::Log("loadAppContent: Invalid element argument");
lua_pushboolean(L, false);
return 1;
}
// Get path from second argument
const char* path = luaL_checkstring(L, 2);
Logger::Log(std::format("loadAppContent: Loading {} into element", path));
// Read file content - try assets first, then filesystem
std::string content;
AAssetManager* am = AssetsManager::Native();
AAsset* asset = AAssetManager_open(am, path, AASSET_MODE_BUFFER);
if (asset) {
// Load from assets
size_t length = AAsset_getLength(asset);
const char* data = static_cast<const char*>(AAsset_getBuffer(asset));
content = std::string(data, length);
AAsset_close(asset);
Logger::Log(std::format(" -> Loaded {} bytes from assets", length));
} else {
// Try filesystem (for installed apps)
std::string fs_path = GetFilesDir() + "/" + path;
std::ifstream file(fs_path);
if (file.is_open()) {
std::stringstream buffer;
buffer << file.rdbuf();
content = buffer.str();
Logger::Log(std::format(" -> Loaded {} bytes from filesystem", content.size()));
} else {
Logger::Log(std::format("loadAppContent: Cannot open file: {}", path));
lua_pushboolean(L, false);
return 1;
}
}
// Set inner RML
element->SetInnerRML(content);
Logger::Log("loadAppContent: Content loaded successfully");
lua_pushboolean(L, true);
return 1;
}
// Register Lua functions for navigation
static void RegisterLuaFunctions(const std::string& current_app_id, bool is_system_app)
{
@@ -535,7 +587,9 @@ static void RegisterLuaFunctions(const std::string& current_app_id, bool is_syst
lua_setglobal(L, "goHome");
lua_pushcfunction(L, LuaSwitchAppSandbox);
lua_setglobal(L, "switchAppSandbox");
Logger::Log("Registered Lua loadScreen, goHome, and switchAppSandbox functions");
lua_pushcfunction(L, LuaLoadAppContent);
lua_setglobal(L, "loadAppContent");
Logger::Log("Registered Lua loadScreen, goHome, switchAppSandbox, and loadAppContent functions");
// Register app management APIs
if (g_app_manager && g_update_service) {
@@ -633,11 +687,11 @@ void Kernel::main_loop()
Rml::LoadFontFace("fonts/Roboto/Roboto-VariableFont_wdth,wght.ttf");
Rml::LoadFontFace("fonts/Roboto/Roboto-Italic-VariableFont_wdth,wght.ttf");
// Load home screen document
g_document = g_context->LoadDocument("apps/home/home.rml");
// Load shell document (provides persistent status bar, nav bar, and loads home content)
g_document = g_context->LoadDocument("apps/shell/shell.rml");
if (!g_document)
{
Logger::Log("Failed to load home.rml document");
Logger::Log("Failed to load shell.rml document");
Rml::Shutdown();
return;
}