From 793b88b9b982d8b5ed9618ac7a178d3881a2c7c4 Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Fri, 15 Dec 2023 14:10:27 +0200 Subject: [PATCH] Try to refresh on invalid token callback --- app/src/main/java/org/futo/circles/App.kt | 4 ++- .../auth/feature/token/RefreshTokenManager.kt | 30 +++++++++---------- .../auth/feature/token/RefreshTokenWorker.kt | 10 +++++-- .../provider/MatrixSessionListenerProvider.kt | 28 ++++++++++++++--- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/futo/circles/App.kt b/app/src/main/java/org/futo/circles/App.kt index f43399085..0685db4f8 100644 --- a/app/src/main/java/org/futo/circles/App.kt +++ b/app/src/main/java/org/futo/circles/App.kt @@ -9,6 +9,7 @@ import com.vanniktech.emoji.google.GoogleEmojiProvider import dagger.hilt.android.HiltAndroidApp import org.futo.circles.core.base.CirclesAppConfig import org.futo.circles.core.base.NetworkObserver +import org.futo.circles.core.feature.ErrorLogger import org.futo.circles.core.provider.MatrixNotificationSetupListener import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.feature.notifications.FcmHelper @@ -20,6 +21,7 @@ import org.matrix.android.sdk.api.session.Session import timber.log.Timber import javax.inject.Inject + @HiltAndroidApp class App : Application() { @@ -37,6 +39,7 @@ class App : Application() { override fun onCreate() { super.onCreate() + ErrorLogger.appendLog("App start") NetworkObserver.register(applicationContext) CirclesAppConfig.Initializer() .buildConfigInfo( @@ -67,7 +70,6 @@ class App : Application() { notificationUtils.createNotificationChannels() setupLifecycleObserver() if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) - } private fun setupLifecycleObserver() { diff --git a/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenManager.kt b/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenManager.kt index ef14c6f28..277c50b2e 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenManager.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenManager.kt @@ -5,16 +5,16 @@ import androidx.work.Constraints import androidx.work.Data import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.NetworkType -import androidx.work.PeriodicWorkRequest.Companion.MIN_PERIODIC_FLEX_MILLIS import androidx.work.PeriodicWorkRequest.Companion.MIN_PERIODIC_INTERVAL_MILLIS import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import dagger.hilt.android.qualifiers.ApplicationContext +import org.futo.circles.core.feature.ErrorLogger import org.matrix.android.sdk.api.auth.data.sessionId import org.matrix.android.sdk.api.session.Session import java.util.concurrent.TimeUnit import javax.inject.Inject -import kotlin.math.max +import kotlin.math.roundToLong class RefreshTokenManager @Inject constructor( @ApplicationContext val context: Context @@ -22,7 +22,7 @@ class RefreshTokenManager @Inject constructor( fun scheduleTokenRefreshIfNeeded(session: Session) { val credentials = session.sessionParams.credentials - val expireTime = credentials.expiresInMs ?: return + val expireTime = ((credentials.expiresInMs ?: 0) * 0.7).roundToLong() if (credentials.refreshToken.isNullOrEmpty()) return if (expireTime < MIN_PERIODIC_INTERVAL_MILLIS) return @@ -30,23 +30,22 @@ class RefreshTokenManager @Inject constructor( .putString(RefreshTokenWorker.SESSION_ID_PARAM_KEY, credentials.sessionId()) .build() - val flex = max(expireTime / 3, MIN_PERIODIC_FLEX_MILLIS) - - val refreshRequest = PeriodicWorkRequestBuilder<RefreshTokenWorker>( - expireTime, TimeUnit.MILLISECONDS, - flex, TimeUnit.MILLISECONDS - ) - .setConstraints( - Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() - ) - .setInputData(sessionIdData) - .build() + val refreshRequest = + PeriodicWorkRequestBuilder<RefreshTokenWorker>(expireTime, TimeUnit.MILLISECONDS) + .setConstraints( + Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() + ) + .setInputData(sessionIdData) + .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( credentials.sessionId(), - ExistingPeriodicWorkPolicy.UPDATE, + ExistingPeriodicWorkPolicy.KEEP, refreshRequest ) + ErrorLogger.appendLog( + "scheduled sessionId ${credentials.sessionId()}, expireTime $expireTime" + ) } fun cancelTokenRefreshing(session: Session) { @@ -55,6 +54,7 @@ class RefreshTokenManager @Inject constructor( } fun cancelTokenRefreshingById(credentialsSessionId: String) { + ErrorLogger.appendLog("$credentialsSessionId canceled") WorkManager.getInstance(context).cancelUniqueWork(credentialsSessionId) } diff --git a/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenWorker.kt b/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenWorker.kt index a5d322858..bb47ed485 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenWorker.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/token/RefreshTokenWorker.kt @@ -9,6 +9,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.createResult +import org.futo.circles.core.feature.ErrorLogger import org.futo.circles.core.provider.MatrixInstanceProvider @HiltWorker @@ -18,13 +19,18 @@ class RefreshTokenWorker @AssistedInject constructor( ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { + ErrorLogger.appendLog("worker start") val sessionId = params.inputData.getString(SESSION_ID_PARAM_KEY) ?: run { WorkManager.getInstance(context).cancelWorkById(this.id) return Result.failure() } + ErrorLogger.appendLog("sessionId $sessionId") val result = refreshToken(sessionId) - return if (result is Response.Success) Result.success() - else { + return if (result is Response.Success) { + ErrorLogger.appendLog("worker success") + Result.success() + } else { + ErrorLogger.appendLog("worker failure") WorkManager.getInstance(context).cancelWorkById(this.id) Result.failure() } diff --git a/core/src/main/java/org/futo/circles/core/provider/MatrixSessionListenerProvider.kt b/core/src/main/java/org/futo/circles/core/provider/MatrixSessionListenerProvider.kt index 9ddcec3fe..54fe389af 100644 --- a/core/src/main/java/org/futo/circles/core/provider/MatrixSessionListenerProvider.kt +++ b/core/src/main/java/org/futo/circles/core/provider/MatrixSessionListenerProvider.kt @@ -1,5 +1,13 @@ package org.futo.circles.core.provider +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.futo.circles.core.extensions.Response +import org.futo.circles.core.extensions.coroutineScope +import org.futo.circles.core.extensions.createResult +import org.futo.circles.core.feature.ErrorLogger +import org.matrix.android.sdk.api.auth.data.sessionId import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session @@ -10,11 +18,23 @@ object MatrixSessionListenerProvider { val sessionListener: Session.Listener = object : Session.Listener { override fun onGlobalError(session: Session, globalError: GlobalError) { - if (globalError is GlobalError.InvalidToken) { - onInvalidToken?.invoke(globalError) - onInvalidToken = null + if (globalError !is GlobalError.InvalidToken) return + + session.coroutineScope.launch(Dispatchers.IO) { + ErrorLogger.appendLog("manual refresh") + val refreshResult = createResult { + MatrixInstanceProvider.matrix.authenticationService() + .refreshToken(session.sessionParams.credentials.sessionId()) + } + + if (refreshResult is Response.Error) { + ErrorLogger.appendLog("invalid token") + withContext(Dispatchers.Main) { + onInvalidToken?.invoke(globalError) + onInvalidToken = null + } + } } - } } -- GitLab