Skip to content

Releases: mhoogenbosch/PiPup

v0.13.0 — an icon beside the title and message

Choose a tag to compare

@github-actions github-actions released this 25 Aug 05:40
9d553ea

English

Requested in #19: show an icon next to the popup's title and message, notification-style.

Added

  • Optional icon (an image URL, loaded like other media) shown beside the title/message block, with:
    • iconPositionleft (default) or right
    • iconWidth — pixels (default 96), aspect ratio preserved
  • Available on both the JSON and multipart /notify endpoints. The title and message sit in a column next to the icon; a media image (if any) stays below, and a media-only popup drops the empty header row.

Verified on a Fire TV (icon left, right, and alongside a media image).

Home Assistant: ha-pipup v1.14.0 adds icon / icon_position / icon_width to pipup.show.


Nederlands

Gevraagd in #19: toon een icoon naast de titel en het bericht van de popup, notificatie-stijl.

Toegevoegd

  • Optioneel icon (een afbeelding-URL, geladen zoals andere media) naast het titel/bericht-blok, met:
    • iconPositionleft (standaard) of right
    • iconWidth — pixels (standaard 96), beeldverhouding behouden
  • Beschikbaar op zowel de JSON- als de multipart-/notify-endpoint. Titel en bericht komen in een kolom naast het icoon; een media-afbeelding (indien aanwezig) blijft eronder, en een popup met alleen media laat de lege kop-rij weg.

Op een Fire TV geverifieerd (icoon links, rechts, en naast een media-afbeelding).

Home Assistant: ha-pipup v1.14.0 voegt icon / icon_position / icon_width toe aan pipup.show.

v0.12.2 — visible focus on multi-button popups

Choose a tag to compare

@github-actions github-actions released this 24 Aug 21:48
5b87428

English

Reported in #18: on a popup with multiple buttons, D-pad navigation worked — the correct button fired — but nothing on screen showed which button was focused, so it looked unresponsive. Users pressed the arrows, saw no change, and assumed the popup was not interactive.

Fixed

  • In an overlay window the platform button background carries no focus state. Each button now has an explicit focused/unfocused background (a bright fill when focused, a subtle translucent one otherwise) plus a small scale bump on focus, and the first button takes focus when the popup appears — so there is a highlight from the start.

Verified on a Fire TV: initial focus lands on the first button, D-pad moves it, and OK activates the focused button.

App-only; no Home Assistant change needed.


Nederlands

Gemeld in #18: bij een popup met meerdere knoppen werkte D-pad-navigatie wel — de juiste knop vuurde — maar niets op het scherm liet zien welke knop geselecteerd was, dus het leek niet te reageren. Gebruikers drukten op de pijltjes, zagen niets veranderen en dachten dat de popup niet interactief was.

Opgelost

  • In een overlay-window heeft de standaard knop-achtergrond geen focus-status. Elke knop heeft nu een expliciete gefocuste/ongefocuste achtergrond (een heldere vulling bij focus, anders een subtiele doorschijnende) plus een lichte schaalvergroting bij focus, en de eerste knop krijgt focus zodra de popup verschijnt — dus er is meteen een highlight.

Op een Fire TV geverifieerd: de eerste knop krijgt focus, de D-pad verplaatst 'm, en OK activeert de gefocuste knop.

Alleen app-kant; geen Home Assistant-wijziging nodig.

v0.12.1 — a remote-initiated update no longer stalls invisibly

Choose a tag to compare

@github-actions github-actions released this 24 Aug 21:34
4046426

English

Follow-up to a field report: pressing Install in Home Assistant for a sleeping Fire TV (Android 9) appeared to do nothing, and afterwards it only said an update was already running.

Fixed

  • Android < 12 cannot install without an on-screen confirmation (the install permission does not change that). The app already turns that into a popup with a button, but it did not wake the screen — so on a sleeping TV the confirmation sat on a black screen and the update stalled invisibly. The app now wakes the screen when a confirmation is pending, so one press on the remote finishes it.
  • The stalled state (installing: true) used to linger for 15 minutes after an unconfirmed attempt. The pending install is now released as soon as its confirmation popup goes away unconfirmed, so the update can be retried immediately.
  • /state.update gained pendingUserAction (waiting for the on-screen confirmation) and silent (false on Android < 12, where an install cannot complete without a remote press).

Home Assistant: ha-pipup v1.13.1 surfaces this as a pending_confirmation attribute.


Nederlands

