Skip to main content

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​

ParameterTypeDescription
onChange(interactive: boolean) => voidCalled 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​

ParameterType
otherHybridObject<{ 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​

ParameterType
listenerIdnumber

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