GAMA
com.popovicialinc.gama
Zapstore _@zapstore.dev Republished from GitHub / F-Droid by the Zapstore main account.
First release: Sep 22, 2026, 1 total release.
Most recent release: Sep 22, 2026.
Appears in 0 app stacks.
0 sats / 0 zaps received in the past year.
Sats Received
Underlying data available via MCP: app_zaps, app_releases.
Zap Count
Underlying data available via MCP: app_zaps, app_releases.
Releases
- Sep 22, 2026 1.4# GAMA v1.4 - Complete Detailed Changelog **From v1.3 to v1.4** **Scale of the change:** 34 → 67 main source files, ~14,600 → ~26,200 lines of app code; 0 → 4 translation files (~6,000 lines); 0 → 20 unit tests + 1 instrumentation test; 0 → full CI pipeline; 19 → 26 panel composables. --- ## 1. Architecture and code organisation
More…
- The v1.3 monoliths were broken up further: `GamaComponents.kt` (2,935 lines) shrank to 115 lines, its contents redistributed into `GamaCards.kt`, `GamaButtons.kt`, `GamaTitle.kt`, `GamaSelectors.kt`, `GamaPanelScaffold.kt`, `PanelButtons.kt`, `GamaAnimations.kt`, `GamaHaptics.kt`, `GamaModifiers.kt`. - New subsystems that did not exist in v1.3: `RendererState` / `RendererController` / `RendererSwitchStateMachine` / `RendererActionHistory` (renderer transaction core), `GamaLocalization` (i18n), `SettingsSearchPanel`, `SettingsHubPanel`, `TaskerAuth`, `ShizukuBackend`, `SupportBundle`, `OpenGLReminderWorker`, `GamaMatrixRain`. - Dialog layer split: v1.3's `GamaDialogs.kt` became `GamaDialog.kt` (base modal), `GamaDialogs.kt`, `InfoDialogs.kt`, `WarningDialogs.kt`, `ActionDialogs.kt`. - `GamaUI.kt` remains the largest file (4,391 lines) but is now mostly orchestration; all panels, cards, buttons, selectors, and animation primitives are extracted. --- ## 2. Navigation and panel framework - **New unified `PanelScaffold`.** In v1.3 every panel re-implemented its own backdrop, padding, back button, and scroll handling. v1.4 has one scaffold used by all panels: - Full-screen `BouncyDialog` container; content scroll resets to top on open. - **Dismissal:** tap-outside only (gated by the new `dismiss_on_click_outside` preference, default on), floating back button, or system back. There is no drag-to-dismiss. - **Sub-dialog layering:** when a child panel/dialog opens, the parent dims to 38% alpha (`tween 300 ms emphasizedDecelerate` in, `190 ms` out) and, on API 31+, gets GPU `Modifier.blur(20.dp)` - blur radius deliberately snaps rather than animating, to avoid rebuilding the RenderEffect every frame. API < 31 only dims. The panel is composed once (v1.3's double sharp+blur composition is gone). - **Layout constants:** back-button space reserved 120 dp (small screens) / 132 dp; horizontal padding 24 dp portrait, back-button-size + 48 dp landscape; content width capped 500 dp portrait / 800 dp landscape; card spacing 16/20 dp; status-bar inset padding; landscape two-column card grid. - **Root-panel exit cascade:** root panels hold their chrome 85 ms while cards leave top-first. - **Only one main panel open at a time** - v1.4 explicitly hides parents when a child is visible (`showSystem && !showNotifications && …`). v1.3 could stack panels visually. - **Back handling** is centralised in `GamaUI` with per-panel `BackHandler`s: 35 → 69 call sites, each restoring its logical parent (e.g. Particles sub-panels return to Particle Settings, System sub-panels to System). - **Floating buttons became a system** (`PanelButtons.kt`, 942 lines, new): - `PanelBackButton`, `PanelSearchButton`, `PanelGlobalButton`, plus the main-screen settings button. - **Gesture model:** tap = action; **hold 2,900 ms** = enter repositioning mode. A ring indicator appears after 500 ms and fills to 2,900 ms. While repositioning, the button follows the finger, snapped to an adaptive grid (4 vertical steps, 4–20 horizontal cells), with X clamped 0.04–0.96 full-width / 0.16–0.84 half-width and Y clamped 0.50–0.96. Position commits on release and persists (12 anchor coordinates: portrait/landscape × left/right/settings). - **Back-button avoidance (new):** cards with shadows/`avoidBackButton` detect overlap with the back button's footprint (radius = button/2 + 16 dp) and shrink their content to dodge it, spring-animated (damping 0.7, stiffness 300), with a 140 ms cooldown on the dodge/return haptics. Toggleable (`back_button_avoidance_enabled`, default on). - **Back-button inversion (new):** `back_button_inversed` swaps the back button and the leading Search/Global controls between sides. - "Reset floating button positions" action added to System. - **Settings hub (new):** v1.3's settings opened straight into a single Visuals panel. v1.4 has a hub with three sections - VISUALS, RENDERER, SYSTEM - each a card with title/description, leading into dedicated panels. --- ## 3. Settings search (entirely new) - Magnifier button in the settings hub opens a search panel with a **hard-coded catalog of 42 entries**: 10 panel shortcuts + 32 individual controls. - Each entry carries a localized title, keywords, a breadcrumb path (e.g. `SETTINGS → VISUALS → EFFECTS`), and **renders the real live control** - toggling a switch in search results changes the actual setting immediately, without navigating. - **Matching algorithm:** lowercase haystack + tokenisation, scored by: - whole-haystack substring 120, exact word 115, word prefix 96, word contains 82, first-3-chars 72, first-2-chars 54, else Levenshtein similarity ×82; threshold ≥45; max 8 results; 90 ms debounce. - **Navigation:** panel-shortcut results close search and open the panel; control results stay in place and mutate the setting. - **GLOBAL mode:** a globe button lists all 42 settings in a flattened list (only when the query is empty). - Keywords and titles are fully localized, so search works in the active language. --- ## 4. Localization (entirely new) - v1.3 was hard-locked to English (`localeFilters = ["en"]`). v1.4 ships **four languages**: English, Português (Brasil), Română, Tiếng Việt. - New runtime localization engine: JSON dictionaries parsed from assets, English fallback per key, cached, with a composition-local `LocalStrings` and a blocking lookup for non-Compose surfaces (notifications, tiles, workers). - **Language panel:** searchable list (name/native name/code), flag, native name with English subtitle, animated "Active" badge, accent bar; switching applies instantly with no restart, persists (`selected_language`), and fires a dedicated "language signature" haptic. - Localized: all panels, settings search, notifications, QS tile label, dialogs, settings keywords. --- ## 5. Renderer experience (rebuilt) **State machine (new):** every switch is a transaction with phases `IDLE → REQUESTED → APPLYING → VERIFYING → VERIFIED → COMPLETE`, or `FAILED` with a reason. Illegal transitions throw; a completed transaction cannot fail. A process-wide mutex serializes switches, and the whole transaction runs in `NonCancellable` so a SystemUI restart can't split the prop write from the persisted state commit. **Verification (new):** after `setprop debug.hwui.renderer skiavk|opengl`, GAMA reads the property back and only accepts the switch if it matches (with a special case where the shell prints "Success" for the OpenGL default). The durable state (`last_renderer`, `desired_renderer`, `last_switch_time`, `last_switch_uptime`, `last_switch_boot_time`) is written with synchronous `commit()` *before* any restart can kill the process. Unverified switches never update state or history. **Action history (new):** the renderer card shows the last action with source and result - `Last action succeeded · <source>: <detail>` (red on failure). Sources: **GAMA, Quick Settings, Boot restore, Tasker**. Detail strings are localized for the six known outcomes; detail is capped at 500 chars. Only the most recent action is kept. The separate "Graphics API last changed Xm ago" label is driven by `last_switch_time` with buckets just now / minutes / hours / yesterday / days. **Backends:** - Shizuku and root are both supported; root (`su -c`, cached 30 s, `su -c id` must contain `uid=0`) takes precedence, with fall-through to Shizuku if a root command errors. Root is only probed after explicit user action so Magisk/KernelSU prompts don't appear randomly. - **Shevery (new):** detected as an optional Shizuku-compatible manager (`com.hamondev.shevery`); official Shizuku always wins when both are installed. Execution still uses the upstream Shizuku protocol. Android 11+ `<queries>` added for both packages. - Renderer detection is a three-source chain: the prop itself → `getprop | grep -Ei 'hwui|renderer'` → `dumpsys hwui`; "Unknown" only if all three fail. - Shell timeouts 3 s; large-output commands (package list, dropbox) use concurrent stream draining with 30 s timeouts to avoid pipe deadlocks on MIUI. **Switch side effects (options):** aggressive mode (`am force-stop` for all third-party packages except a large protected list), restart launcher + System UI (with a 15 s SystemUI cooldown, skipped on MIUI/Xiaomi), restart keyboard on switch (captures and restores the IME), all off by default. Tasker-triggered switches always force launcher/keyboard restarts off. **Quick Settings:** v1.3's three separate tiles (Vulkan, OpenGL, Doze) were replaced by **one "GAMA · Renderer" toggle tile**. Subtitle shows `Vulkan · tap for OpenGL` / `OpenGL · tap for Vulkan`, "Switching…", "Failed - tap to retry", or "<backend> isn't running". The tile never triggers a root prompt; it uses only cached backend state and refreshes via `requestListeningState` after every verified switch. **Boot restore (reworked):** v1.3's WorkManager pipeline was extended with a separate **desired** vs **actual** renderer, boot-time drift detection (5-minute tolerance, legacy 12-hour window), and a distinct "restore unavailable" record so a failed boot restore no longer lies about the active renderer. Receiver accepts BOOT_COMPLETED and both QUICKBOOT_POWERON variants; initial delay 20 s, exponential backoff from 30 s, max 5 attempts, Shizuku wait up to 90 s polling every 2 s. Posts a `gama_boot` (IMPORTANCE_LOW, ID 3001) success/failure notification when permitted. **Tasker (rebuilt security):** v1.3 used a custom manifest permission (`TASKER_PERMISSION`, protection level normal). v1.4 uses a **256-bit capability token**: 32 `SecureRandom` bytes → 43-char URL-safe Base64, stored in a separate `tasker_auth` prefs file, validated with constant-time comparison. Broadcast contract: action `com.popovicialinc.gama.ACTION_SET_RENDERER` with extras `renderer=vulkan|opengl`, `token=…`, optional `aggressive=true|false`. Unauthorized calls are silently dropped; work is enqueued as unique `REPLACE` work outside the receiver's ANR window. The Library panel shows the token with a "Copy token" button (clip flagged sensitive on Android 13+) and links the PDF guide. **Reminders (reworked):** v1.3's in-app 15-minute loop became a real periodic WorkManager job (`gama_opengl_reminder`, 15-minute period, `UPDATE` policy), which only fires when the actual renderer is OpenGL *and* the desired renderer is OpenGL (so intentional OpenGL users aren't nagged). Intervals 2/4/6/12/24 h (default 6 h), channel `gama_reminder_channel` (ID 2001), five randomized personalized messages using your name, plus a "Send test alert" preview in the Alerts panel. --- ## 6. Animation system - **MotionTokens expanded.** v1.3 already had durations/easings/springs; v1.4 adds `enter`, `exit`, and `overshoot` beziers, a `snapBack` spring (0.72/600), a retuned spring set, and a new **`SpeedUtil`** that scales every duration and stiffness. - **New animation speed control:** Slow / Normal / Fast (default Normal). Slow = base × 1.5 (cap 9 s), Fast = base × 0.7 (floor 50 ms), stiffness ×0.8/×1.2. This is a second axis on top of the existing Full / Reduced / Off level: Reduced swaps springs for 210 ms tweens, Off snaps everything. - **Motion usage roughly tripled:** token references 106 → 321; tween/spring/keyframe calls 97 → 183; `Crossfade` 0 → 11; `AnimatedVisibility` 7 → 18; `graphicsLayer` 67 → 122; glow/shadow references 66 → 183. - **Stagger** (`AnimatedElement`): enter delay 60 ms per index (was 95 ms), enter duration 420/300 ms (was 680/460 ms), exit cascades top-first at 18 ms for root panels and reverse at 22 ms for sub-panels; can be disabled (`stagger_enabled`, default on). - **Press physics:** dedicated `pressDown` (0.92/1500, no bounce) and `pressUp` (0.46/440, one clean overshoot) springs drive all interactive cards/buttons; press scale 0.97. - **Card shadows** are now a live animated system (`directionalShadow`): black 18%, offset 4/6 dp, blur 12 dp, corner 28 dp, alpha driven by the card's own reveal progress, 180 ms fade when enabled and instant off when disabled; global toggle (new, default on, forced off in dark/OLED). - **Panels/dialogs:** BouncyDialog enter scale 0.88→1 with a 0.42/190 spring (full), 210 ms tween (reduced), snap (off); exit 0.78 in 170 ms with an optional 105 ms root-panel delay. Panel chrome fades, zooms 0.94→1, and lifts 20/8/0 dp by level. - **Titles:** CleanTitle's one-shot shimmer now plays **once per install** (`title_shimmer_played` persisted), 900 ms silk tween after a 250 ms delay, with a 35%-wide band sweeping outward on both 4 dp gradient bars; titles also parallax at 0.4× scroll. The main-screen GAMA wordmark keeps its glow layers and chromatic-aberration fringes (red shifted left, blue shifted right) and long-press easter egg. - **Selectors:** `GlideOptionSelector` indicator is anchored to the selected stop (spring 0.78/220, or 430 ms velvet on reduced), options select on touch-down and follow the finger while held; disabled state scales to 0.80 and blocks touches. --- ## 7. Haptics (rebuilt into a system) v1.3 had inline, ad-hoc haptics. v1.4 has a dedicated feedback layer (references 307 → 898) with **six independent categories**, each with its own toggle and 0–100 strength, all default on: | Category | Default strength | Pattern | |---|---|---| | Regular clicks (contact/selection/press) | 58 | 12–16 ms one-shots, amplitude interpolated 36–138 | | Hold-release bloom | 82 | 4-segment bloom on hold; 7-segment fading tail on release | | Renderer actions | 68 | 18 ms contact; 4-segment commit waveform | | Language change | 70 | 6-segment signature: contact → bloom → tail | | Dodge left | 38 | 8/26 ms double tick | | Return settle | 66 | 16/30 ms double tick | - Master "Haptics engine" switch; per-category previews and a "Test haptics here" press pad; "Restore default profile" action. - **Hold-release threshold 230 ms:** quick taps produce exactly one contact pulse; the release tail only fires after a real hold. A **110 ms suppression window** prevents a generic click from firing on top of a recent surface haptic. - Strengths interpolate between min/max amplitudes per pattern; graceful fallback to platform haptic constants (`CLOCK_TICK`, `CONTEXT_CLICK`, `LONG_PRESS`, `CONFIRM`, `REJECT`) if vibration effect creation fails. --- ## 8. Visual effects **Particles (expanded):** master toggle; Stars/Matrix style selector; Time Mode (sun/moon by real clock) and Star Mode toggles; Speed (Slow 1× / Medium 3× / Fast 6×); Parallax with Low/Medium/High sensitivity (rotation-vector sensor, 10-sample calibration, low-pass filter); Count Low/Medium/High = 75/150/300 with silent RAM-based caps (50/100/150 on ≤1/2/3 GB devices); Refresh Rate Native / 1/2 / 1/4 controlling both physics and sensor polling (physics clamped 8–144 Hz); celestial bodies with time-of-day arcs and landscape-tuned trajectories. **Matrix rain (new):** discrete row-stepping katakana/digit/Latin rain with three depth layers (30% far, 40% mid, 30% near), per-column speed variation, glyph mutation, a 64-entry color LUT with quadratic tail fade, and a fake bloom pass (three scaled draws instead of BlurMaskFilter). Controls: Speed (Slow/Medium/Fast ≈ 7.5/15/30 rows/s), Density (Sparse/Medium/Dense column widths), Glyph size (11/15/20 sp), Trail length (22%/55%/full), plus preference-only background opacity. Colors derive from the accent/dynamic color and animate on theme changes without resetting the rain. **Theme:** OLED is now the dark theme itself (no separate OLED toggle); legacy `oled_mode`/`oled_accent_color`/`use_dynamic_color_oled` are migrated and removed. Themes Auto/Dark/Light, dynamic Material You color (API 31+), hex color picker (new), accent/gradient pickers, gradient background (unavailable in dark/OLED), UI scale 75/100/125%, card shadows toggle, animation level + speed, stagger, back-button avoidance/inversion, tap-outside-to-close, and "your name" for greetings/notifications. --- ## 9. Settings inventory (v1.4, by panel) - **VISUALS:** Effects (blur, card shadows, particles entry), Colors (dynamic color, hex picker, accent), Background gradient (toggle, start/end colors), Theme, Animations, UI Scale, Stagger, Back-button avoidance, Your Name. - **RENDERER:** Aggressive mode (warning dialog with "don't show again"), Restart launcher & System UI, Restart keyboard on switch, GPUWatch shortcut. - **SYSTEM:** Haptics, Alerts, Backup & Restore, Language, Logs, Verbose output, Tap outside to close, Back button position (Normal/Inverted), Reset floating button positions. - **PARTICLES:** master toggle, style, Shape & Look, Motion, Performance, Matrix glyph/motion sub-panels. - **ALERTS:** permission card with grant button, reminders toggle (context-aware description), interval selector, test alert. - **HAPTICS:** engine toggle, Core Feel, Layout Motion, per-category strength cards with live preview, reset profile. - **LANGUAGE:** searchable language list with flags/native names and instant switching. - **LIBRARY:** GitHub, Discord, Shizuku cards; Tasker setup card with token; Quick Settings tile card; GPUWatch lives in Renderer settings. - **LOGS:** GAMA crash logs (parsed, save/view/clear) and system crash/ANR logs via `dumpsys dropbox` (50 fetched, 20 shown, privacy warning on export), plus support-bundle export. --- ## 10. Diagnostics and backup - **Crash logging** (v1.3 had a basic file) now has a dedicated panel with parsed entries (timestamp, thread, summary, full text), per-entry save, clear-all, and a system-crash list via root/Shizuku. - **Support bundle (new):** app version, device model, Android version, current/desired renderer, backend state (root/binder/permission), last renderer action, and the last 12,000 chars of the crash log - exported as `GAMA_support_yyyy-MM-dd_HH-mm.txt` via the system file picker. - **Backup/restore reworked:** versioned JSON schema (v1.3 = v1, v1.4 = v2), per-key type validation, invalid entries skipped rather than aborting, string-set caps (512 items × 256 chars), device-specific state deliberately excluded (uptime, last-sent reminder, permission-requested flag, first-launch cosmetics), 1 MB import cap. v1.3 backups import cleanly (verified by round-trip test); settings for removed/renamed features are ignored. --- ## 11. Build, security, tests, CI - `targetSdk` 35 → 36; Kotlin 2.0.21 → 2.2.10; AGP 9.0.0 → 9.2.1. - **Signing credentials removed from source** (v1.3 hardcoded keystore path, alias, and passwords in `build.gradle.kts`); now read from a gitignored `keystore.properties` or env vars, with release builds working unsigned when absent (needed for F-Droid). - Release builds are now **minified and obfuscated** with targeted keep rules (v1.3 shipped `-dontobfuscate` plus a blanket keep of the whole app). - **Tests (new):** 20 JVM tests (backup round-trip/validation, renderer state, state machine, support bundle) + an instrumentation launch test; CI builds, lints, unit-tests, and smoke-tests on emulator API 29–36. - Permissions trimmed: no INTERNET, no REQUEST_INSTALL_PACKAGES. --- ## 12. Removed - Home-screen widget (Glance) and its configuration sheet/theme picker. - Doze Quick Settings tile and the separate Vulkan/OpenGL tiles (→ one toggle tile). - Separate OLED toggle (merged into dark theme). - v1.3's custom Tasker permission (→ token). --- ## 13. Compatibility - Update from v1.3 installs directly (same signing identity), and v1.3 backups restore into v1.4.