Vervolg op een praktijkmelding: Bijwerken indrukken in Home Assistant voor een slapende Fire TV (Android 9) leek niets te doen, en meldde daarna alleen dat er al een update bezig was.

Opgelost

  • Android < 12 kan niet installeren zonder een bevestiging op het scherm (de install-permissie verandert dat niet). De app maakt daar al een popup-met-knop van, maar wekte het scherm niet — dus op een slapende tv stond de bevestiging op een zwart scherm en liep de update onzichtbaar vast. De app wekt nu het scherm zodra een bevestiging klaarstaat, zodat één druk op de afstandsbediening 'm afmaakt.
  • De vastgelopen staat (installing: true) bleef voorheen 15 minuten hangen na een onbevestigde poging. De install wordt nu vrijgegeven zodra de bevestigingspopup verdwijnt zonder bevestiging, zodat je meteen opnieuw kunt updaten.
  • /state.update heeft nu pendingUserAction (wacht op de schermbevestiging) en silent (onwaar op Android < 12, waar een install niet kan afronden zonder druk op de afstandsbediening).

Home Assistant: ha-pipup v1.13.1 toont dit als een pending_confirmation-attribuut.

v0.12.0 — comes back after a silent power-restore boot

Choose a tag to compare

@github-actions github-actions released this 24 Aug 20:12
ac34026

English

Follow-up to a field report: after a mains power cut and restore, if the TV boots to standby without being turned on and is later woken over ADB, PiPup never started — the connectivity sensor stayed offline until the app was opened by hand from the app drawer, and the keep-alive automation didn't rescue it.

Root cause

PiPup already restarts itself on boot via a BOOT_COMPLETED receiver. But BOOT_COMPLETED is only broadcast once the device reaches a fully started, unlocked user session — a TV that boots to standby after a power restore never reaches that point, and waking it over ADB is a wake event, not a boot event, so the one-shot broadcast never fires.

Fix

  • The boot receiver and the service are now directBootAware and also listen for LOCKED_BOOT_COMPLETED (plus QUICKBOOT_POWERON for OEM fast-boot). These fire in the early locked-boot phase, before turn-on, so the service starts on a silent power-restore boot too.
  • App preferences (the stable device id and version markers — none of them sensitive) moved to device-protected storage so they are readable during direct boot. The existing file is migrated once, so the device id — and therefore the Home Assistant unique_id — stays the same.

Verified on hardware (Fire TV)

Device id unchanged across the update; after a reboot with the remote untouched the service self-started 27 s later (uptime 1 s). LOCKED_BOOT_COMPLETED is a system-only broadcast, so the exact standby-boot delivery can only be reproduced on a real mains cut — the self-start after reboot confirms the boot path works.

No Home Assistant changes needed. Update the app on your TVs (or let it self-update).


Nederlands

Vervolg op een praktijkmelding: als de netstroom wegvalt en terugkomt en de tv naar standby opstart zonder aangezet te worden en later via ADB gewekt wordt, startte PiPup nooit — de connectivity-sensor bleef offline tot de app met de hand uit de app-drawer werd geopend, en de keep-alive-automation ving het niet op.

Oorzaak

PiPup herstart zichzelf al bij boot via een BOOT_COMPLETED-receiver. Maar BOOT_COMPLETED wordt pas verstuurd zodra het toestel een volledig opgestarte, ontgrendelde gebruikerssessie bereikt — een tv die naar standby opstart bereikt dat punt nooit, en via ADB wekken is een wake-event, geen boot-event, dus de eenmalige broadcast vuurt niet.

Oplossing

  • De boot-receiver én de service zijn nu directBootAware en luisteren ook naar LOCKED_BOOT_COMPLETED (plus QUICKBOOT_POWERON voor OEM fast-boot). Die vuren in de vroege locked-boot-fase, vóór het aanzetten, dus de service start ook bij een silent power-restore-boot.
  • App-voorkeuren (de stabiele device-id en versiemarkers — niets gevoeligs) verhuisd naar device-protected storage zodat ze tijdens direct-boot leesbaar zijn. Het bestaande bestand wordt eenmalig gemigreerd, dus de device-id — en dus de Home Assistant unique_id — blijft gelijk.

Op hardware geverifieerd (Fire TV)

Device-id ongewijzigd over de update; na een reboot zonder de remote aan te raken kwam de service 27 s later vanzelf op (uptime 1 s). LOCKED_BOOT_COMPLETED is een systeem-only broadcast, dus de exacte standby-boot-aflevering is alleen na een echte stroomonderbreking te reproduceren — de zelf-start na reboot bevestigt dat de boot-tak werkt.

