mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2025-02-13 03:06:48 +01:00
EN API: Only use a single writable database instance
Should fix some issues with older Android versions, #1115
This commit is contained in:
parent
ee176c42cc
commit
f30605b145
@ -47,14 +47,14 @@ class ExposureNotificationsAppPreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
|
|
||||||
fun updateContent() {
|
fun updateContent() {
|
||||||
packageName?.let { packageName ->
|
packageName?.let { packageName ->
|
||||||
val database = ExposureDatabase(requireContext())
|
ExposureDatabase.with(requireContext()) { database ->
|
||||||
var str = getString(R.string.pref_exposure_app_checks_summary, database.countMethodCalls(packageName, "provideDiagnosisKeys"))
|
var str = getString(R.string.pref_exposure_app_checks_summary, database.countMethodCalls(packageName, "provideDiagnosisKeys"))
|
||||||
val lastCheckTime = database.lastMethodCall(packageName, "provideDiagnosisKeys")
|
val lastCheckTime = database.lastMethodCall(packageName, "provideDiagnosisKeys")
|
||||||
if (lastCheckTime != null && lastCheckTime != 0L) {
|
if (lastCheckTime != null && lastCheckTime != 0L) {
|
||||||
str += "\n" + getString(R.string.pref_exposure_app_last_check_summary, DateUtils.getRelativeDateTimeString(context, lastCheckTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))
|
str += "\n" + getString(R.string.pref_exposure_app_last_check_summary, DateUtils.getRelativeDateTimeString(context, lastCheckTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))
|
||||||
}
|
}
|
||||||
checks.summary = str
|
checks.summary = str
|
||||||
database.close()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,16 +25,10 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
private lateinit var exposureAppsNone: Preference
|
private lateinit var exposureAppsNone: Preference
|
||||||
private lateinit var collectedRpis: Preference
|
private lateinit var collectedRpis: Preference
|
||||||
private lateinit var advertisingId: Preference
|
private lateinit var advertisingId: Preference
|
||||||
private lateinit var database: ExposureDatabase
|
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
private val updateStatusRunnable = Runnable { updateStatus() }
|
private val updateStatusRunnable = Runnable { updateStatus() }
|
||||||
private val updateContentRunnable = Runnable { updateContent() }
|
private val updateContentRunnable = Runnable { updateContent() }
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
database = ExposureDatabase(requireContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
addPreferencesFromResource(R.xml.preferences_exposure_notifications)
|
addPreferencesFromResource(R.xml.preferences_exposure_notifications)
|
||||||
}
|
}
|
||||||
@ -53,13 +47,14 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
updateStatus()
|
updateStatus()
|
||||||
updateContent()
|
updateContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
database.close()
|
|
||||||
handler.removeCallbacks(updateStatusRunnable)
|
handler.removeCallbacks(updateStatusRunnable)
|
||||||
handler.removeCallbacks(updateContentRunnable)
|
handler.removeCallbacks(updateContentRunnable)
|
||||||
}
|
}
|
||||||
@ -78,6 +73,7 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
handler.postDelayed(updateContentRunnable, UPDATE_CONTENT_INTERVAL)
|
handler.postDelayed(updateContentRunnable, UPDATE_CONTENT_INTERVAL)
|
||||||
val context = requireContext()
|
val context = requireContext()
|
||||||
val (apps, lastHourKeys, currentId) = withContext(Dispatchers.IO) {
|
val (apps, lastHourKeys, currentId) = withContext(Dispatchers.IO) {
|
||||||
|
ExposureDatabase.with(context) { database ->
|
||||||
val apps = database.appList.map { packageName ->
|
val apps = database.appList.map { packageName ->
|
||||||
context.packageManager.getApplicationInfoIfExists(packageName)
|
context.packageManager.getApplicationInfoIfExists(packageName)
|
||||||
}.filterNotNull().mapIndexed { idx, applicationInfo ->
|
}.filterNotNull().mapIndexed { idx, applicationInfo ->
|
||||||
@ -96,9 +92,9 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
}
|
}
|
||||||
val lastHourKeys = database.hourRpiCount
|
val lastHourKeys = database.hourRpiCount
|
||||||
val currentId = database.currentRpiId
|
val currentId = database.currentRpiId
|
||||||
database.close()
|
|
||||||
Triple(apps, lastHourKeys, currentId)
|
Triple(apps, lastHourKeys, currentId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
collectedRpis.summary = getString(R.string.pref_exposure_collected_rpis_summary, lastHourKeys)
|
collectedRpis.summary = getString(R.string.pref_exposure_collected_rpis_summary, lastHourKeys)
|
||||||
advertisingId.summary = currentId.toString()
|
advertisingId.summary = currentId.toString()
|
||||||
exposureApps.removeAll()
|
exposureApps.removeAll()
|
||||||
|
@ -22,12 +22,6 @@ import kotlin.math.roundToInt
|
|||||||
class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
||||||
private lateinit var histogramCategory: PreferenceCategory
|
private lateinit var histogramCategory: PreferenceCategory
|
||||||
private lateinit var histogram: BarChartPreference
|
private lateinit var histogram: BarChartPreference
|
||||||
private lateinit var database: ExposureDatabase
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
database = ExposureDatabase(requireContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
addPreferencesFromResource(R.xml.preferences_exposure_notifications_rpis)
|
addPreferencesFromResource(R.xml.preferences_exposure_notifications_rpis)
|
||||||
@ -43,14 +37,10 @@ class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
|||||||
updateChart()
|
updateChart()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
|
||||||
super.onPause()
|
|
||||||
database.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateChart() {
|
fun updateChart() {
|
||||||
lifecycleScope.launchWhenResumed {
|
lifecycleScope.launchWhenResumed {
|
||||||
val (totalRpiCount, rpiHistogram) = withContext(Dispatchers.IO) {
|
val (totalRpiCount, rpiHistogram) = withContext(Dispatchers.IO) {
|
||||||
|
ExposureDatabase.with(requireContext()) { database ->
|
||||||
val map = linkedMapOf<String, Float>()
|
val map = linkedMapOf<String, Float>()
|
||||||
val lowestDate = Math.round((Date().time / 24 / 60 / 60 / 1000 - 13).toDouble()) * 24 * 60 * 60 * 1000
|
val lowestDate = Math.round((Date().time / 24 / 60 / 60 / 1000 - 13).toDouble()) * 24 * 60 * 60 * 1000
|
||||||
for (i in 0..13) {
|
for (i in 0..13) {
|
||||||
@ -63,9 +53,9 @@ class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
|||||||
map[date.toString()] = entry.value.toFloat()
|
map[date.toString()] = entry.value.toFloat()
|
||||||
}
|
}
|
||||||
val totalRpiCount = database.totalRpiCount
|
val totalRpiCount = database.totalRpiCount
|
||||||
database.close()
|
|
||||||
totalRpiCount to map
|
totalRpiCount to map
|
||||||
}
|
}
|
||||||
|
}
|
||||||
histogramCategory.title = getString(R.string.prefcat_exposure_rpis_histogram_title, totalRpiCount)
|
histogramCategory.title = getString(R.string.prefcat_exposure_rpis_histogram_title, totalRpiCount)
|
||||||
histogram.labelsFormatter = { it.roundToInt().toString() }
|
histogram.labelsFormatter = { it.roundToInt().toString() }
|
||||||
histogram.scale = Scale(0f, rpiHistogram.values.max() ?: 0f)
|
histogram.scale = Scale(0f, rpiHistogram.values.max() ?: 0f)
|
||||||
|
@ -13,7 +13,7 @@ fun PackageManager.getApplicationInfoIfExists(packageName: String?, flags: Int =
|
|||||||
try {
|
try {
|
||||||
getApplicationInfo(it, flags)
|
getApplicationInfo(it, flags)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Package does not exist", e)
|
Log.w(TAG, "Package $packageName not installed.")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class AdvertiserService : LifecycleService() {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
database = ExposureDatabase(this)
|
database = ExposureDatabase.ref(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
@ -56,7 +56,7 @@ class AdvertiserService : LifecycleService() {
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
stopAdvertising()
|
stopAdvertising()
|
||||||
database.close()
|
database.unref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startAdvertising() {
|
fun startAdvertising() {
|
||||||
|
@ -24,22 +24,8 @@ import java.util.concurrent.TimeUnit
|
|||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class ExposureDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
|
class ExposureDatabase private constructor(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
|
||||||
private val refCount = AtomicInteger(0)
|
private var refCount = 0
|
||||||
|
|
||||||
fun ref(): ExposureDatabase {
|
|
||||||
refCount.incrementAndGet()
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unref() {
|
|
||||||
val nu = refCount.decrementAndGet()
|
|
||||||
if (nu == 0) {
|
|
||||||
close()
|
|
||||||
} else if (nu < 0) {
|
|
||||||
throw RuntimeException("ref/unref mismatch")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
onUpgrade(db, 0, DB_VERSION)
|
onUpgrade(db, 0, DB_VERSION)
|
||||||
@ -447,6 +433,35 @@ class ExposureDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, nu
|
|||||||
|
|
||||||
fun generateCurrentPayload(metadata: ByteArray) = currentTemporaryExposureKey.generatePayload(currentIntervalNumber.toInt(), metadata)
|
fun generateCurrentPayload(metadata: ByteArray) = currentTemporaryExposureKey.generatePayload(currentIntervalNumber.toInt(), metadata)
|
||||||
|
|
||||||
|
override fun getWritableDatabase(): SQLiteDatabase {
|
||||||
|
if (this != instance) {
|
||||||
|
throw IllegalStateException("Tried to open writable database from secondary instance")
|
||||||
|
}
|
||||||
|
val db = super.getWritableDatabase()
|
||||||
|
db.enableWriteAheadLogging()
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
synchronized(Companion) {
|
||||||
|
super.close()
|
||||||
|
instance = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ref(): ExposureDatabase = synchronized(Companion) {
|
||||||
|
refCount++
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unref() = synchronized(Companion) {
|
||||||
|
refCount--
|
||||||
|
if (refCount == 0) {
|
||||||
|
close()
|
||||||
|
} else if (refCount < 0) {
|
||||||
|
throw IllegalStateException("ref/unref mismatch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DB_NAME = "exposure.db"
|
private const val DB_NAME = "exposure.db"
|
||||||
@ -457,6 +472,23 @@ class ExposureDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, nu
|
|||||||
private const val TABLE_TEK_CHECK = "tek_check"
|
private const val TABLE_TEK_CHECK = "tek_check"
|
||||||
private const val TABLE_DIAGNOSIS = "diagnosis"
|
private const val TABLE_DIAGNOSIS = "diagnosis"
|
||||||
private const val TABLE_CONFIGURATIONS = "configurations"
|
private const val TABLE_CONFIGURATIONS = "configurations"
|
||||||
|
|
||||||
|
private var instance: ExposureDatabase? = null
|
||||||
|
fun ref(context: Context): ExposureDatabase = synchronized(this) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = ExposureDatabase(context.applicationContext)
|
||||||
|
}
|
||||||
|
instance!!.ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> with(context: Context, call: (ExposureDatabase) -> T): T {
|
||||||
|
val it = ref(context)
|
||||||
|
try {
|
||||||
|
return call(it)
|
||||||
|
} finally {
|
||||||
|
it.unref()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,21 +18,6 @@ import org.microg.gms.common.GmsService
|
|||||||
import org.microg.gms.common.PackageUtils
|
import org.microg.gms.common.PackageUtils
|
||||||
|
|
||||||
class ExposureNotificationService : BaseService(TAG, GmsService.NEARBY_EXPOSURE) {
|
class ExposureNotificationService : BaseService(TAG, GmsService.NEARBY_EXPOSURE) {
|
||||||
lateinit var database: ExposureDatabase
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
database.unref()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
if (!this::database.isInitialized) {
|
|
||||||
database = ExposureDatabase(this)
|
|
||||||
}
|
|
||||||
database.ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
|
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
|
||||||
PackageUtils.getAndCheckCallingPackage(this, request.packageName)
|
PackageUtils.getAndCheckCallingPackage(this, request.packageName)
|
||||||
|
|
||||||
@ -53,7 +38,7 @@ class ExposureNotificationService : BaseService(TAG, GmsService.NEARBY_EXPOSURE)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "handleServiceRequest: " + request.packageName)
|
Log.d(TAG, "handleServiceRequest: " + request.packageName)
|
||||||
callback.onPostInitCompleteWithConnectionInfo(SUCCESS, ExposureNotificationServiceImpl(this, request.packageName, database), ConnectionInfo().apply {
|
callback.onPostInitCompleteWithConnectionInfo(SUCCESS, ExposureNotificationServiceImpl(this, request.packageName), ConnectionInfo().apply {
|
||||||
features = arrayOf(Feature("nearby_exposure_notification", 2))
|
features = arrayOf(Feature("nearby_exposure_notification", 2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import org.microg.gms.nearby.exposurenotification.proto.TemporaryExposureKeyProt
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
class ExposureNotificationServiceImpl(private val context: Context, private val packageName: String, private val database: ExposureDatabase) : INearbyExposureNotificationService.Stub() {
|
class ExposureNotificationServiceImpl(private val context: Context, private val packageName: String) : INearbyExposureNotificationService.Stub() {
|
||||||
private fun confirm(action: String, callback: (resultCode: Int, resultData: Bundle?) -> Unit) {
|
private fun confirm(action: String, callback: (resultCode: Int, resultData: Bundle?) -> Unit) {
|
||||||
val intent = Intent(ACTION_CONFIRM)
|
val intent = Intent(ACTION_CONFIRM)
|
||||||
intent.`package` = context.packageName
|
intent.`package` = context.packageName
|
||||||
@ -59,9 +59,11 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
if (resultCode == SUCCESS) {
|
if (resultCode == SUCCESS) {
|
||||||
ExposurePreferences(context).scannerEnabled = true
|
ExposurePreferences(context).scannerEnabled = true
|
||||||
}
|
}
|
||||||
|
ExposureDatabase.with(context) { database ->
|
||||||
database.noteAppAction(packageName, "start", JSONObject().apply {
|
database.noteAppAction(packageName, "start", JSONObject().apply {
|
||||||
put("result", resultCode)
|
put("result", resultCode)
|
||||||
}.toString())
|
}.toString())
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
params.callback.onResult(Status(if (resultCode == SUCCESS) SUCCESS else FAILED_REJECTED_OPT_IN, resultData?.getString("message")))
|
params.callback.onResult(Status(if (resultCode == SUCCESS) SUCCESS else FAILED_REJECTED_OPT_IN, resultData?.getString("message")))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -75,9 +77,11 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
if (resultCode == SUCCESS) {
|
if (resultCode == SUCCESS) {
|
||||||
ExposurePreferences(context).scannerEnabled = false
|
ExposurePreferences(context).scannerEnabled = false
|
||||||
}
|
}
|
||||||
|
ExposureDatabase.with(context) { database ->
|
||||||
database.noteAppAction(packageName, "stop", JSONObject().apply {
|
database.noteAppAction(packageName, "stop", JSONObject().apply {
|
||||||
put("result", resultCode)
|
put("result", resultCode)
|
||||||
}.toString())
|
}.toString())
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
params.callback.onResult(Status.SUCCESS)
|
params.callback.onResult(Status.SUCCESS)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -94,7 +98,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTemporaryExposureKeyHistory(params: GetTemporaryExposureKeyHistoryParams) {
|
override fun getTemporaryExposureKeyHistory(params: GetTemporaryExposureKeyHistoryParams): Unit = ExposureDatabase.with(context) { database ->
|
||||||
confirm(CONFIRM_ACTION_START) { resultCode, resultData ->
|
confirm(CONFIRM_ACTION_START) { resultCode, resultData ->
|
||||||
val (status, response) = if (resultCode == SUCCESS) {
|
val (status, response) = if (resultCode == SUCCESS) {
|
||||||
SUCCESS to database.allKeys
|
SUCCESS to database.allKeys
|
||||||
@ -122,7 +126,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
.setTransmissionRiskLevel(transmission_risk_level ?: 0)
|
.setTransmissionRiskLevel(transmission_risk_level ?: 0)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private fun storeDiagnosisKeyExport(token: String, export: TemporaryExposureKeyExport): Int {
|
private fun storeDiagnosisKeyExport(token: String, export: TemporaryExposureKeyExport): Int = ExposureDatabase.with(context) { database ->
|
||||||
Log.d(TAG, "Importing keys from file ${export.start_timestamp?.let { Date(it * 1000) }} to ${export.end_timestamp?.let { Date(it * 1000) }}")
|
Log.d(TAG, "Importing keys from file ${export.start_timestamp?.let { Date(it * 1000) }} to ${export.end_timestamp?.let { Date(it * 1000) }}")
|
||||||
for (key in export.keys) {
|
for (key in export.keys) {
|
||||||
database.storeDiagnosisKey(packageName, token, key.toKey())
|
database.storeDiagnosisKey(packageName, token, key.toKey())
|
||||||
@ -130,13 +134,12 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
for (key in export.revised_keys) {
|
for (key in export.revised_keys) {
|
||||||
database.updateDiagnosisKey(packageName, token, key.toKey())
|
database.updateDiagnosisKey(packageName, token, key.toKey())
|
||||||
}
|
}
|
||||||
return export.keys.size + export.revised_keys.size
|
export.keys.size + export.revised_keys.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun provideDiagnosisKeys(params: ProvideDiagnosisKeysParams) {
|
override fun provideDiagnosisKeys(params: ProvideDiagnosisKeysParams) {
|
||||||
database.ref()
|
|
||||||
Thread(Runnable {
|
Thread(Runnable {
|
||||||
try {
|
ExposureDatabase.with(context) { database ->
|
||||||
if (params.configuration != null) {
|
if (params.configuration != null) {
|
||||||
database.storeConfiguration(packageName, params.token, params.configuration)
|
database.storeConfiguration(packageName, params.token, params.configuration)
|
||||||
}
|
}
|
||||||
@ -205,13 +208,11 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Callback failed", e)
|
Log.w(TAG, "Callback failed", e)
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
database.unref()
|
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExposureSummary(params: GetExposureSummaryParams) {
|
override fun getExposureSummary(params: GetExposureSummaryParams): Unit = ExposureDatabase.with(context) { database ->
|
||||||
val configuration = database.loadConfiguration(packageName, params.token)
|
val configuration = database.loadConfiguration(packageName, params.token)
|
||||||
if (configuration == null) {
|
if (configuration == null) {
|
||||||
try {
|
try {
|
||||||
@ -219,7 +220,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Callback failed", e)
|
Log.w(TAG, "Callback failed", e)
|
||||||
}
|
}
|
||||||
return
|
return@with
|
||||||
}
|
}
|
||||||
val exposures = database.findAllMeasuredExposures(packageName, params.token)
|
val exposures = database.findAllMeasuredExposures(packageName, params.token)
|
||||||
val response = ExposureSummary.ExposureSummaryBuilder()
|
val response = ExposureSummary.ExposureSummaryBuilder()
|
||||||
@ -251,7 +252,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExposureInformation(params: GetExposureInformationParams) {
|
override fun getExposureInformation(params: GetExposureInformationParams): Unit = ExposureDatabase.with(context) { database ->
|
||||||
// TODO: Notify user?
|
// TODO: Notify user?
|
||||||
val configuration = database.loadConfiguration(packageName, params.token)
|
val configuration = database.loadConfiguration(packageName, params.token)
|
||||||
if (configuration == null) {
|
if (configuration == null) {
|
||||||
@ -260,7 +261,7 @@ class ExposureNotificationServiceImpl(private val context: Context, private val
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Callback failed", e)
|
Log.w(TAG, "Callback failed", e)
|
||||||
}
|
}
|
||||||
return
|
return@with
|
||||||
}
|
}
|
||||||
val response = database.findAllMeasuredExposures(packageName, params.token).map {
|
val response = database.findAllMeasuredExposures(packageName, params.token).map {
|
||||||
it.toExposureInformation(configuration)
|
it.toExposureInformation(configuration)
|
||||||
|
@ -15,12 +15,12 @@ import android.os.IBinder
|
|||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
class ScannerService : Service() {
|
class ScannerService : Service() {
|
||||||
private var started = false
|
private var started = false
|
||||||
private lateinit var db: ExposureDatabase
|
private lateinit var database: ExposureDatabase
|
||||||
private val callback = object : ScanCallback() {
|
private val callback = object : ScanCallback() {
|
||||||
override fun onScanResult(callbackType: Int, result: ScanResult?) {
|
override fun onScanResult(callbackType: Int, result: ScanResult?) {
|
||||||
val data = result?.scanRecord?.serviceData?.get(SERVICE_UUID) ?: return
|
val data = result?.scanRecord?.serviceData?.get(SERVICE_UUID) ?: return
|
||||||
if (data.size < 16) return // Ignore invalid advertisements
|
if (data.size < 16) return // Ignore invalid advertisements
|
||||||
db.noteAdvertisement(data.sliceArray(0..15), data.drop(16).toByteArray(), result.rssi)
|
database.noteAdvertisement(data.sliceArray(0..15), data.drop(16).toByteArray(), result.rssi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val scanner: BluetoothLeScanner
|
private val scanner: BluetoothLeScanner
|
||||||
@ -36,9 +36,15 @@ class ScannerService : Service() {
|
|||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
database = ExposureDatabase.ref(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
stopScan()
|
stopScan()
|
||||||
|
database.unref()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
@ -48,7 +54,6 @@ class ScannerService : Service() {
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
private fun startScan() {
|
private fun startScan() {
|
||||||
if (started) return
|
if (started) return
|
||||||
db = ExposureDatabase(this)
|
|
||||||
scanner.startScan(
|
scanner.startScan(
|
||||||
listOf(ScanFilter.Builder().setServiceUuid(SERVICE_UUID).setServiceData(SERVICE_UUID, byteArrayOf(0), byteArrayOf(0)).build()),
|
listOf(ScanFilter.Builder().setServiceUuid(SERVICE_UUID).setServiceData(SERVICE_UUID, byteArrayOf(0), byteArrayOf(0)).build()),
|
||||||
ScanSettings.Builder().build(),
|
ScanSettings.Builder().build(),
|
||||||
@ -61,7 +66,6 @@ class ScannerService : Service() {
|
|||||||
private fun stopScan() {
|
private fun stopScan() {
|
||||||
if (!started) return
|
if (!started) return
|
||||||
scanner.stopScan(callback)
|
scanner.stopScan(callback)
|
||||||
db.close()
|
|
||||||
started = false
|
started = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user