diff options
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() } |