Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ abstract class RadarService : LifecycleService(), ServerStatusListener, LoginLis
}
}
private lateinit var notificationHandler: NotificationHandler
private lateinit var periodicPermissionObserver: PeriodicPermissionObserver

override fun onBind(intent: Intent): IBinder? {
super.onBind(intent)
Expand Down Expand Up @@ -155,6 +156,9 @@ abstract class RadarService : LifecycleService(), ServerStatusListener, LoginLis
configuration = radarConfig
providerLoader = SourceProviderLoader(plugins)
broadcaster = LocalBroadcastManager.getInstance(this)
periodicPermissionObserver = PeriodicPermissionObserver(this).apply {
start()
}

broadcaster.run {
permissionsBroadcastReceiver = register(ACTION_PERMISSIONS_GRANTED) { _, intent ->
Expand Down Expand Up @@ -320,6 +324,8 @@ abstract class RadarService : LifecycleService(), ServerStatusListener, LoginLis
}
authConnection.unbind()

periodicPermissionObserver.stop()

mConnections.asSequence()
.filter(SourceProvider<*>::isBound)
.forEach(SourceProvider<*>::unbind)
Expand Down Expand Up @@ -360,6 +366,8 @@ abstract class RadarService : LifecycleService(), ServerStatusListener, LoginLis
}
}
}

periodicPermissionObserver.configurePermissionObserver(config)
}

private fun hasFeatures(provider: SourceProvider<*>, packageManager: PackageManager?): Boolean {
Expand Down Expand Up @@ -420,6 +428,10 @@ abstract class RadarService : LifecycleService(), ServerStatusListener, LoginLis
}
}

fun nonGrantedPermissions(): Set<String> {
return needsPermissions
}

private fun updateBluetoothNeeded(newValue: Boolean) {
needsBluetooth.applyIfChanged(newValue) {
if (newValue) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.radarbase.android.util

import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import org.radarbase.android.RadarApplication.Companion.radarConfig
import org.radarbase.android.RadarService
import org.radarbase.android.config.SingleRadarConfiguration
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.util.concurrent.TimeUnit

class PeriodicPermissionObserver(private val context: RadarService) {
private var count = 0
private val isFirstAlarm: Boolean
get() = count <= 1

private val pObserverProcessor = OfflineProcessor(context) {
process = listOf(this@PeriodicPermissionObserver::observePermissions)
requestCode = PERIODIC_PERMISSION_OBSERVER_REQUEST_CODE
requestName = PERIODIC_PERMISSION_OBSERVER_REQUEST_NAME
wake = false
}

private var observerInterval: Long = -1L

fun start() {
configurePermissionObserver(context.radarConfig.latestConfig)
pObserverProcessor.start()
}

private fun observePermissions() {
count += 1
if (isFirstAlarm) {
logger.info("This is the first alarm, aborting it")
return
}

context.nonGrantedPermissions().also { permissions ->
if (permissions.isNotEmpty()) {
logger.info("Some permissions are still not granted: ${permissions.joinToString(", ") { it }}")
Firebase.crashlytics.apply {
log("User has not granted some permissions")
setCustomKey("error_type", "permissions_not_granted")
setCustomKey("non_granted_permissions", permissions.joinToString(", ") { it })
recordException(RuntimeException("Some permissions have not been granted."))
}
}
}
}

fun configurePermissionObserver(config: SingleRadarConfiguration) {
observerInterval = config.getLong(
PERMISSION_OBSERVER_INTERVAL_SECONDS,
PERMISSION_OBSERVER_INTERVAL_SECONDS_DEFAULT
)

pObserverProcessor.interval(observerInterval, TimeUnit.SECONDS)
}


fun stop() {
pObserverProcessor.close()
}

companion object {
private val logger: Logger = LoggerFactory.getLogger(PeriodicPermissionObserver::class.java)

private const val PERIODIC_PERMISSION_OBSERVER_REQUEST_CODE = 683768762
private const val PERIODIC_PERMISSION_OBSERVER_REQUEST_NAME =
"org.radarbase.android.util.PeriodicPermissionObserver.PERIODIC_PERMISSION_OBSERVER_REQUEST_NAME"
private const val PERMISSION_OBSERVER_INTERVAL_SECONDS =
"org.radarbase.android.util.PeriodicPermissionObserver.PERMISSION_OBSERVER_INTERVAL_SECONDS"
private const val PERMISSION_OBSERVER_INTERVAL_SECONDS_DEFAULT = 2L * ((60 * 60) * 24) // 2-DAYS
}
}
Loading