Skip to content

feat: SDK 0.4.12/0.3.14, background-streaming bridges, one-shot conne…#9

Merged
AdrianLea merged 3 commits into
mainfrom
feat/sdk-0.4.12-background-streaming
Jul 14, 2026
Merged

feat: SDK 0.4.12/0.3.14, background-streaming bridges, one-shot conne…#9
AdrianLea merged 3 commits into
mainfrom
feat/sdk-0.4.12-background-streaming

Conversation

@AdrianLea

Copy link
Copy Markdown
Contributor

SDK 0.4.12 / 0.3.14, background-streaming bridges, one-shot connectDevice promise

Bumps both native SDK pins and exposes the new background-streaming capabilities to React Native. Wrapper version → 0.2.7.

⚠️ Behavior change: ACCELERATION units

The pinned SDKs change ACCELERATION to gravity-compensated linear acceleration in SI units (m/s²) on both platforms — a device at rest reports ≈ [0, 0, 0], and iPhone/Android now report identical semantics. Apps interpreting acceleration values should update before adopting 0.2.7.

SDK bumps (the point of this release)

  • terra-rtandroid 0.4.11 → 0.4.12 — streaming survives screen lock/backgrounding (SDK-managed foreground service + wake lock), websocket auto-reconnection with capped backoff (network drops no longer permanently kill streams), NPE fixes on connection switching, and startRealtime no longer starts the service for devices that aren't actually connected.
  • TerraRTiOS 0.3.13 → 0.3.14 — fixes a stack-overflow crash in the websocket receive loop under buffered message delivery, pedometer data types no longer silently dropped mid-update, and stopStream correctly stops device-motion updates.

New API (Android; typed no-ops on iOS)

startForegroundService(notificationTitle, notificationText)
stopForegroundService()
isIgnoringBatteryOptimizations(): Promise<boolean>
requestIgnoreBatteryOptimizations(): Promise<boolean>

The foreground service itself starts/stops automatically with startRealtime/stopRealtime as of 0.4.12 — startForegroundService exists to customize the persistent notification. The battery-optimization pair matters on aggressive OEMs (MIUI etc.) that kill even foreground services without an exemption; apps can check and offer the one-tap system dialog in-flow.

Fixed

  • connectDevice() resolved its promise more than once — the native SDKs reuse the connection callback for every subsequent connection update (e.g. disconnect), so the settled promise got re-resolved and red-boxed in dev ("Tried to resolve a promise more than once"). Both bridges now guard for exactly-once resolution.

Tests

Replaced the it.todo placeholder with real coverage of the new API: Android calls forward to the native module with correct arguments; iOS resolves as no-ops without touching it. The connectDevice guard is native code, exercised on-device (below) rather than in jest.

Verified

End to end via the Terra Grip demo app (BLE, phone sensors, Apple Watch): locked-screen streaming on Android through multi-hundred-update sessions, reconnection after signal loss, and device-switch/unpair flows no longer warn. yarn lint, yarn typecheck, yarn test all green.

@AdrianLea

Copy link
Copy Markdown
Contributor Author

/sfs

@mep-y mep-y Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a pass — the android battery-optimization bridge isn't shippable yet.

design — standalone foreground-service start/stop is a bit awkward, but it mirrors the native surface this release is exposing, so i'm not asking for a bigger wrapper reshuffle here.
functionality — block on the new android battery-exemption API: isIgnoringBatteryOptimizations() can crash on api <23, and the prompt path needs a manifest permission this package doesn't add, so it resolves false unless apps wire extra setup themselves.
comments — clean.
tests — no test files touched in this pr.

For the non-technically inclined

one of the new Android battery-saver helpers can crash on older phones. The other won't actually open the opt-out prompt unless the app adds extra setup, so apps relying on background streaming will think they exposed a fix when they didn't.

prIQ: 91

Comment on lines +406 to +411
/** Whether the app is exempt from battery optimizations (aggressive OEMs kill streams otherwise). */
@ReactMethod
public void isIgnoringBatteryOptimizations(Promise promise){
PowerManager pm = (PowerManager) this.reactContext.getSystemService(Context.POWER_SERVICE);
promise.resolve(pm != null && pm.isIgnoringBatteryOptimizations(this.reactContext.getPackageName()));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls an API 23-only method unguarded, so older supported Android devices can crash here.

Suggested change
/** Whether the app is exempt from battery optimizations (aggressive OEMs kill streams otherwise). */
@ReactMethod
public void isIgnoringBatteryOptimizations(Promise promise){
PowerManager pm = (PowerManager) this.reactContext.getSystemService(Context.POWER_SERVICE);
promise.resolve(pm != null && pm.isIgnoringBatteryOptimizations(this.reactContext.getPackageName()));
}
/** Whether the app is exempt from battery optimizations (aggressive OEMs kill streams otherwise). */
@ReactMethod
public void isIgnoringBatteryOptimizations(Promise promise){
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
promise.resolve(true);
return;
}
PowerManager pm = (PowerManager) this.reactContext.getSystemService(Context.POWER_SERVICE);
promise.resolve(pm != null && pm.isIgnoringBatteryOptimizations(this.reactContext.getPackageName()));
}

@AdrianLea

Copy link
Copy Markdown
Contributor Author

/sfs

@mep-y mep-y Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed prior round, lgtm — the android battery-optimization bridge now guards pre-23 and ships the required permission.

lgtm

prIQ: 100

@AdrianLea
AdrianLea merged commit 5ca42e7 into main Jul 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants