VancedMicroG/play-services-core/src/main/kotlin/org/microg/gms/gcm/ServiceInfo.kt

85 lines
3.5 KiB
Kotlin

/*
* SPDX-FileCopyrightText: 2020, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.gcm
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.Serializable
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
private const val ACTION_SERVICE_INFO_REQUEST = "org.microg.gms.gcm.SERVICE_INFO_REQUEST"
private const val ACTION_SERVICE_INFO_RESPONSE = "org.microg.gms.gcm.SERVICE_INFO_RESPONSE"
private const val EXTRA_SERVICE_INFO = "org.microg.gms.gcm.SERVICE_INFO"
private const val TAG = "GmsGcmStatusInfo"
data class ServiceInfo(val configuration: ServiceConfiguration, val connected: Boolean, val startTimestamp: Long, val learntMobileInterval: Int, val learntWifiInterval: Int, val learntOtherInterval: Int) : Serializable
data class ServiceConfiguration(val enabled: Boolean, val mobile: Int, val wifi: Int, val roaming: Int, val other: Int) : Serializable
private fun GcmPrefs.toConfiguration(): ServiceConfiguration = ServiceConfiguration(isEnabled, networkMobile, networkWifi, networkRoaming, networkOther)
class ServiceInfoReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
try {
context.sendOrderedBroadcast(Intent(ACTION_SERVICE_INFO_RESPONSE).apply {
setPackage(context.packageName)
val prefs = GcmPrefs.get(context)
val info = ServiceInfo(
configuration = prefs.toConfiguration(),
connected = McsService.isConnected(context),
startTimestamp = McsService.getStartTimestamp(),
learntMobileInterval = prefs.learntMobileInterval,
learntWifiInterval = prefs.learntWifiInterval,
learntOtherInterval = prefs.learntOtherInterval
)
putExtra(EXTRA_SERVICE_INFO, info)
}, null)
} catch (e: Exception) {
Log.w(TAG, e)
}
}
}
private suspend fun sendToServiceInfoReceiver(intent: Intent, context: Context): ServiceInfo = suspendCoroutine {
context.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
context.unregisterReceiver(this)
val serviceInfo = try {
intent.getSerializableExtra(EXTRA_SERVICE_INFO) as ServiceInfo
} catch (e: Exception) {
it.resumeWithException(e)
return
}
try {
it.resume(serviceInfo)
} catch (e: Exception) {
Log.w(TAG, e)
}
}
}, IntentFilter(ACTION_SERVICE_INFO_RESPONSE))
try {
context.sendOrderedBroadcast(intent, null)
} catch (e: Exception) {
it.resumeWithException(e)
}
}
suspend fun getGcmServiceInfo(context: Context): ServiceInfo = sendToServiceInfoReceiver(
// this is still using a broadcast, because it calls into McsService in the persistent process
Intent(context, ServiceInfoReceiver::class.java).apply {
action = ACTION_SERVICE_INFO_REQUEST
}, context)
suspend fun setGcmServiceConfiguration(context: Context, configuration: ServiceConfiguration) = withContext(Dispatchers.IO) {
GcmPrefs.write(context, configuration)
}