Vega ambient mode / Idle behavior

We’re seeing our app get killed whenever the Fire TV Stick 4K Select goes idle and the display sleeps. When the device wakes, we land back on the system launcher instead of our app, so the user loses their place entirely. We wanted to understand whether this is expected behavior on this device, and if there’s a supported way to keep the app alive (or at least be notified so we can save/restore state cleanly).

  1. The idle handler reports the screensaver is disabled by policy, then forces the display off:
lcm-idle-handler: Screensaver disabled by policy
api:PowerManagerExt:forceDisplayOff be called
  1. The display transitions to SLEEP, and the LCM appears to treat this as a display disconnection — it clears the backstack and kills our process:
lcm-dsmonitor: Got 'PowerEvent': displayId[0]: SLEEP
lcm-display-orchestrator: Display power state change from ACTIVE to SLEEP
lcm-display-context: display[0]: Clearing backstack, clear all true
lcm-display-registry: Killed processes in response to display disconnection:  7069 1844
lcm-server: Deregistering application with clientPid 7069 and package id com.fast.react_native after crash
(PID 7069 is our app.)

For context, the goal is for users to resume where they left off after the screensaver, rather than being dropped back at the home screen. Any guidance on the intended pattern for this device would be hugely helpful.

We understand the app will be killed on idle, we’re not asking to run two apps concurrently. We’re asking whether there’s any supported way to either (a) survive display sleep and resume on wake, or (b) auto-relaunch the last app on wake instead of returning to the launcher. If neither is supported, we’ll explore implementing some sort of app on the pre-kill notification, can you confirm that’s the intended pattern and which event we should hook?

We tested it out on the 4K Select and can confirm the split:

Ambient mode on: idle hands off to the screensaver, display stays active, our app just backgrounds normally - comes right back on the same process when you hit a button, no kill, no relaunch.

Ambient mode off: idle can’t find a screensaver to hand off to, so it goes straight to force-display-off > display sleep > treated as an HDMI disconnect > our app gets killed > user’s back at the home screen on wake.

Since we don’t have any way to control/request ambient mode ourselves (that’s purely an end-user setting), is there anything else we can do on our end to avoid the app getting killed when the display actually goes to sleep? Is there some capability or manifest flag that tells LCM to just background us instead of treating display-off as a disconnect? Or is that display-sleep = terminate behavior just hardcoded and not something apps can opt out of?

Basically trying to figure out if this is a dead end (and we just build cold-relaunch + restore-state for that case), or if there’s still a lever we haven’t found.

A few specific questions:

  1. Is “Killed processes in response to display disconnection” expected when the panel simply sleeps on this device, or is the system misinterpreting a normal display-off as a physical disconnect?
  2. We set LIFESPAN_POLICY.PERMANENT via TimeoutManager. We can see the timeout handler honoring it (appInst[89] Timeout is undefined/permanent, skipping timer action), but the process is still killed by the display-registry path above - which seems to ignore the lifespan policy entirely. Is the lifespan policy ever meant to protect against the display-sleep kill, or only against the inactivity-timeout kill? (Separately, TimeoutManager logs “Feature is not supported on this platform” on the 4K Select - is that API supported here at all?)
  3. Is “Screensaver disabled by policy” something we (or the device config) control? Would enabling a screensaver/ambient component change whether the app is killed on display-off?
  4. Is there any supported mechanism on the 4K Select to keep a foreground app alive across display sleep, or a lifecycle callback we can subscribe to before the kill so we can persist our navigation/UI state and restore it on relaunch?

Hi @Jon_Page,

Thank you for the thorough investigation and clear log analysis. Your reading of the system behavior is accurate. Let me address your specific questions:

  1. Is “Killed processes in response to display disconnection” expected when the panel sleeps?

Yes - this is confirmed expected behavior on the Fire TV Stick 4K Select with Ambient mode disabled. When there’s no screensaver to hand off to, the idle handler calls power-service-core → forceDisplayOff, which LCM treats as a display disconnection. This clears the backstack and terminates foreground apps.

  1. Does LIFESPAN_POLICY.PERMANENT protect against the display-sleep kill?

No. LIFESPAN_POLICY.PERMANENT and TimeoutManager only control the app inactivity timeout (the screensaver path). The power-service-core → forceDisplayOff path operates at a lower system level and is independent of app lifecycle policies.

  1. Would enabling a screensaver/ambient component change the behavior?

Yes - this is the key difference you’ve already identified. When Ambient mode is ON, the idle handler hands off to the screensaver instead of forcing display-off. The display stays active, your app backgrounds normally, and resumes on button press without being killed. When Ambient mode is OFF, the system goes directly to forceDisplayOff → display disconnect → process kill.

However, this is an end-user setting - there is no manifest flag or API for apps to request or require Ambient mode.

  1. Is there a supported mechanism to keep the app alive across display sleep, or a pre-kill callback?

Currently, no. There is no public manifest privilege, Kepler API, or VDA command that allows a 3P app to override the forceDisplayOff behavior. The display-sleep kill does not provide a graceful pre-termination callback through the standard app lifecycle.

Recommended approach: Build cold-relaunch + state restore

Since surviving display-sleep is not supported, the intended pattern is:

  1. Use AppState to detect when your app is being backgrounded and persist your navigation/UI state (e.g., to AsyncStorage or another local persistence mechanism). See: Transition App State between Background and Foreground ( Transition App State between Background and Foreground | Design and Develop Vega Apps )
  2. On app launch, check for saved state and restore the user’s position (screen, playback progress, etc.) so the cold relaunch feels seamless.
  3. Note that AppState may not fire before a force-kill. As a defensive measure, consider periodically persisting critical state (e.g., current screen, playback position) rather than only on the background event.

Thanks,
Aishwarya