Files
QuestAppLauncher/docs.md
oxmc7769 77799c1182
Some checks failed
Build / Build launcher (push) Has been cancelled
Move to JSON only, add examples
2026-03-18 09:30:23 -07:00

238 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Quest App Launcher — Documentation
## Table of Contents
1. [Overview](#overview)
2. [Architecture](#architecture)
3. [Configuration](#configuration)
4. [App Name Overrides](#app-name-overrides)
5. [Custom Icons](#custom-icons)
6. [Tab / Category System](#tab--category-system)
7. [Asset Auto-Update](#asset-auto-update)
8. [Managed Policies](#managed-policies)
9. [On-Device File Locations](#on-device-file-locations)
---
## Overview
Quest App Launcher is a VR home-screen replacement for Meta Quest 2. It lists all installed non-system apps in a scrollable grid, organized into tabs. Apps can be launched by pointing and clicking with the controller.
---
## Architecture
### Data Flow
1. **AppInfo.java** (Android plugin) — queries the Android package manager for installed apps, decodes icons as bitmaps, and reads usage statistics via `UsageStatsManager`.
2. **AppProcessor.cs** — calls the Java plugin over JNI, applies name overrides from `appnames*.json`, filters excluded packages, assigns apps to auto tabs (Quest / 2D), and returns a `ProcessedApp` dictionary.
3. **GridPopulation.cs** — takes the processed app list, sorts it (AZ or most-recently-used), builds tab containers, and instantiates `AppEntry` prefab tiles in the grid.
4. **AppEntry.cs** — represents a single icon tile. Lazy-loads and unloads its texture based on scroll position to keep memory use bounded.
### Key Scripts
| File | Role |
|------|------|
| `Assets/Scripts/AppProcessor.cs` | App discovery, name overrides, exclusion lists, icon loading |
| `Assets/Scripts/GridPopulation.cs` | Grid layout, tab assignment, sort order |
| `Assets/Scripts/AppEntry.cs` | Per-tile icon loading / unloading |
| `Assets/Scripts/Config.cs` | Settings model and JSON persistence |
| `Assets/Scripts/AssetsDownloader.cs` | Downloads icon packs and app name files from GitHub |
| `Assets/Scripts/SkyboxHandler.cs` | Background skybox selection and loading |
| `Assets/Scripts/SettingsHandler.cs` | Settings UI wiring |
| `Assets/Scripts/GlobalState.cs` | Cross-scene singleton (DontDestroyOnLoad) |
| `Assets/Plugins/Android/AppInfo.java` | Android interop layer |
---
## Configuration
Settings are stored in `config.json` in the app's persistent data path on-device. The file is created with defaults on first run. You can push a custom `config.json` via `adb`:
```
adb push config.json /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
```
### config.json fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `gridSize.rows` | int | 3 | Number of rows in the grid |
| `gridSize.cols` | int | 3 | Number of columns in the grid |
| `sortMode` | string | `"az"` | Sort order: `"az"` (alphabetical) or `"mostRecent"` |
| `show2D` | bool | `true` | Whether to show 2D (non-VR) apps |
| `autoCategory` | string | `"top"` | Where auto tabs appear: `"top"`, `"left"`, `"right"`, or `"off"` |
| `customCategory` | string | `"right"` | Where custom tabs appear: same options as above |
| `autoUpdate` | bool | `true` | Automatically check for and download asset updates |
| `background` | string | `"default"` | Background image path, or `"default"` for the built-in skybox |
| `downloadRepos` | array | GitHub default | List of repos to pull icon packs and app names from |
| `managedPolicyEndpoint` | string | `""` | URL to fetch managed policy JSON from (IT/MDM use) |
### Example config.json
```json
{
"gridSize": { "rows": 3, "cols": 4 },
"sortMode": "az",
"show2D": true,
"autoCategory": "top",
"customCategory": "right",
"autoUpdate": true,
"background": "default",
"downloadRepos": [
{ "repoUri": "hooverhigh/QuestAppLauncher_Assets/releases/latest", "type": "github" }
]
}
```
---
## App Name Overrides
Place `appnames.json` (or any `appnames*.json` file) in the persistent data path to rename apps and assign them to custom tabs.
### Format (`appnames.json`)
```json
{
"com.example.myapp": {
"Name": "My App",
"Category": "Games",
"Category2": "Favorites"
}
}
```
- **Name** — display name override (leave blank to keep the original name)
- **Category** / **Category2** — optional tab names (up to two per app)
### Pushing to the device
```
adb push appnames.json /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
```
---
## Custom Icons
Place `.jpg` files named `<packageName>.jpg` in the persistent data path, or bundle them into a zip file named `iconpack*.zip`.
### Individual icons
```
adb push com.example.myapp.jpg /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
```
### Icon packs (zip)
Create a zip containing `<packageName>.jpg` files at the root level:
```
iconpack_custom.zip
com.example.myapp.jpg
com.example.otherapp.jpg
```
```
adb push iconpack_custom.zip /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
```
The launcher extracts icon packs automatically on startup. Multiple icon packs are supported and applied in alphabetical order (later packs override earlier ones).
---
## Tab / Category System
### Auto tabs
Apps are automatically assigned to one of two built-in tabs based on their package metadata:
| Tab | Criteria |
|-----|----------|
| **Quest** | App declares the `android.hardware.vr.headtracking` feature, or any other VR app |
| **2D** | App has no VR features |
The **All** tab always shows every app regardless of category.
Auto tabs can be placed at the top, left, or right of the panel, or disabled entirely via `autoCategory` in `config.json`.
### Custom tabs
Assign apps to custom tabs using the `Category` / `Category2` fields in `appnames.json`. Custom tabs appear sorted alphabetically. Their position is controlled by `customCategory` in `config.json`.
---
## Asset Auto-Update
When `autoUpdate` is `true`, the launcher checks configured repos for updated icon packs and app name files on startup (rate-limited to once every 5 minutes). If updates are found, they are downloaded to the `download_cache` folder inside the persistent data path and the scene is reloaded.
### Adding a custom HTTP repo
In addition to GitHub releases, you can host assets on any plain HTTP server by providing a manifest JSON:
```json
{
"files": [
{ "name": "iconpack_school.zip", "url": "https://yourserver.com/iconpack_school.zip", "updatedAt": "2025-01-01T00:00:00Z" },
{ "name": "appnames.json", "url": "https://yourserver.com/appnames.json", "updatedAt": "2025-01-01T00:00:00Z" }
]
}
```
Add it to `downloadRepos` in `config.json`:
```json
{ "repoUri": "https://yourserver.com/manifest.json", "type": "http" }
```
---
## Managed Policies
For IT/MDM deployments, the launcher can fetch a policy JSON from a URL on every startup. Set `managedPolicyEndpoint` in `config.json` (or define `DEV_ENDPOINT` at compile time).
Supported policy fields:
| Field | Type | Description |
|-------|------|-------------|
| `hiddenApps` | string[] | Package names to hide from the launcher |
| `appNames` | object | Same format as `appnames.json` — name/category overrides |
| `disableSettings` | bool | Hides the settings button |
| `wallpaper` | string | URL to a background image (overrides user setting) |
---
## On-Device File Locations
All user-editable files live in the app's persistent data path:
```
/sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
```
| File / Folder | Purpose |
|---------------|---------|
| `config.json` | App settings |
| `appnames*.json` | App name and category overrides |
| `iconpack*.zip` | Custom icon packs |
| `*.jpg` | Individual icon overrides (`<packageName>.jpg`) |
| `excludedpackages.txt` | One package name per line — these apps are hidden |
| `download_cache/` | Downloaded icon packs and app name files (managed automatically) |
### Useful adb commands
```bash
# View Unity logs live
adb logcat -s Unity
# List files in persistent data path
adb shell ls /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
# Push a config file
adb push config.json /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/
# Pull all app data (for debugging)
adb pull /sdcard/Android/data/dev.oxmc.QuestAppLauncher/files/ ./device_files
```