Skip to content

feat: Verification Deep Dive — Local Hosting Simulation + review fixes - #28

Merged
manjees merged 3 commits into
mainfrom
solve/issue-12
May 14, 2026
Merged

feat: Verification Deep Dive — Local Hosting Simulation + review fixes#28
manjees merged 3 commits into
mainfrom
solve/issue-12

Conversation

@manjees

@manjees manjees commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Verification Deep Dive — Local Hosting Simulation (feat: Verification Deep Dive - Local Hosting Simulation #12): local Ktor server hosts a generated assetlinks.json so developers can pre-flight App Links verification before publishing the real file. Includes fingerprint extraction from device, JSON preview, and a step-by-step workflow that triggers pm verify-app-links --re-verify and polls for results.
  • Code review follow-up — 7 blocker/major fixes on top of the feature.

What's in the feature

  • infrastructure/server/AssetLinksServer.kt — Ktor server (127.0.0.1 bound only)
  • data/generator/AssetLinksGenerator.kt — builds the JSON
  • data/parser/FingerprintParser.kt — extracts SHA-256 from device output
  • domain/usecase/localhosting/* — Start / Stop / Extract / Generate / RunVerificationWorkflow
  • ui/screen/localhosting/LocalHostingScreen.kt + LocalHostingViewModel.kt
  • Unit tests for generator / parser / use cases

Review fixes (commit 16ad6a6)

  • ADB command parser is now quote-aware so URIs with spaces survive tokenization
  • Android 11 strategy drops the broken | grep pipe (ProcessBuilder bypasses the shell — filtering is done in Kotlin instead)
  • FavoriteRepositoryImpl: disk writes on Dispatchers.IO, add/remove serialized with Mutex
  • runVerificationWorkflow wrapped in try { } finally { } so the server is always stopped on early return / exception / cancellation
  • AssetLinksStatus.INVALID_CONTENT_TYPE added (was being silently mapped to VALID) — analyzer + UI updated to surface it
  • App.kt stops the local server before cancelling viewModelScope on dispose, so the port is freed at app exit
  • MainViewModel.refreshDevices() now goes through RefreshDevicesUseCaseDeviceRepository instead of touching AdbShellExecutor / DeviceMapper directly

Test plan

  • ./gradlew :composeApp:compileKotlinJvm → BUILD SUCCESSFUL
  • ./gradlew :composeApp:jvmTest → all green
  • Manual: Android 11 device — verify App Links list now populates (previously broken by the | grep pipe)
  • Manual: Local Hosting workflow — abort mid-polling and confirm server port is released (lsof -iTCP:<port>)
  • Manual: Favorites — add same URI twice rapidly, confirm only one entry persists
  • Manual: Diagnostics — point at a domain serving assetlinks.json with wrong Content-Type, confirm UI shows "Wrong Content-Type"

Related: closes-out work tracked in #12.

manjee and others added 2 commits February 12, 2026 16:28
- AdbShellExecutor: parseCommand now honors double-quoted args so intents
  with spaces in URIs no longer split mid-argument
- Android11Strategy: drop "| grep" pipe — ProcessBuilder doesn't go through
  a shell, so the pipe was being passed as a literal grep argument and
  breaking App Links queries on Android 11. Filtering is already done in
  Kotlin by the caller.
- FavoriteRepositoryImpl: move saveToDisk to Dispatchers.IO and serialize
  add/remove with a Mutex so concurrent calls can't double-write
- LocalHostingRepositoryImpl: wrap runVerificationWorkflow in try/finally
  to guarantee server cleanup on early return, exception, or cancellation
- VerificationDiagnostics: add INVALID_CONTENT_TYPE status and matching
  failure reason so wrong Content-Type responses are surfaced instead of
  being silently mapped to VALID
- App.kt: stop the local Ktor server inside DisposableEffect before
  cancelling viewModelScope so the port isn't held until process exit
- MainViewModel: route refreshDevices through a new RefreshDevicesUseCase
  + DeviceRepository.refreshDevices(), removing direct AdbShellExecutor
  and DeviceMapper usage from the UI layer
@manjees manjees added enhancement New feature or request bug Something isn't working ui User interface and visual improvements labels May 14, 2026
# Conflicts:
#	composeApp/build.gradle.kts
#	composeApp/src/jvmMain/kotlin/com/manjee/linkops/App.kt
#	composeApp/src/jvmMain/kotlin/com/manjee/linkops/data/repository/LocalHostingRepositoryImpl.kt
#	composeApp/src/jvmMain/kotlin/com/manjee/linkops/di/AppContainer.kt
#	composeApp/src/jvmMain/kotlin/com/manjee/linkops/ui/navigation/NavGraph.kt
#	composeApp/src/jvmMain/kotlin/com/manjee/linkops/ui/navigation/Screen.kt
#	gradle/libs.versions.toml
@manjees
manjees merged commit 4ccb73c into main May 14, 2026
2 checks passed
@manjees
manjees deleted the solve/issue-12 branch May 14, 2026 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request ui User interface and visual improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant