package io.oxygenhub.android import android.app.Application import android.os.Build import android.util.Log import io.oxygenhub.android.alerts.PushAlerts import io.oxygenhub.android.api.DeviceAuth import io.oxygenhub.android.api.HubClient import io.oxygenhub.android.api.HubDeviceAuth import io.oxygenhub.android.api.hubHttpClient import io.oxygenhub.android.auth.KeystoreSessionStore import io.oxygenhub.android.auth.SessionManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.launch import okhttp3.OkHttpClient /** The hub the app signs in to unless told otherwise. */ const val DEFAULT_HUB = "https://oxygenhub.io" /** The app's shared objects, made once. A small hand-made container: no DI framework yet. */ class AppContainer(app: Application) { val http: OkHttpClient = hubHttpClient() val sessions = SessionManager(KeystoreSessionStore(app)) { session, onUnauthorized -> HubClient(session.hub, session.token, http, onUnauthorized) } fun deviceAuth(hub: String): DeviceAuth = HubDeviceAuth(hub, http) /** What the app calls itself on the hub's /device page and token list. */ val clientName: String = "OxygenHub for Android on ${Build.MODEL}".take(80) } class OxygenHubApp : Application() { lateinit var container: AppContainer private set override fun onCreate() { super.onCreate() container = AppContainer(this) // Alerts from the hub (#16): each signed-in session registers this // phone; signing out revokes the token, which ends it on the hub. if (PushAlerts.available) { PushAlerts.start(this) CoroutineScope(SupervisorJob() + Dispatchers.IO).launch { container.sessions.session.filterNotNull().distinctUntilChanged().collect { val api = container.sessions.api() ?: return@collect runCatching { PushAlerts.register(this@OxygenHubApp, api) } .onFailure { Log.w("OxygenHubApp", "alerts: registering with the hub: ${it.message}") } } } } } }