diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 24cf5ec87aa93da3b6eb68f368f4b276a57dd745..036f3e83ee280797b2d2fa82b2ce2f1c2ec52912 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -55,4 +55,7 @@ dependencies { implementation(libs.retrofit2.converter.gson) implementation(libs.retrofit2.converter.scalars) implementation(libs.okhttp3) + + // Work + implementation(libs.androidx.work.runtime) } \ No newline at end of file diff --git a/app/src/main/java/com/onionsquad/bondoman/MainActivity.kt b/app/src/main/java/com/onionsquad/bondoman/MainActivity.kt index a6ad2b9fb755fc340a1eb96c21c88a0dc4708055..5e8bc1e29afe9cefe2d3a0afa6402a29c6d29fab 100644 --- a/app/src/main/java/com/onionsquad/bondoman/MainActivity.kt +++ b/app/src/main/java/com/onionsquad/bondoman/MainActivity.kt @@ -8,6 +8,7 @@ import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import com.google.android.material.bottomnavigation.BottomNavigationView +import com.onionsquad.bondoman.auth.AutoLogoutWorker import com.onionsquad.bondoman.auth.SessionManager import com.onionsquad.bondoman.databinding.ActivityMainBinding import com.onionsquad.bondoman.ui.login.LoginActivity @@ -19,6 +20,8 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + AutoLogoutWorker.start(this) + val sessionManager = SessionManager(this) if (sessionManager.fetchAuthToken() == null) { sendToLoginActivity() diff --git a/app/src/main/java/com/onionsquad/bondoman/auth/AutoLogoutWorker.kt b/app/src/main/java/com/onionsquad/bondoman/auth/AutoLogoutWorker.kt new file mode 100644 index 0000000000000000000000000000000000000000..bbf7a225b6c8024633518557dbfff5b6b2eaa713 --- /dev/null +++ b/app/src/main/java/com/onionsquad/bondoman/auth/AutoLogoutWorker.kt @@ -0,0 +1,58 @@ +package com.onionsquad.bondoman.auth + +import android.content.Context +import android.util.Log +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import androidx.work.Worker +import androidx.work.WorkerParameters +import java.time.Instant +import java.util.concurrent.TimeUnit +import kotlin.math.max + + +class AutoLogoutWorker( + private val context: Context, + private val workerParameters: WorkerParameters +) : Worker(context, workerParameters) { + + override fun doWork(): Result { + Log.d(this::class.java.simpleName, "Proceed auto logout") + val sessionManager = SessionManager(context) + sessionManager.deleteAuthToken() + return Result.success() + } + + companion object { + fun start(context: Context) { + Log.d(AutoLogoutWorker::class.java.simpleName, "Starting auto logout worker") + val sessionManager = SessionManager(context) + val token = sessionManager.fetchAuthToken() + if (token != null) { + val duration = max(0, token.exp - Instant.now().epochSecond) + Log.d(AutoLogoutWorker::class.java.simpleName, "Proceed to logout in $duration secs") + val workRequest = OneTimeWorkRequestBuilder<AutoLogoutWorker>() + .setInitialDelay(duration, TimeUnit.SECONDS) + .build() + WorkManager + .getInstance(context) + .enqueueUniqueWork( + AutoLogoutWorker::class.java.simpleName, + ExistingWorkPolicy.REPLACE, + workRequest + ) + } else { + stop(context) + } + } + + fun stop(context: Context) { + Log.d(AutoLogoutWorker::class.java.simpleName, "Stopping auto logout worker") + WorkManager + .getInstance(context) + .cancelUniqueWork(AutoLogoutWorker::class.java.simpleName) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/onionsquad/bondoman/ui/login/LoginActivity.kt b/app/src/main/java/com/onionsquad/bondoman/ui/login/LoginActivity.kt index 3eace85f0832e12fce0cf2201091ba1bdfeb9c3b..b756280b2e8f04b7a4eef3d57e7614828c682d4b 100644 --- a/app/src/main/java/com/onionsquad/bondoman/ui/login/LoginActivity.kt +++ b/app/src/main/java/com/onionsquad/bondoman/ui/login/LoginActivity.kt @@ -12,11 +12,18 @@ import android.view.View import android.view.inputmethod.EditorInfo import android.widget.EditText import android.widget.Toast +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager import com.onionsquad.bondoman.MainActivity import com.onionsquad.bondoman.databinding.ActivityLoginBinding import com.onionsquad.bondoman.R +import com.onionsquad.bondoman.auth.AutoLogoutWorker import com.onionsquad.bondoman.auth.SessionManager +import java.time.Instant +import java.util.concurrent.TimeUnit class LoginActivity : AppCompatActivity() { @@ -56,6 +63,7 @@ class LoginActivity : AppCompatActivity() { } if (loginResult.success != null) { sessionManager.saveAuthToken(loginResult.success) + AutoLogoutWorker.start(this@LoginActivity) showLoginSuccess() sendToMainActivity() } diff --git a/app/src/main/java/com/onionsquad/bondoman/ui/settings/SettingsFragment.kt b/app/src/main/java/com/onionsquad/bondoman/ui/settings/SettingsFragment.kt index 8599805898a3461fae5249a8dc1f618a17c15079..37c78c8c5c0b91cfcb6ee44ff9bbde80ab9e6751 100644 --- a/app/src/main/java/com/onionsquad/bondoman/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/onionsquad/bondoman/ui/settings/SettingsFragment.kt @@ -7,9 +7,9 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController import com.onionsquad.bondoman.R +import com.onionsquad.bondoman.auth.AutoLogoutWorker import com.onionsquad.bondoman.auth.SessionManager import com.onionsquad.bondoman.databinding.FragmentSettingsBinding @@ -25,15 +25,14 @@ class SettingsFragment : Fragment() { ): View { _binding = FragmentSettingsBinding.inflate(inflater, container, false) - val sessionManager = SessionManager(requireContext()) - binding.apply { logoutButton.setOnClickListener { val alertBuilder = AlertDialog.Builder(requireContext()) alertBuilder.setTitle(R.string.title_alert_logout) alertBuilder.setMessage(R.string.message_alert_logout) alertBuilder.setPositiveButton(R.string.yes) { _, _ -> - logout(sessionManager) + AutoLogoutWorker.stop(requireContext()) + logout() } alertBuilder.setNegativeButton(R.string.no) { dialog, _ -> dialog.cancel() @@ -50,7 +49,8 @@ class SettingsFragment : Fragment() { _binding = null } - private fun logout(sessionManager: SessionManager) { + private fun logout() { + val sessionManager = SessionManager(requireContext()) sessionManager.deleteAuthToken() Toast.makeText(requireContext(), R.string.log_out_success, Toast.LENGTH_SHORT).show() findNavController().popBackStack(R.id.navigation_transaction, true) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 29c47e56b19e76de706812cbc86d529a727fa6b8..f97c4635183e36d7327b23cd0961282b2fec0b66 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ navigationUiKtx = "2.6.0" retrofit = "2.11.0" okhttp3 = "4.12.0" annotation = "1.7.1" +work = "2.9.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -33,6 +34,7 @@ retrofit2-converter-scalars = { group = "com.squareup.retrofit2", name = "conver retrofit2-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" } okhttp3 = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp3" } androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "annotation" } +androidx-work-runtime = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }