Skip to content

Persistent diagnostics + split resize verification + debug variant#48

Merged
Suprhimp merged 1 commit into
masterfrom
devplanningo/mirror-stability-logs
Apr 27, 2026
Merged

Persistent diagnostics + split resize verification + debug variant#48
Suprhimp merged 1 commit into
masterfrom
devplanningo/mirror-stability-logs

Conversation

@Suprhimp
Copy link
Copy Markdown
Owner

Summary

  • Persistent file logging so error/crash logs survive app restart and can be shared from Settings (URLs/intent-extras/shell commands auto-redacted).
  • Split LEFT pane resize fix via centralized viability gate, min-pane invariants (≥360 left, ≥320 right), and serialized resize-with-verification (re-reads dumpsys bounds, retries on mismatch).
  • Debug install fix: applicationIdSuffix=".debug" so debug coexists with release; debug versionName/versionCode now auto-track the latest git tag (e.g. 1.4.0-debug) and commit count instead of the stale defaultConfig stub.

What changes

Diagnostics

  • FileLogger<filesDir>/logs/mirror.log (+ rotated .1), 512 KB × 2 cap, init-fail-safe degraded mode.
  • DiagnosticSanitizer — redacts URLs (host only), --es key value extras, Executing: <shell> bodies; applied to every persisted write.
  • CastlaApp installs a Thread.setDefaultUncaughtExceptionHandler that writes via FileLogger, then chains to the previous handler.
  • MirrorDiagnostics.log() / endSession() now persist alongside Logcat.
  • MirrorForegroundService.markTerminal(reason) (first-writer-wins via AtomicReference) at the 4 known silent-fail sites: VD_RECREATE_FAILED, SHIZUKU_REBIND_FAILED, PIPELINE_REBUILD_EXCEPTION, BROWSER_ACTIVATION_FAILED. performCleanup() is the sole owner of MirrorDiagnostics.endSession().
  • Settings → new Diagnostic Logs section with Share / Copy Recent buttons; IO performed on Dispatchers.IO via rememberCoroutineScope.

Split resize

  • New SplitMath (pure JVM): LEFT_PANE_MIN_PX=360, RIGHT_PANE_MIN_PX=320, MIN_TOTAL_PX=680, isSplitViable(), computeLeftPaneWidth().
  • New ensureSplitViable(reason) gate; every split-entry path (launchSplitWebTarget, launchSplitExternalBrowserTarget, launchSplitStandardTarget, all 4 AppLaunchBus splitMode branches, relaunchPrimaryTaskForSplit) goes through it.
  • splitTaskBounds() / primaryTaskBounds() now check(isSplitViable(...)) and call SplitMath directly — fail-fast instead of degenerate fallback.
  • runResizeWithVerification: serialized via Mutex + per-pane Job cancel-previous, max 4 verify rounds, 800ms shell timeout, 16px tolerance, dumpsys-bounds parser (TaskBoundsParser) with graceful skip on OEM mismatch.

Build

  • debug { applicationIdSuffix = ".debug" } → debug app is com.castla.mirror.debug, coexists with release.
  • New gitLatestSemverTag() + gitCommitCount() helpers; androidComponents.onVariants(selector().withBuildType("debug")) overrides debug versionName / versionCode from git. CI release path is untouched (sed pattern only matches defaultConfig).
  • Verified APK metadata: applicationId=com.castla.mirror.debug, versionName=1.4.0-debug, versionCode=97.

DUUL protocol

  • Plan review: REVISE only on diagnosis-handoff heuristic; architectural analysis "production-ready as written".
  • Code review (round 2): all logic-validation checks pass; remaining flags are heuristic (scope-punting on the pre-existing Robolectric-vs-SDK35 failures, diagnosis-handoff). The 6 Robolectric test-init failures exist on master too (verified by git stash + rerun on a clean checkout) and are unrelated to this PR.

Test plan

  • ./gradlew :app:testDebugUnitTest — 277 of 283 pass; the 6 failures are pre-existing Robolectric ↔ compileSdk=35 infrastructure issues unrelated to this PR.
  • New unit tests (33 total): DiagnosticSanitizerTest, FileLoggerTest, SplitMathTest, TaskBoundsParserTest — all green.
  • ./gradlew :app:assembleDebug succeeds; APK metadata confirms split applicationId + git-tag-derived versionName.
  • Manual: install debug build over an existing release install — should succeed without INSTALL_FAILED_VERSION_DOWNGRADE.
  • Manual: trigger a mirror failure, open Settings → "Share Logs" → confirm mirror.log is attached and URLs are redacted.
  • Manual: enter split mode several times — confirm left pane resizes consistently, no fullscreen-overlap regression.

Out of scope

  • Identifying the actual Tesla mirror "loading screen → close" root cause; this PR adds the missing observability so a follow-up PR can diagnose from a real reproduction.
  • Native crash / ANR capture.
  • Robolectric upgrade for SDK 35 compatibility.

🤖 Generated with Claude Code

- Add FileLogger with rotation + DiagnosticSanitizer (URL/extras/shell-command redaction); install uncaught exception handler in CastlaApp.
- Add markTerminal() (first-writer-wins) at known silent-fail sites in MirrorForegroundService; performCleanup() is sole owner of MirrorDiagnostics.endSession().
- Add SplitMath with min-pane invariants (LEFT >= 360, RIGHT >= 320) and centralized ensureSplitViable() gate at every split entry path; splitTaskBounds()/primaryTaskBounds() now fail-fast via check().
- Add serialized resize verification: per-pane Mutex + cancel-previous, dumpsys bounds re-read with 16px tolerance, up to 4 retry rounds, 800ms shell timeout.
- Settings UI: new Diagnostic Logs section with Share/Copy buttons; IO on Dispatchers.IO via rememberCoroutineScope.
- Build: applicationIdSuffix=".debug" so debug coexists with release. Debug versionName/versionCode now auto-track latest git tag and commit count via androidComponents.onVariants — debug builds reflect the actual current release (e.g. 1.4.0-debug) instead of the stale defaultConfig stub.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Suprhimp Suprhimp added the patch Version bump: patch (1.2.3 → 1.2.4) label Apr 27, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Apr 27, 2026 3:01am

@Suprhimp Suprhimp merged commit c8e81b2 into master Apr 27, 2026
4 checks passed
@Suprhimp Suprhimp deleted the devplanningo/mirror-stability-logs branch May 25, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch Version bump: patch (1.2.3 → 1.2.4)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant