diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-03 13:36:19 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-03 14:24:54 +0200 |
| commit | 1f19ccaa583734951d5fcccebb06b073a2b1a111 (patch) | |
| tree | b8c1e9f33b8fdb8251eb7308f10eb1e4dd87fd2a /packages/meshbay-android/app/src | |
| parent | 67af4248c97d2e1568e5c22179fa0026dbbc5219 (diff) | |
| download | meshbay-1f19ccaa583734951d5fcccebb06b073a2b1a111.tar.gz | |
fix(android): cast context created at launch, session found if its callback is missed
As the SDK recommends; and a connected session the listener did not hear of
still counts, so a missed callback no longer fails the cast.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-android/app/src')
| -rw-r--r-- | packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/MainActivity.kt | 1 | ||||
| -rw-r--r-- | packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/cast/CastControl.kt | 29 |
2 files changed, 28 insertions, 2 deletions
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 23df907..a781350 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 @@ -86,6 +86,7 @@ class MainActivity : Activity() { hasCatalogue = { code -> hasAsset("ui/locales/$code.js") }, keys = keys, saves = saves, cast = cast) WebViewCompat.addWebMessageListener(web, Bridge.PORT, setOf(UiAssets.ORIGIN), Bridge(channels)) + cast.control.warmUp() installShim() web.loadUrl(UiAssets.START) } diff --git a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/cast/CastControl.kt b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/cast/CastControl.kt index 8b5d8e1..9f47f42 100644 --- a/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/cast/CastControl.kt +++ b/packages/meshbay-android/app/src/main/kotlin/org/meshbay/client/cast/CastControl.kt @@ -65,6 +65,17 @@ class CastControl(private val context: Context) { private fun need() { if (!available()) throw Refused("Casting is not available on this device") } + /** + * Create the cast context at launch, as the SDK asks. Created only at the + * first connect, it was born in the same moment the route was selected, + * and the session started without the listener hearing of it: on a fresh + * start the first cast timed out, every time (measured). + */ + fun warmUp() { + if (!available()) return + try { onMain { CastContext.getSharedInstance(context) } } catch (e: Exception) { Log.w(TAG, "cast context", e) } + } + private fun <T> onMain(timeoutS: Long = 10, block: () -> T): T { if (Looper.myLooper() == Looper.getMainLooper()) return block() val done = CountDownLatch(1) @@ -132,8 +143,22 @@ class CastControl(private val context: Context) { when (s) { is CastSession -> s is Pending -> try { - if (!s.done.await(15, TimeUnit.SECONDS)) throw IllegalStateException("Connection timeout") - s.session() ?: throw IllegalStateException("The receiver refused the connection") + // The listener, or the session manager itself: a started + // session the listener missed is still a started session. + val deadline = System.currentTimeMillis() + 15_000 + var found: CastSession? = null + while (found == null && System.currentTimeMillis() < deadline) { + if (s.done.await(300, TimeUnit.MILLISECONDS)) { + found = s.session() ?: throw IllegalStateException("The receiver refused the connection") + } else { + found = onMain { + CastContext.getSharedInstance(context).sessionManager.currentCastSession + ?.takeIf { it.isConnected } + } + if (found != null) Log.i(TAG, "session found connected without its callback") + } + } + found ?: throw IllegalStateException("Connection timeout") } finally { main.post { s.cleanup() } } else -> throw IllegalStateException() } |