Skip to content

fix: dedupe comparator, cross-ecosystem isolation, and URLEncoder API level - #25

Merged
gthgomez merged 2 commits into
mainfrom
fix/dedupe-comparator-and-api-compat
Oct 9, 2026
Merged

gthgomez merged 2 commits into
mainfrom
fix/dedupe-comparator-and-api-compat

Conversation

@gthgomez

@gthgomez gthgomez commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Summary of Changes

  1. URLEncoder API Level Compatibility Fix (RokuEcpClient.kt)

    • Replaced URLEncoder.encode(char.toString(), Charsets.UTF_8) with URLEncoder.encode(char.toString(), "UTF-8").
    • URLEncoder.encode(String, Charset) requires Android API 33+. On Android 8.0–12L (minSdk = 26), typing special characters in the TV keyboard caused runtime NoSuchMethodError crashes.
    • Resolves the blocking NewApi lint error on ./gradlew :app:lintDebug.
  2. Deduplication Comparator Realignment (DeviceDao.kt)

    • Fixed inverted boolean conditions in DEVICE_ROW_COMPARATOR so that maxWithOrNull correctly prefers:
      • Real serials over manual entries (!it.uniqueId.startsWith("manual:"))
      • Mapped HDMI over unmapped (it.hdmiPortMapping != null)
      • Online over offline (it.isOnline)
      • Zero failures over failing devices (it.consecutiveFailures == 0)
      • Latest seen timestamp (it.lastSeenMillis)
    • Aligns with DEVICE_COMPARATOR in DeviceCanonical.kt.
  3. Cross-Ecosystem Deduplication Grouping (DeviceDao.kt & DeviceCanonical.kt)

    • Namespaced deduplication grouping by device type and included endpoint port for manual devices ("${device.type}:${endpoint}").
    • Prevents cross-lane erasure when a Roku TV and Google TV share an IP address (e.g. test harnesses or proxy tunnels).
    • Added unit tests in DeviceCanonicalTest.kt verifying cross-type retention and comparator precedence.
  4. Enum Modernization (HaloDpad.kt)

    • Migrated deprecated RingAction.values() to RingAction.entries.
  5. Toolchain Permissions (gradlew)

    • Tracked gradlew with executable file mode 100755.

Verification

  • ./gradlew :app:assembleDebug :app:testDebugUnitTest --rerun-tasks -> PASS (95/95 unit tests)
  • ./gradlew :app:lintDebug -> PASS (0 errors)

… URLEncoder API level

- DeviceDao.DEVICE_ROW_COMPARATOR: invert boolean criteria to match natural max ordering, correctly preferring real serials over manual entries, mapped HDMI over unmapped, online over offline, and zero failures over failing devices.
- Deduplication grouping: namespace grouping key by device type and include port for manual devices in both DeviceDao and DeviceCanonical, preventing cross-ecosystem device erasure when devices share an IP.
- RokuEcpClient: use URLEncoder.encode(str, "UTF-8") instead of Charset overload (API 33+) to prevent NoSuchMethodError on Android 8-12 (minSdk 26) and resolve NewApi lint error.
- HaloDpad: replace deprecated RingAction.values() with RingAction.entries.
- gradlew: set executable permission bit in git (100755).
- DeviceCanonicalTest: add tests for cross-type preservation on same IP and comparator preference.
…ial rekeying

- Reorder DEVICE_ROW_COMPARATOR and DEVICE_COMPARATOR to prioritize liveness, health, and recency over hdmiPortMapping, preventing stale offline endpoints from winning on DHCP IP shifts.
- Guard deletePairingCredential and migratePairingCredential in rekeyDeviceIdentity to only execute when staleDeviceId != merged.id.
- Add regression tests covering same-type different-port preservation and liveness precedence over HDMI configuration.
@gthgomez
gthgomez merged commit 1af92a0 into main Oct 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant