Skip to content

Commit be2f002

Browse files
committed
Logout feature
1 parent b7811bd commit be2f002

File tree

13 files changed

+276
-106
lines changed

13 files changed

+276
-106
lines changed

radar-commons-android/src/main/java/org/radarbase/android/MainActivity.kt

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,28 @@ import com.google.firebase.analytics.FirebaseAnalytics
3030
import kotlinx.coroutines.CoroutineStart
3131
import kotlinx.coroutines.Dispatchers
3232
import kotlinx.coroutines.Job
33+
import kotlinx.coroutines.delay
3334
import kotlinx.coroutines.flow.MutableSharedFlow
3435
import kotlinx.coroutines.flow.SharedFlow
3536
import kotlinx.coroutines.flow.StateFlow
3637
import kotlinx.coroutines.launch
3738
import kotlinx.coroutines.sync.Mutex
3839
import kotlinx.coroutines.sync.withLock
40+
import kotlinx.coroutines.withContext
3941
import org.radarbase.android.RadarApplication.Companion.radarApp
4042
import org.radarbase.android.RadarApplication.Companion.radarConfig
4143
import org.radarbase.android.RadarConfiguration.Companion.PROJECT_ID_KEY
4244
import org.radarbase.android.RadarConfiguration.Companion.UI_REFRESH_RATE_KEY
4345
import org.radarbase.android.RadarConfiguration.Companion.USER_ID_KEY
46+
import org.radarbase.android.RadarConfiguration.RemoteConfigStatus.INITIAL
4447
import org.radarbase.android.RadarService.Companion.ACTION_CHECK_PERMISSIONS
4548
import org.radarbase.android.RadarService.Companion.EXTRA_PERMISSIONS
4649
import org.radarbase.android.auth.AppAuthState
4750
import org.radarbase.android.auth.AuthService
4851
import org.radarbase.android.auth.AuthServiceStateReactor
4952
import org.radarbase.android.auth.LoginListener
5053
import org.radarbase.android.auth.LoginManager
54+
import org.radarbase.android.config.SingleRadarConfiguration
5155
import org.radarbase.android.util.BindState
5256
import org.radarbase.android.util.BluetoothEnforcer
5357
import org.radarbase.android.util.CoroutineTaskExecutor
@@ -57,10 +61,11 @@ import org.radarbase.android.util.PermissionBroadcast
5761
import org.radarbase.android.util.PermissionHandler
5862
import org.radarbase.kotlin.coroutines.launchJoin
5963
import org.slf4j.LoggerFactory
64+
import java.io.File
6065
import kotlin.time.Duration
6166
import kotlin.time.Duration.Companion.milliseconds
6267

63-
typealias RadarServiceStateReactor = (IRadarBinder) -> Unit
68+
typealias RadarServiceStateReactor = suspend (IRadarBinder) -> Unit
6469

6570
/** Base MainActivity class. It manages the services to collect the data and starts up a view. To
6671
* create an application, extend this class and override the abstract methods. */
@@ -109,6 +114,7 @@ abstract class MainActivity : AppCompatActivity(), LoginListener {
109114
get() = configuration.latestConfig.optString(PROJECT_ID_KEY)
110115

111116
private val mutexCreateView: Mutex = Mutex()
117+
private var connectionBound: Boolean = false
112118

113119
private var radarConnectionJob: Job? = null
114120
private var authConnectionJob: Job? = null
@@ -191,6 +197,8 @@ abstract class MainActivity : AppCompatActivity(), LoginListener {
191197
logger.info("RADAR configuration at create: {}", configuration)
192198
onConfigChanged()
193199

200+
connectionBound = false
201+
194202
// Start the UI thread
195203
uiRefreshRate = configuration.latestConfig.getLong(UI_REFRESH_RATE_KEY, 250L)
196204

@@ -261,10 +269,14 @@ abstract class MainActivity : AppCompatActivity(), LoginListener {
261269

262270
with(lifecycleScope) {
263271
launch {
264-
authConnection.bind()
265-
}
266-
launch {
267-
radarConnection.bind()
272+
try {
273+
connectionBound = true
274+
authConnection.bind()
275+
radarConnection.bind()
276+
} catch (ex: Exception) {
277+
connectionBound = false
278+
throw ex
279+
}
268280
}
269281
}
270282
permissionHandler.invalidateCache()
@@ -343,18 +355,20 @@ abstract class MainActivity : AppCompatActivity(), LoginListener {
343355

344356
@CallSuper
345357
public override fun onStop() {
346-
super.onStop()
347-
348358
mainExecutor.stop { view = null }
349359

350-
radarConnection.unbind()
351-
authConnection.unbind()
360+
if (connectionBound) {
361+
connectionBound = false
362+
radarConnection.unbind()
363+
authConnection.unbind()
364+
}
352365
bluetoothEnforcer.stop()
353366

354367
radarConnectionJob?.cancel()
355368
authConnectionJob?.cancel()
356369
radarConnectionJob = null
357370
authConnectionJob = null
371+
super.onStop()
358372
}
359373

360374
override fun onRequestPermissionsResult(
@@ -373,22 +387,62 @@ abstract class MainActivity : AppCompatActivity(), LoginListener {
373387
* still valid.
374388
*/
375389
protected suspend fun logout(disableRefresh: Boolean) {
376-
authConnection.applyBinder { invalidate(null, disableRefresh) }
390+
lifecycleScope.launch {
391+
authConnection.applyBinder { invalidate(null, disableRefresh) }
392+
}
377393
logger.debug("Disabling Firebase Analytics")
378394
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(false)
379395
}
380396

381397
override fun loginSucceeded(manager: LoginManager?, authState: AppAuthState) = Unit
382398

383399
override suspend fun logoutSucceeded(manager: LoginManager?, authState: AppAuthState) {
400+
if (!connectionBound) {
401+
connectionBound = false
402+
radarConnection.unbind()
403+
authConnection.unbind()
404+
}
405+
clearAppData(this)
406+
delay(300)
407+
logger.trace("Configurations reset")
384408
logger.info("Starting SplashActivity")
385-
val intent = packageManager.getLaunchIntentForPackage(BuildConfig.LIBRARY_PACKAGE_NAME) ?: return
409+
val applicationPackage = packageName
410+
val intent = packageManager.getLaunchIntentForPackage(applicationPackage) ?: return
411+
logger.debug("Starting splash activity with intent {}", intent)
386412
startActivity(intent.apply {
387413
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
388414
})
389415
finish()
390416
}
391417

418+
private fun clearAppData(context: Context) {
419+
clearCache(context)
420+
clearFilesDir(context)
421+
}
422+
423+
private fun clearFilesDir(context: Context) {
424+
val filesDir = context.filesDir
425+
deleteFilesInDirectory(filesDir)
426+
}
427+
428+
private fun clearCache(context: Context) {
429+
val cacheDir = context.cacheDir
430+
deleteFilesInDirectory(cacheDir)
431+
}
432+
433+
private fun deleteFilesInDirectory(directory: File) {
434+
if (directory.isDirectory) {
435+
val children = directory.listFiles()
436+
if (children != null) {
437+
for (child in children) {
438+
if (child.absolutePath.toString().contains("firebase")) return
439+
deleteFilesInDirectory(child)
440+
}
441+
}
442+
}
443+
directory.delete()
444+
}
445+
392446
companion object {
393447
private val logger = LoggerFactory.getLogger(MainActivity::class.java)
394448

radar-commons-android/src/main/java/org/radarbase/android/RadarConfiguration.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ interface RadarConfiguration {
6161
/**
6262
* Force fetching the remote configuration from server, even if it is not outdated.
6363
*/
64-
suspend fun forceFetch()
64+
suspend fun forceFetch(callAfterLogout: Boolean = false)
6565

6666
/**
6767
* Adds base URL from auth state to configuration.
6868
*/
69-
suspend fun updateWithAuthState(context: Context, appAuthState: AppAuthState?)
69+
suspend fun updateWithAuthState(context: Context, appAuthState: AppAuthState?, isLogoutCall: Boolean = false)
70+
71+
suspend fun resetConfigs()
7072

7173
companion object {
7274
const val RADAR_CONFIGURATION_CHANGED = "org.radarcns.android.RadarConfiguration.CHANGED"

0 commit comments

Comments
 (0)