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:
1 parent
f29f62ddae
commit
7b32de789a
16 files changed
+973
-176
No files matched your search
@@ -154,11 +154,15 @@ def _apps_table_text(
|
||||
"""The Editable apps table: stored rows first, then discovered apps (t57).
|
||||
|
||||
Every app the Shield reports gets a row, so the page opens on the REAL app
|
||||
list instead of the four curated entries ("it doesn't find all the apps").
|
||||
list instead of only the built-in names ("it doesn't find all the apps").
|
||||
The stored rows keep their position, name and icon — the user's edit is
|
||||
never overwritten by a discovery — and a discovered app the map does not
|
||||
mention is appended with the device label (or its package id when the label
|
||||
fetch did not answer) and its heuristic icon.
|
||||
mention is appended with the name the SAME chain resolves (user map > device
|
||||
label > curated map) and its heuristic icon. An app whose name is unknown
|
||||
anywhere is NOT written as ``pkg=pkg``: a row that saves the package id as if
|
||||
it were a name is the defect the user reported from this very field, so such
|
||||
an app is offered in the row editor (which says "no name yet" out loud)
|
||||
instead of being pre-filled here.
|
||||
|
||||
The icon column is emitted only for a stored icon, because the discovered
|
||||
icon is an MDI NAME (``mdi:netflix``) and the icon column's documented
|
||||
@@ -178,7 +182,11 @@ def _apps_table_text(
|
||||
if not package or package in seen:
|
||||
continue
|
||||
seen.add(package)
|
||||
name = app.get("name") or package
|
||||
name = str(app.get("name") or "").strip()
|
||||
if not name or name == package:
|
||||
# nothing names this app: the id would be doubled into a "name" that
|
||||
# is not one (t66). The row editor still offers it for naming.
|
||||
continue
|
||||
lines.append(f"{package}={name}")
|
||||
return "\n".join(lines)
|
||||
|
||||
@@ -1287,6 +1295,13 @@ class NvidiaShieldOptionsFlow(config_entries.OptionsFlowWithReload):
|
||||
"the Shield reported no installed apps — the table keeps your "
|
||||
"saved rows."
|
||||
)
|
||||
if getattr(manager, "app_labels_absent", False):
|
||||
# Measured, not guessed: the sweep probed and this firmware named
|
||||
# nothing, so say which names the user is looking at (t66).
|
||||
return (
|
||||
f"{len(apps)} apps found — this Shield exposes no app labels over "
|
||||
"ADB, so names come from the built-in app names and your own rows."
|
||||
)
|
||||
return f"{len(apps)} apps found on the Shield — the table is updated."
|
||||
|
||||
async def async_step_menu_again(self, user_input=None):
|
||||
@@ -1530,19 +1545,24 @@ class NvidiaShieldOptionsFlow(config_entries.OptionsFlowWithReload):
|
||||
"""The apps the device reported, ``{package: {name, icon}}`` (t64).
|
||||
|
||||
Straight from the t57 cache — no sweep, no shell. The name may be empty:
|
||||
the user's Shield exposes no device label at all, and a package whose
|
||||
``pm dump`` failed falls back to its id, which is NOT a name (see
|
||||
``_editable_apps``).
|
||||
the user's Shield exposes no device label at all (t66: the discovery table
|
||||
no longer repeats the package id as a name), and an app nothing names is
|
||||
left empty so ``_editable_apps`` can mark it as needing a name.
|
||||
"""
|
||||
detected: dict = {}
|
||||
for app in self._discovered_apps():
|
||||
package = str(app.get("package") or "").strip()
|
||||
if not package:
|
||||
continue
|
||||
name = str(app.get("name") or "").strip()
|
||||
if name == package:
|
||||
# a name that IS the id is not a name (t66): the row editor says
|
||||
# "(no name yet)" instead of offering the id twice.
|
||||
name = ""
|
||||
detected.setdefault(
|
||||
package,
|
||||
{
|
||||
"name": str(app.get("name") or "").strip(),
|
||||
"name": name,
|
||||
"icon": str(app.get("icon") or "").strip(),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user