diff --git a/play-services-nearby-core/src/main/AndroidManifest.xml b/play-services-nearby-core/src/main/AndroidManifest.xml
index 83a8bda1..e40ecda8 100644
--- a/play-services-nearby-core/src/main/AndroidManifest.xml
+++ b/play-services-nearby-core/src/main/AndroidManifest.xml
@@ -14,6 +14,9 @@
+
+
+
@@ -24,6 +27,8 @@
+
+
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/AdvertiserService.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/AdvertiserService.kt
index 417aaf8e..d3e0b2e8 100644
--- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/AdvertiserService.kt
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/AdvertiserService.kt
@@ -76,7 +76,7 @@ class AdvertiserService : LifecycleService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
ForegroundServiceContext.completeForegroundService(this, intent, TAG)
super.onStartCommand(intent, flags, startId)
- if (ExposurePreferences(this).advertiserEnabled) {
+ if (ExposurePreferences(this).enabled) {
loopAdvertising()
} else {
stopSelf()
@@ -191,7 +191,7 @@ class AdvertiserService : LifecycleService() {
companion object {
fun isNeeded(context: Context): Boolean {
- return ExposurePreferences(context).scannerEnabled
+ return ExposurePreferences(context).enabled
}
}
}
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/CleanupService.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/CleanupService.kt
index f7908f85..0883b803 100644
--- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/CleanupService.kt
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/CleanupService.kt
@@ -27,7 +27,7 @@ class CleanupService : LifecycleService() {
companion object {
fun isNeeded(context: Context): Boolean {
return ExposurePreferences(context).let {
- it.scannerEnabled && it.lastCleanup < System.currentTimeMillis() - CLEANUP_INTERVAL
+ it.enabled && it.lastCleanup < System.currentTimeMillis() - CLEANUP_INTERVAL
}
}
}
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt
index efbb7c74..a14bf339 100644
--- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt
@@ -50,13 +50,13 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
}
override fun start(params: StartParams) {
- if (ExposurePreferences(context).scannerEnabled) {
+ if (ExposurePreferences(context).enabled) {
params.callback.onResult(Status(FAILED_ALREADY_STARTED))
return
}
confirm(CONFIRM_ACTION_START) { resultCode, resultData ->
if (resultCode == SUCCESS) {
- ExposurePreferences(context).scannerEnabled = true
+ ExposurePreferences(context).enabled = true
}
ExposureDatabase.with(context) { database ->
database.noteAppAction(packageName, "start", JSONObject().apply {
@@ -72,13 +72,13 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
}
override fun stop(params: StopParams) {
- if (!ExposurePreferences(context).scannerEnabled) {
+ if (!ExposurePreferences(context).enabled) {
params.callback.onResult(Status.SUCCESS)
return
}
confirm(CONFIRM_ACTION_STOP) { resultCode, _ ->
if (resultCode == SUCCESS) {
- ExposurePreferences(context).scannerEnabled = false
+ ExposurePreferences(context).enabled = false
}
ExposureDatabase.with(context) { database ->
database.noteAppAction(packageName, "stop", JSONObject().apply {
@@ -95,7 +95,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
override fun isEnabled(params: IsEnabledParams) {
try {
- params.callback.onResult(Status.SUCCESS, ExposurePreferences(context).scannerEnabled)
+ params.callback.onResult(Status.SUCCESS, ExposurePreferences(context).enabled)
} catch (e: Exception) {
Log.w(TAG, "Callback failed", e)
}
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposurePreferences.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposurePreferences.kt
index 1945d519..511e3b02 100644
--- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposurePreferences.kt
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposurePreferences.kt
@@ -8,13 +8,21 @@ package org.microg.gms.nearby.exposurenotification
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
+import android.util.Log
import androidx.preference.PreferenceManager
+import org.microg.gms.common.PackageUtils
class ExposurePreferences(private val context: Context) {
private var preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
- var scannerEnabled
+ init {
+ if (context.packageName != PackageUtils.getProcessName()) {
+ Log.w("Preferences", ExposurePreferences::class.simpleName + " initialized outside main process", RuntimeException())
+ }
+ }
+
+ var enabled
get() = preferences.getBoolean(PREF_SCANNER_ENABLED, false)
set(newStatus) {
preferences.edit().putBoolean(PREF_SCANNER_ENABLED, newStatus).commit()
@@ -26,9 +34,6 @@ class ExposurePreferences(private val context: Context) {
}
}
- val advertiserEnabled
- get() = scannerEnabled
-
var lastCleanup
get() = preferences.getLong(PREF_LAST_CLEANUP, 0)
set(value) = preferences.edit().putLong(PREF_LAST_CLEANUP, value).apply()
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ScannerService.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ScannerService.kt
index f180e1d6..470beca7 100644
--- a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ScannerService.kt
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ScannerService.kt
@@ -7,7 +7,6 @@ package org.microg.gms.nearby.exposurenotification
import android.annotation.TargetApi
import android.app.Service
-import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothAdapter.*
import android.bluetooth.le.*
import android.content.BroadcastReceiver
@@ -76,7 +75,7 @@ class ScannerService : Service() {
}
fun startScanIfNeeded() {
- if (ExposurePreferences(this).scannerEnabled) {
+ if (ExposurePreferences(this).enabled) {
startScan()
} else {
stopSelf()
@@ -138,7 +137,7 @@ class ScannerService : Service() {
companion object {
fun isNeeded(context: Context): Boolean {
- return ExposurePreferences(context).scannerEnabled
+ return ExposurePreferences(context).enabled
}
}
}
diff --git a/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ServiceInfo.kt b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ServiceInfo.kt
new file mode 100644
index 00000000..1379e9ce
--- /dev/null
+++ b/play-services-nearby-core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ServiceInfo.kt
@@ -0,0 +1,89 @@
+/*
+ * SPDX-FileCopyrightText: 2020, microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.microg.gms.nearby.exposurenotification
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.util.Log
+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.nearby.exposurenotification.SERVICE_INFO_REQUEST"
+private const val ACTION_UPDATE_CONFIGURATION = "org.microg.gms.nearby.exposurenotification.UPDATE_CONFIGURATION"
+private const val ACTION_SERVICE_INFO_RESPONSE = "org.microg.gms.nearby.exposurenotification.SERVICE_INFO_RESPONSE"
+private const val EXTRA_SERVICE_INFO = "org.microg.gms.nearby.exposurenotification.SERVICE_INFO"
+private const val EXTRA_CONFIGURATION = "org.microg.gms.nearby.exposurenotification.CONFIGURATION"
+
+data class ServiceInfo(val configuration: ServiceConfiguration) : Serializable
+
+data class ServiceConfiguration(val enabled: Boolean) : Serializable {
+ fun saveToPrefs(context: Context) {
+ ExposurePreferences(context).enabled = enabled
+ }
+}
+
+private fun ExposurePreferences.toConfiguration(): ServiceConfiguration = ServiceConfiguration(enabled)
+
+class ServiceInfoReceiver : BroadcastReceiver() {
+ private fun sendInfoResponse(context: Context) {
+ context.sendOrderedBroadcast(Intent(ACTION_SERVICE_INFO_RESPONSE).apply {
+ setPackage(context.packageName)
+ putExtra(EXTRA_SERVICE_INFO, ServiceInfo(ExposurePreferences(context).toConfiguration()))
+ }, null)
+ }
+
+ override fun onReceive(context: Context, intent: Intent) {
+ try {
+ when (intent.action) {
+ ACTION_UPDATE_CONFIGURATION -> {
+ (intent.getSerializableExtra(EXTRA_CONFIGURATION) as? ServiceConfiguration)?.saveToPrefs(context)
+ }
+ }
+ sendInfoResponse(context)
+ } 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 getExposureNotificationsServiceInfo(context: Context): ServiceInfo = sendToServiceInfoReceiver(
+ Intent(context, ServiceInfoReceiver::class.java).apply {
+ action = ACTION_SERVICE_INFO_REQUEST
+ }, context)
+
+suspend fun setExposureNotificationsServiceConfiguration(context: Context, configuration: ServiceConfiguration): ServiceInfo = sendToServiceInfoReceiver(
+ Intent(context, ServiceInfoReceiver::class.java).apply {
+ action = ACTION_UPDATE_CONFIGURATION
+ putExtra(EXTRA_CONFIGURATION, configuration)
+ }, context)