mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2024-12-28 13:45:50 +01:00
EN: Make service more robust against exceptions while processing app input
This commit is contained in:
parent
45d4dffb88
commit
91c8e43ab9
@ -12,6 +12,7 @@ import android.content.*
|
||||
import android.os.*
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.gms.common.api.Status
|
||||
@ -19,6 +20,8 @@ import com.google.android.gms.nearby.exposurenotification.*
|
||||
import com.google.android.gms.nearby.exposurenotification.ExposureNotificationStatusCodes.*
|
||||
import com.google.android.gms.nearby.exposurenotification.internal.*
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@ -37,6 +40,8 @@ import kotlin.random.Random
|
||||
|
||||
class ExposureNotificationServiceImpl(private val context: Context, private val lifecycle: Lifecycle, private val packageName: String) : INearbyExposureNotificationService.Stub(), LifecycleOwner {
|
||||
|
||||
private fun LifecycleCoroutineScope.launchSafely(block: suspend CoroutineScope.() -> Unit): Job = launchWhenStarted { try { block() } catch (e: Exception) { Log.w(TAG, "Error in coroutine", e) } }
|
||||
|
||||
override fun getLifecycle(): Lifecycle = lifecycle
|
||||
|
||||
private fun pendingConfirm(permission: String): PendingIntent {
|
||||
@ -102,7 +107,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun start(params: StartParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val isAuthorized = ExposureDatabase.with(context) { it.isAppAuthorized(packageName) }
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter()
|
||||
val status = if (isAuthorized && ExposurePreferences(context).enabled) {
|
||||
@ -131,7 +136,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun stop(params: StopParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val isAuthorized = ExposureDatabase.with(context) { database ->
|
||||
database.isAppAuthorized(packageName).also {
|
||||
if (it) database.noteAppAction(packageName, "stop")
|
||||
@ -149,7 +154,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun isEnabled(params: IsEnabledParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val isAuthorized = ExposureDatabase.with(context) { database ->
|
||||
database.isAppAuthorized(packageName)
|
||||
}
|
||||
@ -162,7 +167,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getTemporaryExposureKeyHistory(params: GetTemporaryExposureKeyHistoryParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val status = confirmPermission(CONFIRM_ACTION_KEYS)
|
||||
val response = when {
|
||||
status.isSuccess -> ExposureDatabase.with(context) { database ->
|
||||
@ -243,7 +248,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
override fun provideDiagnosisKeys(params: ProvideDiagnosisKeysParams) {
|
||||
val token = params.token ?: TOKEN_A
|
||||
Log.w(TAG, "provideDiagnosisKeys() with $packageName/$token")
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val tid = ExposureDatabase.with(context) { database ->
|
||||
val configuration = params.configuration
|
||||
if (configuration != null) {
|
||||
@ -259,7 +264,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Callback failed", e)
|
||||
}
|
||||
return@launchWhenStarted
|
||||
return@launchSafely
|
||||
}
|
||||
ExposureDatabase.with(context) { database ->
|
||||
val start = System.currentTimeMillis()
|
||||
@ -289,21 +294,25 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
params.keyFileSupplier?.let { keyFileSupplier ->
|
||||
Log.d(TAG, "Using key file supplier")
|
||||
while (keyFileSupplier.isAvailable && keyFileSupplier.hasNext()) {
|
||||
try {
|
||||
val cacheFile = File(context.cacheDir, "en-keyfile-${System.currentTimeMillis()}-${Random.nextInt()}.zip")
|
||||
ParcelFileDescriptor.AutoCloseInputStream(keyFileSupplier.next()).use { it.copyToFile(cacheFile) }
|
||||
val hash = MessageDigest.getInstance("SHA-256").digest(cacheFile)
|
||||
val storedKeys = database.storeDiagnosisFileUsed(tid, hash)
|
||||
if (storedKeys != null) {
|
||||
keys += storedKeys.toInt()
|
||||
cacheFile.delete()
|
||||
} else {
|
||||
todoKeyFiles.add(cacheFile to hash)
|
||||
try {
|
||||
while (keyFileSupplier.isAvailable && keyFileSupplier.hasNext()) {
|
||||
try {
|
||||
val cacheFile = File(context.cacheDir, "en-keyfile-${System.currentTimeMillis()}-${Random.nextInt()}.zip")
|
||||
ParcelFileDescriptor.AutoCloseInputStream(keyFileSupplier.next()).use { it.copyToFile(cacheFile) }
|
||||
val hash = MessageDigest.getInstance("SHA-256").digest(cacheFile)
|
||||
val storedKeys = database.storeDiagnosisFileUsed(tid, hash)
|
||||
if (storedKeys != null) {
|
||||
keys += storedKeys.toInt()
|
||||
cacheFile.delete()
|
||||
} else {
|
||||
todoKeyFiles.add(cacheFile to hash)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Failed parsing file", e)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Failed parsing file", e)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Disconnected from key file supplier", e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,7 +398,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getExposureSummary(params: GetExposureSummaryParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val response = buildExposureSummary(params.token)
|
||||
|
||||
ExposureDatabase.with(context) { database ->
|
||||
@ -413,7 +422,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getExposureInformation(params: GetExposureInformationParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
ExposureDatabase.with(context) { database ->
|
||||
val pair = database.loadConfiguration(packageName, params.token)
|
||||
val response = if (pair != null && database.isAppAuthorized(packageName)) {
|
||||
@ -494,7 +503,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getExposureWindows(params: GetExposureWindowsParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val response = getExposureWindowsInternal(params.token ?: TOKEN_A)
|
||||
|
||||
ExposureDatabase.with(context) { database ->
|
||||
@ -529,7 +538,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getDailySummaries(params: GetDailySummariesParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val response = getExposureWindowsInternal().groupBy { it.dateMillisSinceEpoch }.map {
|
||||
val map = arrayListOf<DailySummary.ExposureSummaryData>()
|
||||
for (i in 0 until ReportType.VALUES) {
|
||||
@ -564,7 +573,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun setDiagnosisKeysDataMapping(params: SetDiagnosisKeysDataMappingParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
ExposureDatabase.with(context) { database ->
|
||||
database.storeConfiguration(packageName, TOKEN_A, params.mapping)
|
||||
database.noteAppAction(packageName, "setDiagnosisKeysDataMapping")
|
||||
@ -578,7 +587,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
}
|
||||
|
||||
override fun getDiagnosisKeysDataMapping(params: GetDiagnosisKeysDataMappingParams) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
val mapping = ExposureDatabase.with(context) { database ->
|
||||
val triple = database.loadConfiguration(packageName, TOKEN_A)
|
||||
database.noteAppAction(packageName, "getDiagnosisKeysDataMapping")
|
||||
@ -594,7 +603,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
|
||||
override fun getPackageConfiguration(params: GetPackageConfigurationParams) {
|
||||
Log.w(TAG, "Not yet implemented: getPackageConfiguration")
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
ExposureDatabase.with(context) { database ->
|
||||
database.noteAppAction(packageName, "getPackageConfiguration")
|
||||
}
|
||||
@ -608,7 +617,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
||||
|
||||
override fun getStatus(params: GetStatusParams) {
|
||||
Log.w(TAG, "Not yet implemented: getStatus")
|
||||
lifecycleScope.launchWhenStarted {
|
||||
lifecycleScope.launchSafely {
|
||||
ExposureDatabase.with(context) { database ->
|
||||
database.noteAppAction(packageName, "getStatus")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user