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