# Quality-Scale Audit: `androidtv` > Audit snapshot per rubric; re-verify against `dev` before execution. > Scope is the ADB-based `androidtv` domain — **not** `androidtv_remote` (Google TV remote > protocol), which is a separate, more modern integration. Cross-references noted in §4. ## 1. Integration profile | Attribute | Value | |---|---| | Domain | `androidtv` | | IoT class | `local_polling` | | Primary libraries | `androidtv` (with `adb_shell` for native ADB, or `pure-python-adb` for ADB-server mode) | | Declared `quality_scale` | none declared | | Install base | Top-60; Fire TV + Android TV/Google TV boxes, Shield, Sony Bravia | | Issue volume | Medium-high — ADB auth dance (key rejection, "device unauthorized"), state-detection wrong app/state, slow polls blocking, custom state-detection rules confusion, ADB-server mode mismatches | | CODEOWNERS | Yes — owner also maintains the upstream `androidtv` library, which simplifies upstreaming fixes | **Why selected:** persistent auth-UX pain with a clean rule-mapped fix (reauth flow), plus an unusual advantage: the integration owner controls the upstream library, so cross-layer fixes are tractable. ## 2. Rule-by-rule audit ### Bronze | Rule | Status | Evidence / Gap | |---|---|---| | `config-flow` | ✅ | UI flow; manual host entry (no reliable discovery for ADB), options flow for app lists, state-detection rules, exclude patterns. | | `test-before-configure` | ✅ | ADB connect + device-properties fetch before entry creation. | | `unique-config-entry` | ✅ | Unique ID from device properties (serial/MAC fallback chain) — verify fallback order is documented. | | `config-flow-test-coverage` | 🟡 | Options-flow JSON validation branches (state-detection rules) need coverage check. | | `entity-unique-id` | ✅ | Media player + remote entities. | | `has-entity-name` | 🟡 | Verify both platforms set `_attr_has_entity_name = True` with device-name entity naming. | | `runtime-data` | 🟡 | Verify `entry.runtime_data` migration. | | `appropriate-polling` | 🟡 | ADB screencap/state polls are expensive on some devices; interval and the "no screencap" option exist — document rationale; ensure poll work is fully executor-offloaded (reported event-loop stalls). | | `entity-event-setup` | ➖ | N/A. | | `action-setup` | 🟡 | Custom services (`adb_command`, `learn_sendevent`, `download`, `upload`) are entity services — verify registration pattern and translated validation errors; `download`/`upload` must validate paths against allowlist (security-sensitive — verify current checks against `hass.config.is_allowed_path`). | | `common-modules` | 🟡 | `entity.py` shared base exists; no coordinator (per-entity poll) — acceptable, record exemption rationale. | | `dependency-transparency` | ✅ | PyPI, public source. | | `docs-*` (Bronze set) | 🟡 | Docs are detailed (ADB setup, state detection); removal instructions and actions table to template. | | `brands` | ✅ | Present. | ### Silver | Rule | Status | Evidence / Gap | |---|---|---| | `config-entry-unloading` | ✅ | ADB connection closed on unload; verify both transport modes. | | `reauthentication-flow` | ❌ | **Key gap.** When the device revokes/forgets the ADB key (factory reset, "revoke USB debugging authorizations", new key prompt), setup fails with retry loops and users are told (in forums) to delete/re-add. Implement reauth flow: trigger on ADB auth rejection, flow step instructs to accept the on-screen prompt, retries connect, confirms. Must handle both native-ADB (key files) and ADB-server modes. | | `action-exceptions` | 🟡 | `adb_command` failures partially return None/log; raise translated `HomeAssistantError` (device unavailable, command failed, path not allowed). | | `entity-unavailable` | ✅/🟡 | Availability flips on failed update; verify no flapping on single transient ADB hiccup (debounce consideration; coordinate with owner). | | `log-when-unavailable` | 🟡 | Reconnect attempts log per cycle; implement log-once. | | `parallel-updates` | ❌ | Not declared; ADB is strictly serial per device — declare `1` on both platforms. | | `integration-owner` | ✅ | Active; owns upstream library. | | `test-coverage` | 🟡 | Good patch-based suite; reauth (new) and remote platform branches need work; service path-validation tests must be thorough (security-relevant). | | `docs-configuration-parameters` | 🟡 | State-detection rules schema documented; verify all options-flow fields are in the parameter table. | ### Gold (selected) | Rule | Status | Notes | |---|---|---| | `diagnostics` | ✅/🟡 | Diagnostics module exists; verify it includes transport mode, device properties, last state-detection output, and redacts serial/host/key paths. Extend if thin (AT-4). | | `discovery` | ➖ | No usable discovery protocol for ADB targets; record exemption. (DHCP-based hints are possible but out of scope — note for owner.) | | `entity-translations` | 🟡 | Fold trivial fixes into AT-3 if touched. | | `strict-typing` | ❌ | Out of scope. | ## 3. Gap summary and proposed work items | ID | Work item | Rule(s) | Size | Risk | |---|---|---|---|---| | AT-1 | Implement reauthentication flow for ADB key rejection (both transports) + flow tests | `reauthentication-flow` | M | Medium — auth dance is fiddly; owner co-review; may need a small upstream `androidtv` release to expose a clean auth-failure exception | | AT-2 | Translated action exceptions for `adb_command`/`download`/`upload`; verify allowlist path checks + security tests | `action-exceptions` | S | Low (security-sensitive review flag set) | | AT-3 | `PARALLEL_UPDATES = 1`, `runtime_data` migration, `has_entity_name` verification, log-once unavailability | `parallel-updates`, `runtime-data`, `has-entity-name`, `log-when-unavailable` | S | Low | | AT-4 | Diagnostics review/extension (transport, state-detection snapshot, redaction) | `diagnostics` | S | Low | | AT-5 | Coverage: remote platform, options-flow validation, new reauth paths to ≥95 % | `test-coverage`, `config-flow-test-coverage` | M (tests only) | Low | | AT-6 | Docs: removal instructions, parameter table completion, reauth troubleshooting section | `docs-*` | S | Low | | AT-7 | Add `quality_scale.yaml` (discovery + coordinator exemptions recorded); declare Bronze→Silver after AT-1…AT-3, AT-5 | meta | XS | Low | **Target outcome:** unscored → **Silver**. AT-1 removes the single worst UX failure ("delete and re-add your entry") for this integration. ## 4. Maintainer-coordination notes - The owner maintains upstream `androidtv`: if AT-1 requires distinguishing auth-rejection from transport errors, propose the exception upstream first; pin the integration requirement to the released version per the requirements policy. - Be explicit in all communication that this work targets `androidtv`, not `androidtv_remote`; several past contributors conflated the two. Where users would be better served by `androidtv_remote` (Google TV devices), the docs PR (AT-6) should add a pointer rather than expanding `androidtv` scope.