aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-android/app/src')
-rw-r--r--packages/meshbay-android/app/src/main/assets/bridge/meshbay-bridge.js39
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt1
-rw-r--r--packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/bridge/Channels.kt2
3 files changed, 42 insertions, 0 deletions
diff --git a/packages/meshbay-android/app/src/main/assets/bridge/meshbay-bridge.js b/packages/meshbay-android/app/src/main/assets/bridge/meshbay-bridge.js
index e8b40b2d..e78a2337 100644
--- a/packages/meshbay-android/app/src/main/assets/bridge/meshbay-bridge.js
+++ b/packages/meshbay-android/app/src/main/assets/bridge/meshbay-bridge.js
@@ -46,6 +46,45 @@
port.postMessage(JSON.stringify({ id, ch: channel, args }));
});
+ // The Screen Wake Lock API, which Chrome has and the WebView does not: the
+ // video player (and music, when asked) holds it so the screen does not time
+ // out mid-film. Held natively as the WebView's keepScreenOn, and released
+ // when the page hides, as the API does. Cleared first, for a reload that
+ // left one held.
+ if (!('wakeLock' in navigator)) {
+ const held = new Set();
+ const sync = () => call('screen:keep-on', held.size > 0).catch(() => {});
+ class WakeLockSentinel extends EventTarget {
+ constructor() { super(); this.type = 'screen'; this.released = false; this.onrelease = null; }
+ release() {
+ if (!this.released) {
+ this.released = true;
+ held.delete(this);
+ sync();
+ const event = new Event('release');
+ if (typeof this.onrelease === 'function') this.onrelease(event);
+ this.dispatchEvent(event);
+ }
+ return Promise.resolve();
+ }
+ }
+ const request = (type) => {
+ if (type !== 'screen') return Promise.reject(new TypeError('Unsupported wake lock type'));
+ if (document.visibilityState !== 'visible') {
+ return Promise.reject(new DOMException('The page is not visible', 'NotAllowedError'));
+ }
+ const sentinel = new WakeLockSentinel();
+ held.add(sentinel);
+ sync();
+ return Promise.resolve(sentinel);
+ };
+ document.addEventListener('visibilitychange', () => {
+ if (document.visibilityState !== 'visible') [...held].forEach((s) => s.release());
+ });
+ Object.defineProperty(navigator, 'wakeLock', { value: Object.freeze({ request }) });
+ sync();
+ }
+
// A write is a binary message: "MBB1" | id | channel | 0 | handle | bytes,
// big-endian — one copy, no JSON, no base64 (spike S-3: 136 MB/s awaited
// per 48 KB chunk). Without ArrayBuffer messages, base64 over JSON.
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
index 75ac0156..e60535b9 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt
@@ -134,6 +134,7 @@ class MainActivity : Activity() {
channels = Channels(hub, onHubChanged = { runOnUiThread { reloadForHub() } },
hasCatalogue = { code -> hasAsset("ui/locales/$code.js") }, keys = keys, saves = saves,
cast = cast, onPlayback = { on -> runOnUiThread { playing = on; keepAlive() } },
+ onKeepScreenOn = { on -> runOnUiThread { web.keepScreenOn = on } },
push = PushChannels(this, PushState(getSharedPreferences(PushState.PREFS, Context.MODE_PRIVATE)),
channelNames = { mapOf(
Notifier.CHANNEL_CHAT to text.get("push.channel_chat", channels.locale),
diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/bridge/Channels.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/bridge/Channels.kt
index 19b0f3c2..1563810b 100644
--- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/bridge/Channels.kt
+++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/bridge/Channels.kt
@@ -32,6 +32,7 @@ class Channels(
private val saves: SaveSinks? = null,
private val cast: CastChannels? = null,
private val onPlayback: (Boolean) -> Unit = {},
+ private val onKeepScreenOn: (Boolean) -> Unit = {},
private val push: PushChannels? = null,
private val photos: PhotoChannels? = null,
private val destinations: DestinationChannels? = null,
@@ -48,6 +49,7 @@ class Channels(
"ice:resolve-stun" -> resolveStun(args.optJSONArray(0) ?: JSONArray())
"ui:locale" -> setLocale(args.optString(0, ""))
"playback:keep-alive" -> { onPlayback(args.optBoolean(0, false)); true }
+ "screen:keep-on" -> { onKeepScreenOn(args.optBoolean(0, false)); true }
// Where downloads go, chosen once; a display name, never a URI.
"folder:choose" -> saves().chooseFolder()