t66: app names on a device that exposes none

The reported Shield names no app: `pm dump com.netflix.ninja` is ~2241 lines of
dumpsys and grep for `application-label` over the whole capture finds nothing.
The probe shipped `| head -300`, which cut the dump BEFORE the package section,
so "no label" was a truncation artefact; the sweep then named every app after
its own package id, and the apps editor pre-filled the `pkg=pkg` row the user
read as a bug.

  * the probe greps ON THE DEVICE for the three shapes Android prints
    (`application-label`, `nonLocalizedLabel`, `labelRes`); a quoted value is a
    name, `null` and a resource id are not. The dump is never truncated.
  * after APP_LABEL_PROBE_LIMIT consecutive "ran, no label" answers the device
    is taken at its word: the sweep stops spending a shell per package
    (APP_LABEL_TTL expiry re-checks, and a package whose probe FAILED still owes
    its retry — t57 UNIT 0 survives, driven by the app on screen).
  * ONE precedence chain in `ha_adb_common/app_label.resolve_package_name`, used
    by the media player, the Current App sensor, the discovery table, the source
    list and the apps editor: user map > device label > curated map > package id
    (the id shown ONCE, `name` empty when nothing names the app).
  * the curated table covers the user's 21 apps (community-maintained, not
    device truth) and the Configure row says when the device named nothing.
  * the real device shape is a test fixture (trimmed, and marked as such in the
    file: the raw capture is not in the repo) pinning that no label is
    extracted, that the probe count is bounded, and that `Netflix` surfaces.

Also drops the dead `ATTR_MEDIA_DAG_NOW_PLAYING` re-exports left by the t65
flattening and updates the RESEARCH_SHIELD now-playing note to the flat names.

No real Shield was available: the fetch/burst behaviour is exercised against the
documented Android output and the trimmed reproduction of the reported capture.
This commit is contained in:
James Mackay committed 2026-10-12 10:54:38 +01:00
1 parent f29f62ddae
commit 7b32de789a
16 files changed
+973 -176

No files matched your search

+22 -15
View File
@@ -116,7 +116,11 @@ from .const import (
TIVIMATE_PACKAGE,
command_scripts,
)
from .ha_adb_common import PlaybackIntent, running_apps_from_tasks
from .ha_adb_common import (
PlaybackIntent,
resolve_package_name,
running_apps_from_tasks,
)
from .jellyfin import fetch_session_media_info
from .power import discover_power_siblings
@@ -377,26 +381,29 @@ def resolve_app_name(
package: str | None,
app_name_map,
app_label,
curated=None,
) -> str | None:
"""Resolve a package id to a friendly name (t40; entity tier removed t41).
"""Resolve a package id to a friendly name (t40; curated tier t66).
The single chain behind ``media_player.app_name`` and the Current App
sensor:
sensor, delegating to ``ha_adb_common.app_label.resolve_package_name`` so the
discovery table and the options editor cannot drift from it:
1. the user's explicit apps map (``CONF_APP_NAME_MAP``);
2. the cached device-manifest label (``manager.app_label`` — a cache miss
enqueues the on-demand fetch and falls through);
3. the raw package text — a bare or unknown package falls back to itself,
never to None.
2. the cached device label (``manager.app_label`` — a cache miss enqueues the
on-demand fetch and falls through);
3. the curated table (``DEFAULT_APP_DIRECTORY``) — the tier that names apps on
a Shield whose ``pm dump`` exposes no label at all;
4. the raw package text — a bare or unknown package falls back to itself,
never to None, and it is shown ONCE (no ``pkg=pkg`` anywhere).
"""
if package:
mapped = (app_name_map or {}).get(package)
if mapped:
return mapped
label = app_label(package) if app_label is not None else None
if label:
return label
return package or None
return resolve_package_name(
package,
user_map=app_name_map,
# the callable keeps the device tier LAZY: the user's map answers first
device_label=app_label,
curated=DEFAULT_APP_DIRECTORY if curated is None else curated,
)
class NvidiaShieldMediaPlayer(MediaPlayerEntity):