Files
MosisService/CLAUDE.md

412 lines
12 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Mosis is a **virtual smartphone OS** for VR games and applications. It provides a phone-like device that users can interact with inside VR environments, with real smartphone functionality.
### Project Components
| Component | Location | Purpose |
|-----------|----------|---------|
| Android Service | `src/main/` | Native service running RmlUi renderer |
| Desktop Designer | `designer/` | UI development with hot-reload |
| Designer Tests | `designer-test/` | Automated UI testing framework |
| UI Assets | `src/main/assets/` | Shared RML/RCSS/Lua assets |
## Build Commands
### Android (Gradle)
```bash
# Build entire project
./gradlew build
# Build debug APK
./gradlew assembleDebug
# Build release APK
./gradlew assembleRelease
# Clean build outputs
./gradlew clean
# Build with verbose output
./gradlew build --info --stacktrace
# Run lint checks
./gradlew lint
# Run unit tests
./gradlew test
# Run connected device tests
./gradlew connectedAndroidTest
```
### Desktop Designer (CMake)
```bash
# Configure (from designer/ folder)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
# Build
cmake --build build --config Debug
# Run with hot-reload
./build/Debug/mosis-designer.exe ../src/main/assets/apps/home/home.rml
# Run with logging and hierarchy dump
./build/Debug/mosis-designer.exe ../src/main/assets/apps/home/home.rml --log output.log --hierarchy hierarchy.json
```
### Designer Tests (CMake)
```bash
# Configure (from designer-test/ folder)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
# Build
cmake --build build --config Debug
# Run tests
./build/Debug/designer-test.exe
```
## Environment Requirements
Required environment variables:
- `ANDROID_HOME` - Android SDK path
- `ANDROID_NDK_HOME` - Android NDK path (version 29.0.14206865)
- `VCPKG_ROOT` - vcpkg package manager root
## Architecture Overview
MosisService is an Android application combining Kotlin UI with native C++ libraries for UI rendering via Android's Binder IPC system.
### Two Native Libraries
**mosis-service** (`libmosis-service.so`):
- Main Android Binder service implementation
- Implements `IMosisService.aidl` interface for touch events and initialization
- Contains the Kernel rendering engine with RmlUi integration
- Links against RmlUi for HTML/CSS-like UI rendering
**mosis-test** (`libmosis-test.so`):
- Test/rendering client implementation
- Implements `IMosisListener.aidl` for receiving callbacks
- OpenGL ES 2.0 rendering pipeline using GLAD
### IPC Flow
```
Kotlin NativeService → JNI → mosis-service (IMosisService)
IMosisListener callbacks
mosis-test (rendering client)
```
### Key Interfaces (AIDL)
`IMosisService`: `initOS()`, `onTouchDown()`, `onTouchMove()`, `onTouchUp()`
`IMosisListener` (oneway/async): `onServiceInitialized()`, `onBufferAvailable()`, `onFrameAvailable()`
### Native Code Structure (src/main/cpp/)
- `kernel.cpp` - Core rendering engine, RmlUi integration, event processing
- `mosis-service.cpp` - Binder service implementation, JNI entry points
- `mosis-test.cpp` - Test client implementation
- `egl_context.cpp` - OpenGL ES context management
- `render_target.cpp` - Framebuffer and buffer management
- `RmlUi_Renderer_GL3.cpp` - RmlUi OpenGL renderer backend
- `assets_manager.cpp` - Android AssetManager integration
## Code Style
- C++23 standard with modern features (std::span, std::format)
- PascalCase for classes/functions, camelCase for variables
- RAII principles with smart pointers
- Kotlin code follows Android conventions
## Dependencies
- vcpkg manages native dependencies (RmlUi, GLFW, Freetype, Lua, libpng, nlohmann-json)
- CMake build system with vcpkg toolchain integration
- Android target architecture: arm64-v8a only
- Desktop target: Windows x64 (MSVC)
## Desktop Designer
The desktop designer (`designer/`) provides rapid UI development with:
- **Hot-reload**: Automatically reloads when RML/RCSS/Lua files change
- **UI Hierarchy Dumping**: Exports element tree to JSON for inspection
- **Screenshot Capture**: PNG export via F12 key
- **Logging**: Detailed output for debugging navigation and events
- **Action Recording**: Record mouse/keyboard interactions to JSON
- **Action Playback**: Replay recorded interactions with timing
### Key Files
| File | Purpose |
|------|---------|
| `designer/src/main.cpp` | Main entry point, GLFW window, event loop |
| `designer/src/desktop_kernel.cpp` | RmlUi context management, rendering |
| `designer/src/testing/ui_inspector.cpp` | UI hierarchy JSON export |
| `designer/src/testing/visual_capture.cpp` | PNG screenshot capture and comparison |
| `designer/src/testing/action_recorder.cpp` | Record user interactions to JSON |
| `designer/src/testing/action_player.cpp` | Playback recorded actions |
| `designer/src/backend/RmlUi_Backend_GLFW_GL3.cpp` | GLFW backend with input hooks |
### Command Line Options
```
--log <path> Write logs to file
--hierarchy <path> Dump UI hierarchy JSON each frame
--dump Single-shot dump mode (screenshot + hierarchy)
--record <path> Enable recording mode (F5 to start/stop)
--playback <path> Play back recorded actions from JSON
```
### Keyboard Controls
| Key | Function |
|-----|----------|
| F5 | Start/stop recording (when --record is enabled) |
| F6 | Pause/resume playback (when --playback is enabled) |
| F12 | Take screenshot |
## Automated Testing Framework
The designer-test (`designer-test/`) provides automated UI testing:
### Test Architecture
1. **WindowController**: Finds designer window, sends mouse/keyboard events via Windows SendInput API
2. **HierarchyReader**: Parses UI hierarchy JSON to find elements by ID/class
3. **LogParser**: Monitors log file for navigation events
4. **TestRunner**: Orchestrates test execution, reports results
### Writing Tests
```cpp
// Find element by ID and click it
bool ClickById(TestContext& ctx, const std::string& id) {
ctx.hierarchy.Reload();
auto element = ctx.hierarchy.FindById(id);
if (!element) return false;
int x = element->bounds.centerX();
int y = element->bounds.centerY();
ScaleToPhysical(ctx, x, y); // Convert logical to physical coords
ctx.window.SendClick(x, y);
return true;
}
// Test example
bool TestNavigateToDialer(TestContext& ctx) {
GoHome(ctx);
ctx.log.Clear();
if (!ClickById(ctx, "dock-phone")) return false;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
ctx.log.Reload();
return ctx.log.Contains("Loaded screen: apps/dialer/dialer.rml");
}
```
### Test Output
Tests produce JSON results at `test_results.json`:
```json
{
"name": "Mosis Designer UI Tests",
"summary": {"passed": 5, "failed": 0, "total": 5},
"tests": [
{"name": "Navigate to Dialer", "status": "passed", "duration_ms": 3500}
]
}
```
## UI Assets Structure
All UI assets are in `src/main/assets/`:
```
assets/
├── apps/ # System apps (RML documents)
│ ├── home/home.rml # Home screen launcher
│ ├── dialer/dialer.rml # Phone dialer
│ ├── messages/ # Messages app
│ ├── contacts/ # Contacts app
│ ├── settings/ # Settings app
│ └── browser/ # Web browser
├── ui/ # Shared stylesheets
│ ├── html.rcss # Base HTML element styles
│ ├── theme.rcss # Design tokens (colors, typography)
│ └── components.rcss # Reusable UI components
├── scripts/ # Lua scripts
│ └── navigation.lua # Navigation system
├── icons/ # TGA icon files (24x24, 32x32)
└── fonts/ # TTF fonts (LatoLatin, Roboto)
```
### Navigation System
Navigation is handled by `scripts/navigation.lua`:
```lua
-- Navigate to a screen
navigateTo('dialer') -- Push to history, animate forward
-- Go back
goBack() -- Pop from history, animate back
-- Go home
goHome() -- Clear history, return to home
```
### Element IDs for Testing
Key elements have IDs for automated testing:
| ID | Location | Purpose |
|----|----------|---------|
| `dock-phone` | home.rml | Phone dock icon |
| `dock-messages` | home.rml | Messages dock icon |
| `dock-contacts` | home.rml | Contacts dock icon |
| `dock-browser` | home.rml | Browser dock icon |
| `app-settings` | home.rml | Settings app icon |
### CSS Classes for Navigation
Back buttons use `app-bar-nav` class for automated GoHome:
```html
<div class="app-bar-nav btn-icon" onclick="goBack()">
<img src="../../icons/back.tga"/>
</div>
```
## Material Design Resources
Material Design icons and components are available in the MosisDesigner repository:
### Material Design Icons
**Location**: `D:\Dev\Mosis\MosisDesigner\material-design-icons`
A comprehensive icon library from Google with 2000+ icons across 20 categories:
| Category | Examples |
|----------|----------|
| action | home, search, settings, delete, info |
| alert | error, warning, notification |
| av | play, pause, volume, mic |
| communication | phone, message, email, contacts |
| content | add, remove, copy, paste |
| device | battery, wifi, bluetooth, gps |
| editor | format, text, color, brush |
| file | folder, attachment, download, upload |
| hardware | keyboard, mouse, phone, tablet |
| home | lightbulb, thermostat, security |
| image | camera, photo, filter, tune |
| maps | location, directions, navigation |
| navigation | arrow, chevron, menu, close |
| notification | sync, update, event |
| places | hotel, restaurant, airport |
| search | search variants |
| social | share, person, group, notifications |
| toggle | star, checkbox, radio |
**Available Formats**:
- `src/` - SVG source files organized by category
- `png/` - PNG files at multiple DPIs (24dp, 36dp, 48dp)
- `font/` - Icon fonts (WOFF, TTF)
- `symbols/` - Material Symbols variable font (newer)
- `variablefont/` - Variable font files
**Icon Styles**:
- Outlined (default)
- Filled
- Rounded
- Sharp
- Two-tone (Material Icons only)
### Material Design Lite
**Location**: `D:\Dev\Mosis\MosisDesigner\material-design-lite`
CSS/JS component library implementing Material Design (reference implementation):
| Directory | Contents |
|-----------|----------|
| `src/` | SASS source for components |
| `docs/` | Component documentation |
| `templates/` | Page templates |
**Key Components** (for design reference):
- Buttons (raised, flat, FAB)
- Cards
- Dialogs
- Lists
- Menus
- Navigation drawers
- Progress indicators
- Sliders
- Snackbars
- Tables
- Tabs
- Text fields
- Tooltips
### Using Icons in Mosis
1. **Find icon** at https://fonts.google.com/icons
2. **Export SVG** from `material-design-icons/src/<category>/<name>/`
3. **Convert to TGA** using image tool (24x24 or 32x32, RGBA)
4. **Place in** `src/main/assets/icons/`
5. **Reference in RML**: `<img src="../../icons/<name>.tga"/>`
## Android Device Testing
### Event Injection via ADB
Inject touch events for automated testing:
```bash
# Click at normalized coordinates (0.0-1.0)
adb shell am broadcast -a com.omixlab.mosis.INJECT_TOUCH \
--es touch_type "click" --ef x 0.5 --ef y 0.5
# Touch down
adb shell am broadcast -a com.omixlab.mosis.INJECT_TOUCH \
--es touch_type "down" --ef x 0.2 --ef y 0.9
# Touch up
adb shell am broadcast -a com.omixlab.mosis.INJECT_TOUCH \
--es touch_type "up" --ef x 0.2 --ef y 0.9
```
### Dock Element Coordinates (Normalized)
| Element | X | Y |
|---------|---|---|
| dock-phone | 0.16 | 0.97 |
| dock-messages | 0.39 | 0.97 |
| dock-contacts | 0.61 | 0.97 |
| dock-browser | 0.84 | 0.97 |
### Reading Logs
```bash
# Filter for Mosis logs
adb logcat -s MosisTest ServiceTester RMLUI
# Save to file
adb logcat -s MosisTest > mosis-log.txt
```