OXYGENHUB
# 797eca1a3e64 oxygenhub-android / app / src / main / java / io / oxygenhub / android / OxygenHubApp.kt
2.2 KiB · last changed Alerts from the hub: the phone registers its Cloud Messaging token and an X25519 key kept by the Keystore, and opens and shows what the hub seals to it with the Rust core; Firebase from google-services.json (the release job's firebase-config secret); pins OxygenFlow main (refs #16) 8 days ago source blame history raw
5ae4af48 Andy McCall ↶ 1
package io.oxygenhub.android
2
3
import android.app.Application
4
import android.os.Build
aa21eb5e Andy McCall ↶ 5
import android.util.Log
6
import io.oxygenhub.android.alerts.PushAlerts
5ae4af48 Andy McCall ↶ 7
import io.oxygenhub.android.api.DeviceAuth
8
import io.oxygenhub.android.api.HubClient
9
import io.oxygenhub.android.api.HubDeviceAuth
10
import io.oxygenhub.android.api.hubHttpClient
11
import io.oxygenhub.android.auth.KeystoreSessionStore
12
import io.oxygenhub.android.auth.SessionManager
aa21eb5e Andy McCall ↶ 13
import kotlinx.coroutines.CoroutineScope
14
import kotlinx.coroutines.Dispatchers
15
import kotlinx.coroutines.SupervisorJob
16
import kotlinx.coroutines.flow.distinctUntilChanged
17
import kotlinx.coroutines.flow.filterNotNull
18
import kotlinx.coroutines.launch
5ae4af48 Andy McCall ↶ 19
import okhttp3.OkHttpClient
20
21
/** The hub the app signs in to unless told otherwise. */
22
const val DEFAULT_HUB = "https://oxygenhub.io"
23
24
/** The app's shared objects, made once. A small hand-made container: no DI framework yet. */
25
class AppContainer(app: Application) {
26
    val http: OkHttpClient = hubHttpClient()
27
28
    val sessions = SessionManager(KeystoreSessionStore(app)) { session, onUnauthorized ->
29
        HubClient(session.hub, session.token, http, onUnauthorized)
30
    }
31
32
    fun deviceAuth(hub: String): DeviceAuth = HubDeviceAuth(hub, http)
33
34
    /** What the app calls itself on the hub's /device page and token list. */
35
    val clientName: String = "OxygenHub for Android on ${Build.MODEL}".take(80)
36
}
37
38
class OxygenHubApp : Application() {
39
    lateinit var container: AppContainer
40
        private set
41
42
    override fun onCreate() {
43
        super.onCreate()
44
        container = AppContainer(this)
aa21eb5e Andy McCall ↶ 45
        // Alerts from the hub (#16): each signed-in session registers this
46
        // phone; signing out revokes the token, which ends it on the hub.
47
        if (PushAlerts.available) {
48
            PushAlerts.start(this)
49
            CoroutineScope(SupervisorJob() + Dispatchers.IO).launch {
50
                container.sessions.session.filterNotNull().distinctUntilChanged().collect {
51
                    val api = container.sessions.api() ?: return@collect
52
                    runCatching { PushAlerts.register(this@OxygenHubApp, api) }
53
                        .onFailure { Log.w("OxygenHubApp", "alerts: registering with the hub: ${it.message}") }
54
                }
55
            }
56
        }
5ae4af48 Andy McCall ↶ 57
    }
58
}