aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/main/kotlin/org
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-android/app/src/main/kotlin/org')
-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/cast/CastControl.kt29
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()
}