Interface: RnMediaScreenState
Defined in: packages/player/src/specs/screen-state.nitro.ts:40
Whether the device's display is currently on ("interactive"), and a notification when that changes.
Remarks
Why this exists at all. React Native's AppState answers a different
question — "is this app's Activity/Scene in the foreground" — and on Android
the two answers are not the same fact. A screen-off soak on a Poco F4 (MIUI,
charging) recorded AppState reporting active again while the display
stayed off: subscribed at 11:25, paused at 11:36 ("not in the foreground"),
re-subscribed at 11:43 with the screen still off, paused again at 11:53.
OEM lifecycle churn (a resumed Activity behind the keyguard, a doze/charging
overlay) flaps AppState for reasons that have nothing to do with whether a
frame can be seen — and while it says active, everything gated on it runs.
With the visualizer that measured 65-80 % of a core, drawing to a display
that was off.
PowerManager.isInteractive() plus ACTION_SCREEN_ON/ACTION_SCREEN_OFF is
the platform's own answer to "is the display on", and it is the one signal
MIUI cannot flap: it is the display state.
This is a device-global fact, so this object is a singleton — one display
per device, exactly like audio focus is one focus per device (CLAUDE.md §5:
singletons only where the OS itself is singular). It lives in
@afkcodes/timbre-player rather than in @afkcodes/timbre-audio-session because its only
consumer is the player's visualizer, and a player-only install must not have
to pull in a second native module to stop burning battery.
iOS has nothing to implement. Locking an iPhone (or the display
auto-sleeping) resigns the app's active state and moves it to the background,
which AppState reports as 'inactive' then 'background'. There is no iOS
state in which the app is foreground-active with the display off, and no
public API for the display's power state either — so the platform truth and
AppState agree by construction and the C++ implementation answers a
constant true. See the class comment on
cpp/HybridRnMediaScreenState.hpp.
Extends
HybridObject<{android:"kotlin";ios:"c++"; }>
Properties
interactive
readonly interactive: boolean;
Defined in: packages/player/src/specs/screen-state.nitro.ts:53
true while the display is on.
Android: PowerManager.isInteractive(). Note this is display on, not
unlocked: a device showing the lock screen is interactive, which is
correct — a lock-screen widget or an always-on surface can be presenting.
iOS: always true (see the interface remarks).
name
readonly name: string;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:52
The HybridObject's name.
Inherited from
HybridObject.name
Methods
addScreenStateListener()
addScreenStateListener(onChange: (interactive: boolean) => void): number;
Defined in: packages/player/src/specs/screen-state.nitro.ts:70
Observe display-state changes.
Parameters
| Parameter | Type | Description |
|---|---|---|
onChange | (interactive: boolean) => void | Called with the new value on every transition, never for the current one — read interactive for that. |
Returns
number
An id to hand back to removeScreenStateListener. Ids are
used rather than function identity for the reason
@afkcodes/timbre-audio-session documents: a Nitro callback is an opaque native
closure and cannot be compared across the bridge.
Remarks
The native receiver is derived from the listener set — registered on the
first listener, unregistered on the last — so a process with nothing
observing the display holds no BroadcastReceiver at all.
dispose()
dispose(): void;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:94
Disposes any resources this HybridObject might hold natively,
and releases this HybridObject's NativeState.
After calling (), this object can no longer be used.
Eagerly disposing a HybridObject could be beneficial for a queue-/handler-architecture
where a bunch of Hybrid Objects are allocated, and later deallocated once a callback (e.g. a render function)
completes.
Returns
void
Note
It is NOT required to call () manually, as the JavaScript
Garbage Collector automatically disposes and releases any resources when needed.
It is purely optional to eagerly-, and manually-, call () here - use with caution!
Inherited from
HybridObject.dispose
equals()
equals(other: HybridObject<{
android: "kotlin";
ios: "c++";
}>): boolean;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:79
Returns whether this HybridObject is the same object as other.
While two HybridObjects might not be equal when compared with ==, they might still
hold the same underlying HybridObject, in which case equals(other)
will return true.
Parameters
| Parameter | Type |
|---|---|
other | HybridObject<{ android: "kotlin"; ios: "c++"; }> |
Returns
boolean
Example
const hybridA = SomeModule.getExistingHybridInstance()
const hybridB = SomeModule.getExistingHybridInstance()
console.log(hybridA.equals(hybridB)) // true
Inherited from
HybridObject.equals
removeScreenStateListener()
removeScreenStateListener(listenerId: number): void;
Defined in: packages/player/src/specs/screen-state.nitro.ts:72
Remove a listener added by addScreenStateListener.
Parameters
| Parameter | Type |
|---|---|
listenerId | number |
Returns
void
toString()
toString(): string;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:64
Returns a string representation of the given HybridObject.
Unless overridden by the HybridObject, this will return the name of the object.
Returns
string
Example
const hybridA = SomeModule.getExistingHybridInstance()
console.log(hybridA.toString()) // [HybridObject HybridA]
Inherited from
HybridObject.toString