Geen Home Assistant-wijzigingen nodig. Werk de app op je tv's bij (of laat 'm zichzelf updaten).

v0.11.1 — a Fix button that doesn't lie on locked-down TVs

Choose a tag to compare

@github-actions github-actions released this 24 Aug 18:19
c3d68ef

English

Follow-up to a field report (TCL Smart TV Pro, Android 11): the self-update permission stayed MISSING no matter how often Fix was pressed. The /permissions/diagnose endpoint showed why:

"opModes": { "installPackages": "errored" }
"lastFix": { "what": "install", "ok": true }   ← the screen opened, but the toggle didn't stick

errored is a device-blocked app-op. Several manufacturers lock "install unknown apps" for sideloaded apps at the system level (Samsung's Auto Blocker is the best-known example): the settings screen opens, the switch won't take, and only adb can change it.

Change

When an app-op is errored/ignored, PiPup stops offering a Fix button that leads nowhere:

  • Status screen shows the adb command with a "this TV blocks it from its settings screen" note instead of a button.
  • POST /permissions/fix answers 501 with that reason + the adb command, rather than opening a dead screen.
  • A neutral default op (the normal case) keeps the on-screen Fix button — unchanged.

Verified on hardware: forcing the install-op to ignored gave install.fixable: false, a 501 with the adb command, and the adb line on the status screen; restoring to allow returned everything to normal.

Home Assistant: ha-pipup v1.13.0 adds a "Fix self-update permission" button that surfaces the same message.


Nederlands

Vervolg op een praktijkmelding (TCL Smart TV Pro, Android 11): de zelf-update-permissie bleef ONTBREEKT, hoe vaak Repareren ook werd ingedrukt. Het /permissions/diagnose-endpoint liet zien waarom:

"opModes": { "installPackages": "errored" }
"lastFix": { "what": "install", "ok": true }   ← het scherm opende, maar de schakelaar bleef niet staan

errored is een door het toestel geblokkeerde app-op. Diverse fabrikanten vergrendelen "onbekende apps installeren" voor gesideloade apps op systeemniveau (Samsung's Auto Blocker is het bekendste voorbeeld): het instellingenscherm opent, de schakelaar pakt niet, en alleen adb kan het wijzigen.

Wijziging

Bij een errored/ignored-app-op biedt PiPup geen loze Repareren-knop meer aan:

  • Statusscherm toont het adb-commando met de melding "deze tv blokkeert het via het instellingenscherm" i.p.v. een knop.
  • POST /permissions/fix antwoordt 501 met die reden + het adb-commando, in plaats van een dood scherm te openen.
  • Een neutrale default-op (het normale geval) houdt de knop op het scherm — ongewijzigd.

Op hardware geverifieerd: de install-op op ignored gaf install.fixable: false, een 501 met het adb-commando en de adb-regel op het statusscherm; terug op allow was alles weer normaal.

Home Assistant: ha-pipup v1.13.0 voegt een knop "Zelf-updaten repareren" toe die dezelfde melding toont.

v0.11.0 — visible updates, and a confirmation that can actually be confirmed

Choose a tag to compare

@github-actions github-actions released this 23 Aug 11:24
138cefd

English

Field report: pressing Install in Home Assistant made "a screen flash by" on the TV, then nothing. Two platform behaviours behind it:

  • Android < 12: the installer demands an on-screen confirmation. Launched blind from the background, that dialog flashes and vanishes (measured on a TCL Google TV) — the install session then waits forever on a dialog nobody can reach.
  • Android 12+: the install is silent and over in seconds — nothing ever acknowledged the button press.

What's new

  • "Installing PiPup vX…" popup (with countdown bar) the moment an update starts.
  • A confirmation popup with a button (Android < 12): pressing OK launches the system's install dialog from a visible window, so it keeps focus instead of flashing away — the same background-activity-launch lesson as v0.9.0, now applied to the system installer. And it is repeatable: POST /update while a confirmation is pending shows the popup again instead of answering "already running".
  • "PiPup updated to vX" popup once the app has replaced itself (only when the screen is on).

Note

These flows live in the new code, so they become visible from the next update cycle onward — updating to 0.11.0 still uses the old, silent path. Home Assistant users: ha-pipup v1.12.0 fixes the missing progress spinner on the update entity.


Nederlands

Praktijkmelding: op Installeren drukken in Home Assistant liet "heel even een schermpje flitsen" op de tv, en daarna niets. Twee platformgedragingen daarachter:

  • Android < 12: de installer eist een bevestiging op het scherm. Blind gestart vanuit de achtergrond flitst die dialoog voorbij en verdwijnt (gemeten op een TCL Google TV) — de installatiesessie wacht daarna eeuwig op een dialoog die niemand kan bereiken.
  • Android 12+: de installatie is stil en in seconden klaar — niets bevestigde ooit de knopdruk.

Nieuw

  • Popup "PiPup vX wordt geïnstalleerd…" (met aftelbalk) zodra een update start.
  • Een bevestigingspopup mét knop (Android < 12): OK drukken opent de systeemdialoog vanuit een zichtbaar venster, waardoor hij focus houdt in plaats van weg te flitsen — dezelfde background-activity-launch-les als v0.9.0, nu toegepast op de systeeminstaller. En herhaalbaar: POST /update terwijl een bevestiging openstaat toont de popup opnieuw in plaats van "already running" te antwoorden.
  • Popup "PiPup bijgewerkt naar vX" zodra de app zichzelf vervangen heeft (alleen bij scherm aan).

NB

Deze flows zitten in de nieuwe code en worden dus zichtbaar vanaf de volgende update-cyclus — updaten naar 0.11.0 loopt nog via het oude, stille pad. Home Assistant: ha-pipup v1.12.0 verhelpt de ontbrekende voortgangsspinner op de update-entity.

v0.10.2 — diagnose: raw app-op modes

Choose a tag to compare

@github-actions github-actions released this 23 Aug 05:57
d3820de

English

Diagnostics-only release, prompted by a field report with screenshots of a genuine contradiction: the Install unknown apps settings screen shows Allowed, while the app's status screen reports Self-update permission: MISSING.

Those two really can disagree. Measured on Android 14: with the app-op in mode default — the state every reinstall resets it to — canRequestPackageInstalls() answers false, whatever a toggle shows. The old boolean collapsed default, ignored and "the check itself threw" into the same false.

GET /permissions/diagnose now also reports:

  • opModes — the raw app-op mode (allowed/ignored/errored/default) for the install and overlay grants;
  • installCheckError — an exception inside the check is no longer indistinguishable from a revoked permission;
  • user — app-ops are per profile: a Settings screen viewed under another profile (e.g. a Google TV kids profile) shows that profile's state, not the app's;
  • targetSdk.

If your TV shows this contradiction: paste the output of curl http://<tv-ip>:7979/permissions/diagnose in an issue — opModes.installPackages now names the actual state. The quick fix remains one command (or re-toggling the switch off and on in Settings):

adb shell appops set nl.rogro82.pipup REQUEST_INSTALL_PACKAGES allow

Nederlands

Release met alleen diagnostiek, naar aanleiding van een praktijkmelding met screenshots van een echte tegenstrijdigheid: het instellingenscherm Onbekende apps installeren toont Toegestaan, terwijl het statusscherm van de app Zelf-updaten: ONTBREEKT meldt.

Die twee kúnnen echt uiteenlopen. Gemeten op Android 14: met de app-op in stand default — waar elke herinstallatie hem op terugzet — antwoordt canRequestPackageInstalls() false, wat een schakelaar ook toont. De oude boolean gooide default, ignored en "de check zelf gooide een fout" op één hoop.

GET /permissions/diagnose meldt nu ook:

  • opModes — de rauwe app-op-stand (allowed/ignored/errored/default) voor de install- en overlay-rechten;
  • installCheckError — een exception ín de check is niet langer onzichtbaar;
  • user — app-ops zijn per profiel: een instellingenscherm bekeken onder een ander profiel (bv. een Google TV-kinderprofiel) toont de stand van dat profiel;
  • targetSdk.

Zie je deze tegenstrijdigheid op je tv: plak de uitvoer van curl http://<tv-ip>:7979/permissions/diagnose in een issue — opModes.installPackages benoemt nu de werkelijke stand. De snelle fix blijft één commando (of de schakelaar in Instellingen uit- en weer aanzetten):

adb shell appops set nl.rogro82.pipup REQUEST_INSTALL_PACKAGES allow

v0.10.1 — security/robustness audit fixes

Choose a tag to compare

@github-actions github-actions released this 22 Aug 15:08
9a17e82

English

Results of a full audit of the fork. Every finding was verified against a concrete failure scenario before it was fixed, and the top three re-verified on hardware afterwards. Update recommended — the first item is reachable by anything on your LAN.

  • Request bodies are now capped at 256 KB (security). /notify allocated a buffer of whatever Content-Length claimed, and the chunked fallback read without a ceiling — a single request with Content-Length: 900000000 crashed the service with an out-of-memory. Now: HTTP 400, service stays up. (The LAN remains the trust boundary, as documented — but a one-request crash is a bug, not a design decision.)
  • A self-update whose on-TV confirmation was never accepted no longer blocks all future updates. On Android < 12 the system shows its confirmation on the TV; if nobody accepted it, the "installing" flag stayed stuck forever and every later install answered "an update is already running" until a service restart. The flag is now a 15-minute deadline.
  • Popups longer than ~24.8 days vanished instantly: the removal delay overflowed a 32-bit multiply and went negative. duration: 2200000 now stays up.
  • Every snapshot popup leaked one file descriptor (BitmapFactory.decodeStream does not close its stream); a corrupt upload also produced a null bitmap instead of a clean error.
  • Removed the dead CONNECTIVITY_CHANGE/WIFI_STATE_CHANGED manifest filters — Android has not delivered those to manifest receivers since API 24/26, so the start-on-network-change they suggested never happened.

Also audited and found sound: the update path (hardcoded HTTPS, non-exported result receiver, setPackage, platform signature enforcement), the JSON setup (fixed subtypes, no polymorphic surprises), button callbacks and the placeholder detection.

Companion: ha-pipup v1.11.2 fixes an indefinite camera popup going dark after 24 h and a timer that could outlive its entity.


Nederlands

Resultaat van een volledige audit van de fork. Elke bevinding is vóór het fixen geverifieerd met een concreet faalscenario, en de bovenste drie zijn daarna op hardware hergecontroleerd. Update aanbevolen — het eerste punt is bereikbaar voor alles op je LAN.

  • Request-bodies zijn nu begrensd op 256 KB (security). /notify alloceerde een buffer ter grootte van wat Content-Length beweerde, en het chunked-pad las zonder plafond — één request met Content-Length: 900000000 crashte de service met een out-of-memory. Nu: HTTP 400, service blijft staan. (Het LAN blijft de vertrouwensgrens, zoals gedocumenteerd — maar een crash door één request is een bug, geen ontwerpkeuze.)
  • Een self-update waarvan de bevestiging op de tv nooit werd geaccepteerd blokkeert niet langer alle volgende updates. Op Android < 12 toont het systeem z'n bevestiging op de tv; accepteerde niemand die, dan bleef de "installing"-vlag voorgoed hangen en antwoordde elke latere poging "an update is already running" tot een service-herstart. De vlag is nu een deadline van 15 minuten.
  • Popups langer dan ~24,8 dagen verdwenen direct: de verwijdertimer overflowde een 32-bits vermenigvuldiging en werd negatief. duration: 2200000 blijft nu gewoon staan.
  • Elke snapshot-popup lekte één file descriptor (BitmapFactory.decodeStream sluit z'n stream niet); een corrupt beeld gaf bovendien een null-bitmap in plaats van een nette fout.
  • De dode CONNECTIVITY_CHANGE/WIFI_STATE_CHANGED-manifestfilters zijn verwijderd — Android levert die sinds API 24/26 niet meer aan manifest-receivers, dus de gesuggereerde start-bij-netwerkwissel gebeurde nooit.

Ook doorgelicht en in orde bevonden: het updatepad (vaste HTTPS, niet-geëxporteerde result-receiver, setPackage, handtekeningcontrole door het platform), de JSON-verwerking, de knop-callbacks en de placeholder-detectie.

Hoort bij: ha-pipup v1.11.2, die een oneindige camera-popup na 24 uur op zwart en een timer die z'n entity kon overleven verhelpt.

v0.10.0 — status screen: calm, readable, honest about what is optional

Choose a tag to compare

@github-actions github-actions released this 22 Aug 14:47
748e31a

English

All three from one field report: an update that "failed", a Fix button that never went away, and status text that was very difficult to see.

The Fix button that never goes away

A design bug in the permission panel, not a permission problem on your TV. A TV without the screen-off grants showed a permanent yellow MISSING with a Fix button — for a feature that is entirely optional — so people understandably kept pressing it through disables, enables and reboots. Screen on/off is now one calm line: green configured (via …) when either route works, neutral optional, not configured with one explanatory sentence when neither does. Required permissions (overlay, self-update) keep the loud treatment. The difference between a problem and an option is the whole point of the panel.

Readability

  • The permission panel starts mid-screen (compact header; the panel gets the whole lower half), so on most devices nothing needs scrolling anymore.
  • Text sizes go from 14/12/11sp to 18/15/14sp — this is a 10-foot UI.

About the failed update

That half of the report lives in the integration: ha-pipup v1.11.1 exposes install_error, install_permission and requires_remote on the update entity. Two things worth knowing either way: any adb install -r silently resets the install permission ("granted long ago" is routinely true and irrelevant), and Android < 12 shows the system's install confirmation on the TV, which someone has to accept with the remote.


Nederlands

Alle drie uit één praktijkmelding: een update die "faalde", een repareerknop die nooit wegging, en statustekst die slecht leesbaar was.

De repareerknop die nooit weggaat

Een ontwerpfout in het permissiepaneel, geen permissieprobleem op de tv. Een tv zonder de scherm-uit-rechten toonde een permanente gele ONTBREEKT met repareerknop — voor een functie die volledig optioneel is — dus mensen bleven er begrijpelijkerwijs op drukken, door disables, enables en reboots heen. Scherm aan/uit is nu één rustige regel: groen ingesteld (via …) als één van beide routes werkt, neutraal optioneel, niet ingesteld met één zin uitleg als geen van beide is ingericht. Verplichte permissies (overlay, zelf-updaten) houden de luide opmaak. Het verschil tussen een probleem en een optie is precies waar het paneel voor bestaat.

Leesbaarheid

  • Het permissiepaneel begint midden op het scherm (compacte kop; het paneel krijgt de hele onderste helft), dus op de meeste toestellen hoeft er niets meer gescrold te worden.
  • Tekstgroottes van 14/12/11sp naar 18/15/14sp — dit is een 10-foot-UI.

Over de mislukte update

Die helft van de melding zit in de integratie: ha-pipup v1.11.1 toont install_error, install_permission en requires_remote op de update-entity. Twee dingen die hoe dan ook goed zijn om te weten: elke adb install -r reset stilletjes de installatiepermissie ("lang geleden toegekend" is geregeld waar én irrelevant), en Android < 12 toont de systeembevestiging op de tv, die iemand met de afstandsbediening moet accepteren.

v0.9.1 — device admin: report what is observable

Choose a tag to compare

@github-actions github-actions released this 22 Aug 14:28
892dc5e

English

Reporting fix on 0.9.0. /state could contradict itself:

"power":       { "canSleep": true, "sleepMethod": "device_admin" }
"permissions": { "deviceAdmin": null }

Cause is hasSystemFeature(FEATURE_DEVICE_ADMIN), which is false on a Fire TV stick (Fire OS 11) whose admin is registered and whose lockNow() works. Measured across four devices, the flag is wrong in both directions:

device feature flag admin registers
Fire TV stick, Fire OS 9 true yes
Fire TV stick, Fire OS 11 false yes
Nokia Streaming Box 8010 (Android 14) false no — while dpm still prints Success
TCL Google TV (Android 11) false no — while dpm still prints Success

An active admin is proof and now outranks the flag; null means only "not active, and no sign the platform supports it". The device-admin fix button no longer hides behind the flag either — the honest filter is the placeholder check that already refuses Fire OS's CTSDummyDeviceAdminActivity.

No behaviour change to screen on/off: that was already driven by isAdminActive.


Nederlands

Rapportagefix op 0.9.0. /state kon zichzelf tegenspreken: power.sleepMethod: "device_admin" naast permissions.deviceAdmin: null.

Oorzaak is hasSystemFeature(FEATURE_DEVICE_ADMIN), die false meldt op een Fire TV-stick (Fire OS 11) waar de admin geregistreerd staat en lockNow() gewoon werkt. Over vier toestellen gemeten is die vlag in beide richtingen fout:

toestel feature-vlag admin registreert
Fire TV-stick, Fire OS 9 true ja
Fire TV-stick, Fire OS 11 false ja
Nokia Streaming Box 8010 (Android 14) false nee — terwijl dpm tóch Success meldt
TCL Google TV (Android 11) false nee — terwijl dpm tóch Success meldt

Een actieve admin is bewijs en gaat nu vóór de vlag; null betekent alleen nog "niet actief, en geen enkel teken dat het platform het ondersteunt". De repareerknop voor apparaatbeheerder verstopt zich ook niet meer achter die vlag — de eerlijke filter is de placeholder-check, die Fire OS' CTSDummyDeviceAdminActivity al weigert.

Aan scherm aan/uit verandert niets: dat liep al op isAdminActive.