diff --git a/app/build.gradle b/app/build.gradle index ffee743e27..dd94c400cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -184,6 +184,7 @@ dependencies { implementation libs.androidx.room.ktx ksp libs.androidx.room.compiler + implementation platform(libs.okhttp.bom) implementation libs.okhttp implementation libs.okhttp.tls implementation libs.okhttp.dnsoverhttps diff --git a/app/src/debug/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt b/app/src/debug/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt index 9bd5f2498d..eba6755035 100644 --- a/app/src/debug/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt +++ b/app/src/debug/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt @@ -1,9 +1,14 @@ package io.github.landwarderer.futon.core.util.ext import android.os.Looper +import android.util.Log fun Throwable.printStackTraceDebug() = printStackTrace() +fun Throwable.printStackTraceDebug(tag: String) = Log.e(tag, this.stackTraceToString()) + +fun Throwable.printStackTraceDebug(tag: String, source: String) = Log.e(tag, "source: $source", this) + fun assertNotInMainThread() = check(Looper.myLooper() != Looper.getMainLooper()) { "Calling this from the main thread is prohibited" } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/alternatives/ui/AutoFixService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/alternatives/ui/AutoFixService.kt index 458c916f73..646c2c095c 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/alternatives/ui/AutoFixService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/alternatives/ui/AutoFixService.kt @@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat import coil3.ImageLoader import coil3.request.ImageRequest import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.runBlocking import io.github.landwarderer.futon.R import io.github.landwarderer.futon.alternatives.domain.AutoFixUseCase import io.github.landwarderer.futon.alternatives.domain.AutoFixUseCase.NoAlternativesException @@ -32,6 +31,7 @@ import io.github.landwarderer.futon.core.util.ext.toBitmapOrNull import io.github.landwarderer.futon.core.util.ext.withPartialWakeLock import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.runBlocking import javax.inject.Inject import androidx.appcompat.R as appcompatR @@ -196,7 +196,7 @@ class AutoFixService : CoroutineIntentService() { ContextCompat.startForegroundService(context, intent) true } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("AutoFixService::start") false } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/BackupUtils.kt b/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/BackupUtils.kt index 7248b41150..5b010fae06 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/BackupUtils.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/BackupUtils.kt @@ -29,7 +29,7 @@ object BackupUtils { fun parseBackupDateTime(fileName: String): Date? = try { dateTimeFormat.parse(fileName.substringAfterLast('_').substringBefore('.')) } catch (e: ParseException) { - e.printStackTraceDebug() + e.printStackTraceDebug("BackupUtils::parseBackupDateTime") null } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/ExternalBackupStorage.kt b/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/ExternalBackupStorage.kt index 912b4f7a19..8e21331a4d 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/ExternalBackupStorage.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/backups/domain/ExternalBackupStorage.kt @@ -5,15 +5,15 @@ import android.net.Uri import androidx.annotation.CheckResult import androidx.documentfile.provider.DocumentFile import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.landwarderer.futon.core.prefs.AppSettings +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug +import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runInterruptible import okio.buffer import okio.sink import okio.source import org.jetbrains.annotations.Blocking -import io.github.landwarderer.futon.core.prefs.AppSettings -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug -import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import java.io.File import javax.inject.Inject @@ -40,7 +40,7 @@ class ExternalBackupStorage @Inject constructor( suspend fun listOrNull() = runCatchingCancellable { list() }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("ExternalBackupStorage::listOrNull") }.getOrNull() suspend fun put(file: File): Uri = runInterruptible(Dispatchers.IO) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/backup/BackupService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/backup/BackupService.kt index 79c4fec062..0f923f9dcc 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/backup/BackupService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/backup/BackupService.kt @@ -12,11 +12,6 @@ import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat import androidx.documentfile.provider.DocumentFile import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.backups.data.BackupRepository import io.github.landwarderer.futon.backups.ui.BaseBackupRestoreService @@ -28,6 +23,11 @@ import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.toUriOrNull import io.github.landwarderer.futon.core.util.ext.withPartialWakeLock import io.github.landwarderer.futon.core.util.progress.Progress +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.io.FileNotFoundException import java.util.zip.ZipOutputStream import javax.inject.Inject @@ -124,7 +124,7 @@ class BackupService : BaseBackupRestoreService() { ContextCompat.startForegroundService(context, intent) true } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("BackupService::start") false } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreService.kt index 099e7c400a..ab2dd70986 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreService.kt @@ -10,9 +10,6 @@ import androidx.annotation.CheckResult import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch import io.github.landwarderer.futon.R import io.github.landwarderer.futon.backups.data.BackupRepository import io.github.landwarderer.futon.backups.domain.BackupSection @@ -25,6 +22,9 @@ import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.toUriOrNull import io.github.landwarderer.futon.core.util.ext.withPartialWakeLock import io.github.landwarderer.futon.core.util.progress.Progress +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch import java.io.FileNotFoundException import java.util.zip.ZipInputStream import javax.inject.Inject @@ -111,7 +111,7 @@ class RestoreService : BaseBackupRestoreService() { ContextCompat.startForegroundService(context, intent) true } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("RestoreService::start") false } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreViewModel.kt index 269c699e2a..952dd8c5b0 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/backups/ui/restore/RestoreViewModel.kt @@ -4,17 +4,17 @@ import android.content.Context import androidx.lifecycle.SavedStateHandle import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.runInterruptible -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.decodeFromStream import io.github.landwarderer.futon.backups.data.model.BackupIndex import io.github.landwarderer.futon.backups.domain.BackupSection import io.github.landwarderer.futon.core.nav.AppRouter import io.github.landwarderer.futon.core.ui.BaseViewModel import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.toUriOrNull +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.runInterruptible +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream import java.io.FileNotFoundException import java.io.InputStream import java.util.Date @@ -107,6 +107,6 @@ class RestoreViewModel @Inject constructor( val index = Json.decodeFromStream>(this) Date(index.single().createdAt) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("RestoreViewModel::InputStream") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/bookmarks/domain/BookmarksRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/bookmarks/domain/BookmarksRepository.kt index b79d316f0e..66cd990405 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/bookmarks/domain/BookmarksRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/bookmarks/domain/BookmarksRepository.kt @@ -3,8 +3,6 @@ package io.github.landwarderer.futon.bookmarks.domain import android.database.SQLException import androidx.room.withTransaction import dagger.Reusable -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import io.github.landwarderer.futon.bookmarks.data.BookmarkEntity import io.github.landwarderer.futon.bookmarks.data.toBookmark import io.github.landwarderer.futon.bookmarks.data.toBookmarks @@ -17,6 +15,8 @@ import io.github.landwarderer.futon.core.ui.util.ReversibleHandle import io.github.landwarderer.futon.core.util.ext.mapItems import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.model.Manga +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map import javax.inject.Inject @Reusable @@ -94,7 +94,7 @@ class BookmarksRepository @Inject constructor( try { db.getBookmarksDao().insert(e) } catch (e: SQLException) { - e.printStackTraceDebug() + e.printStackTraceDebug("BookmarksRepository::reverse") } } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserActivity.kt b/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserActivity.kt index a204e5f0b2..774ec25e9d 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserActivity.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserActivity.kt @@ -9,7 +9,6 @@ import androidx.activity.result.contract.ActivityResultContract import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.exceptions.InteractiveActionRequiredException import io.github.landwarderer.futon.core.nav.AppRouter @@ -18,6 +17,7 @@ import io.github.landwarderer.futon.core.parser.ParserMangaRepository import io.github.landwarderer.futon.core.util.ext.getDisplayMessage import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.model.MangaSource +import kotlinx.coroutines.launch @AndroidEntryPoint class BrowserActivity : BaseBrowserActivity() { @@ -29,7 +29,7 @@ class BrowserActivity : BaseBrowserActivity() { try { proxyProvider.applyWebViewConfig() } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("BrowserActivity::onCreate2") Snackbar.make(viewBinding.webView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() } if (savedInstanceState == null) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/browser/cloudflare/CloudFlareActivity.kt b/app/src/main/kotlin/io/github/landwarderer/futon/browser/cloudflare/CloudFlareActivity.kt index 99fcdc2421..824c6a75cc 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/browser/cloudflare/CloudFlareActivity.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/browser/cloudflare/CloudFlareActivity.kt @@ -10,12 +10,6 @@ import androidx.core.view.isInvisible import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.runInterruptible -import kotlinx.coroutines.yield -import okhttp3.HttpUrl -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import io.github.landwarderer.futon.R import io.github.landwarderer.futon.browser.BaseBrowserActivity import io.github.landwarderer.futon.core.exceptions.CloudFlareProtectedException @@ -30,6 +24,12 @@ import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.network.CloudFlareHelper import io.github.landwarderer.futon.parsers.util.ifNullOrEmpty import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.runInterruptible +import kotlinx.coroutines.yield +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import javax.inject.Inject @AndroidEntryPoint @@ -110,7 +110,7 @@ class CloudFlareActivity : BaseBrowserActivity(), CloudFlareCallback { runCatchingCancellable { captchaHandler.discard(MangaSource(source)) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("CloudFlareActivity::onCheckPassed") } } finishAfterTransition() diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/ErrorReporterReceiver.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/ErrorReporterReceiver.kt index 6359ef7484..82444a581e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/ErrorReporterReceiver.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/ErrorReporterReceiver.kt @@ -74,7 +74,7 @@ class ErrorReporterReceiver : BroadcastReceiver() { PendingIntentCompat.getBroadcast(context, 0, intent, 0, false) }.onFailure { e -> // probably cannot write exception as serializable - e.printStackTraceDebug() + e.printStackTraceDebug("ErrorReporterReceiver::getPendingIntentInternal") }.getOrNull() } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/exceptions/resolve/CaptchaHandler.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/exceptions/resolve/CaptchaHandler.kt index eed2b40097..d2ab4376d5 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/exceptions/resolve/CaptchaHandler.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/exceptions/resolve/CaptchaHandler.kt @@ -26,14 +26,6 @@ import coil3.request.allowHardware import coil3.request.lifecycle import coil3.size.Scale import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.LocalizedAppContext import io.github.landwarderer.futon.core.db.MangaDatabase @@ -58,6 +50,14 @@ import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.network.CloudFlareHelper import io.github.landwarderer.futon.parsers.util.mapToArray import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Provider import javax.inject.Singleton @@ -256,7 +256,7 @@ class CaptchaHandler @Inject constructor( .build(), ).toBitmapOrNull() }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("CaptchaHandler::getFavicon") }.getOrNull() @AndroidEntryPoint diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt index f538671639..c7d3d8c80b 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt @@ -2,13 +2,6 @@ package io.github.landwarderer.futon.core.github import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.Request -import org.json.JSONObject import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.network.BaseHttpClient @@ -16,6 +9,13 @@ import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.util.await import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton @@ -72,7 +72,7 @@ class AppUpdateRepository @Inject constructor( description = json.getString("body"), ) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("AppUpdateRepository::fetchUpdate") }.onSuccess { availableUpdate.value = it }.getOrNull() @@ -86,7 +86,7 @@ class AppUpdateRepository @Inject constructor( .build() okHttp.newCall(request).await().body?.string() }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("AppUpdateRepository::fetchChangelog") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/image/BitmapDecoderCompat.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/image/BitmapDecoderCompat.kt index eb998326b0..308992ed82 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/image/BitmapDecoderCompat.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/image/BitmapDecoderCompat.kt @@ -8,12 +8,6 @@ import android.os.Build import androidx.annotation.RequiresApi import androidx.core.graphics.createBitmap import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException -import okio.IOException -import okio.buffer -import okio.source -import org.aomedia.avif.android.AvifDecoder -import org.aomedia.avif.android.AvifDecoder.Info -import org.jetbrains.annotations.Blocking import io.github.landwarderer.futon.core.util.MimeTypes import io.github.landwarderer.futon.core.util.ext.MimeType import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug @@ -21,6 +15,12 @@ import io.github.landwarderer.futon.core.util.ext.readByteBuffer import io.github.landwarderer.futon.core.util.ext.toByteBuffer import io.github.landwarderer.futon.core.util.ext.toMimeTypeOrNull import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import okio.IOException +import okio.buffer +import okio.source +import org.aomedia.avif.android.AvifDecoder +import org.aomedia.avif.android.AvifDecoder.Info +import org.jetbrains.annotations.Blocking import java.io.File import java.io.InputStream import java.nio.ByteBuffer @@ -67,7 +67,7 @@ object BitmapDecoderCompat { BitmapRegionDecoder.newInstance(inoutStream, false) } } catch (e: IOException) { - e.printStackTraceDebug() + e.printStackTraceDebug("DecoderConfigListener::createRegionDecoder") null } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt index d037efc940..340af3e6cd 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt @@ -628,7 +628,7 @@ class AppRouter private constructor( private fun getFragmentManager(): FragmentManager? = runCatching { fragment?.childFragmentManager ?: activity?.supportFragmentManager }.onFailure { exception -> - exception.printStackTraceDebug() + exception.printStackTraceDebug("AppRouter::getFragmentManager") }.getOrNull() private fun shareLink(link: String, title: String) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/CommonHeadersInterceptor.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/CommonHeadersInterceptor.kt index 38da8b56d8..b76b99b00a 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/CommonHeadersInterceptor.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/CommonHeadersInterceptor.kt @@ -1,12 +1,6 @@ package io.github.landwarderer.futon.core.network import dagger.Lazy -import okhttp3.Headers -import okhttp3.Interceptor -import okhttp3.Interceptor.Chain -import okhttp3.Request -import okhttp3.Response -import okio.IOException import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.core.model.MangaSource import io.github.landwarderer.futon.core.parser.MangaLoaderContextImpl @@ -17,6 +11,12 @@ import io.github.landwarderer.futon.parsers.model.MangaParserSource import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.util.mergeWith import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import okhttp3.Headers +import okhttp3.Interceptor +import okhttp3.Interceptor.Chain +import okhttp3.Request +import okhttp3.Response +import okio.IOException import java.net.IDN import javax.inject.Inject import javax.inject.Singleton @@ -59,7 +59,7 @@ class CommonHeadersInterceptor @Inject constructor( private fun Headers.Builder.trySet(name: String, value: String) = try { set(name, value) } catch (e: IllegalArgumentException) { - e.printStackTraceDebug() + e.printStackTraceDebug("CommonHeadersInterceptor::trySet") } private fun Interceptor.interceptSafe(chain: Chain): Response = runCatchingCancellable { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/DoHManager.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/DoHManager.kt index ff7c26446f..7c81e32c99 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/DoHManager.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/DoHManager.kt @@ -1,12 +1,12 @@ package io.github.landwarderer.futon.core.network +import io.github.landwarderer.futon.core.prefs.AppSettings +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import okhttp3.Cache import okhttp3.Dns import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.dnsoverhttps.DnsOverHttps -import io.github.landwarderer.futon.core.prefs.AppSettings -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import java.net.InetAddress import java.net.UnknownHostException @@ -93,7 +93,7 @@ class DoHManager( private fun tryGetByIp(ip: String): InetAddress? = try { InetAddress.getByName(ip) } catch (e: UnknownHostException) { - e.printStackTraceDebug() + e.printStackTraceDebug("DoHManager::tryGetByIp") null } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/NetworkModule.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/NetworkModule.kt index edae97adbf..4ec8f2e5f3 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/NetworkModule.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/NetworkModule.kt @@ -1,15 +1,13 @@ package io.github.landwarderer.futon.core.network import android.content.Context +import android.util.Log import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import okhttp3.Cache -import okhttp3.CookieJar -import okhttp3.OkHttpClient import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.core.network.cookies.AndroidCookieJar import io.github.landwarderer.futon.core.network.cookies.MutableCookieJar @@ -19,8 +17,10 @@ import io.github.landwarderer.futon.core.network.imageproxy.RealImageProxyInterc import io.github.landwarderer.futon.core.network.proxy.ProxyProvider import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.util.ext.assertNotInMainThread -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.local.data.LocalStorageManager +import okhttp3.Cache +import okhttp3.CookieJar +import okhttp3.OkHttpClient import java.util.concurrent.TimeUnit import javax.inject.Provider import javax.inject.Singleton @@ -29,74 +29,70 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) interface NetworkModule { - @Binds - fun bindCookieJar(androidCookieJar: MutableCookieJar): CookieJar + @Binds + fun bindCookieJar(androidCookieJar: MutableCookieJar): CookieJar - @Binds - fun bindImageProxyInterceptor(impl: RealImageProxyInterceptor): ImageProxyInterceptor + @Binds + fun bindImageProxyInterceptor(impl: RealImageProxyInterceptor): ImageProxyInterceptor - companion object { + companion object { - @Provides - @Singleton - fun provideCookieJar( - @ApplicationContext context: Context - ): MutableCookieJar = runCatching { - AndroidCookieJar() - }.getOrElse { e -> - e.printStackTraceDebug() - // WebView is not available - PreferencesCookieJar(context) - } + @Provides + @Singleton + fun provideCookieJar( + @ApplicationContext context: Context + ): MutableCookieJar = runCatching { + AndroidCookieJar() + }.getOrElse { e -> + Log.e("NetworkModule::provideCookieJar", e.stackTraceToString()) + // WebView is not available + PreferencesCookieJar(context) + } - @Provides - @Singleton - fun provideHttpCache( - localStorageManager: LocalStorageManager, - ): Cache = localStorageManager.createHttpCache() + @Provides + @Singleton + fun provideHttpCache( + localStorageManager: LocalStorageManager, + ): Cache = localStorageManager.createHttpCache() - @Provides - @Singleton - @BaseHttpClient - fun provideBaseHttpClient( - @ApplicationContext contextProvider: Provider, - cache: Cache, - cookieJar: CookieJar, - settings: AppSettings, - proxyProvider: ProxyProvider, - ): OkHttpClient = OkHttpClient.Builder().apply { - assertNotInMainThread() - connectTimeout(20, TimeUnit.SECONDS) - readTimeout(60, TimeUnit.SECONDS) - writeTimeout(20, TimeUnit.SECONDS) - cookieJar(cookieJar) - proxySelector(proxyProvider.selector) - proxyAuthenticator(proxyProvider.authenticator) - dns(DoHManager(cache, settings)) - if (settings.isSSLBypassEnabled) { - disableCertificateVerification() - } else { - installExtraCertificates(contextProvider.get()) - } - cache(cache) - addInterceptor(GZipInterceptor()) - addInterceptor(CloudFlareInterceptor()) - addInterceptor(RateLimitInterceptor()) - if (BuildConfig.DEBUG) { - addInterceptor(CurlLoggingInterceptor()) - } - }.build() + @Provides + @Singleton + @BaseHttpClient + fun provideBaseHttpClient( + @ApplicationContext contextProvider: Provider, + cache: Cache, + cookieJar: CookieJar, + settings: AppSettings, + proxyProvider: ProxyProvider, + ): OkHttpClient = OkHttpClient.Builder().apply { + assertNotInMainThread() + connectTimeout(20, TimeUnit.SECONDS) + readTimeout(60, TimeUnit.SECONDS) + writeTimeout(20, TimeUnit.SECONDS) + cookieJar(cookieJar) + proxySelector(proxyProvider.selector) + proxyAuthenticator(proxyProvider.authenticator) + dns(DoHManager(cache, settings)) + installExtraCertificates(contextProvider.get()) + applyTlsConfiguration() + cache(cache) + addInterceptor(CloudFlareInterceptor()) + addInterceptor(RateLimitInterceptor()) + if (BuildConfig.DEBUG) { + addInterceptor(CurlLoggingInterceptor()) + } + }.build() - @Provides - @Singleton - @MangaHttpClient - fun provideMangaHttpClient( - @BaseHttpClient baseClient: OkHttpClient, - commonHeadersInterceptor: CommonHeadersInterceptor, - ): OkHttpClient = baseClient.newBuilder().apply { - addNetworkInterceptor(CacheLimitInterceptor()) - addInterceptor(commonHeadersInterceptor) - }.build() + @Provides + @Singleton + @MangaHttpClient + fun provideMangaHttpClient( + @BaseHttpClient baseClient: OkHttpClient, + commonHeadersInterceptor: CommonHeadersInterceptor, + ): OkHttpClient = baseClient.newBuilder().apply { + addNetworkInterceptor(CacheLimitInterceptor()) + addInterceptor(commonHeadersInterceptor) + }.build() - } + } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/SSLUtils.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/SSLUtils.kt index 8f3a6196e9..62206db1bf 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/SSLUtils.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/SSLUtils.kt @@ -4,60 +4,93 @@ import android.annotation.SuppressLint import android.content.Context import android.content.res.AssetManager import android.util.Log -import okhttp3.OkHttpClient -import okhttp3.tls.HandshakeCertificates import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug +import okhttp3.CipherSuite +import okhttp3.ConnectionSpec +import okhttp3.OkHttpClient +import okhttp3.TlsVersion +import okhttp3.tls.HandshakeCertificates +import org.conscrypt.Conscrypt import java.security.SecureRandom import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import javax.net.ssl.SSLContext -import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager -@SuppressLint("CustomX509TrustManager") -fun OkHttpClient.Builder.disableCertificateVerification() = also { builder -> - runCatching { - val trustAllCerts = object : X509TrustManager { - override fun checkClientTrusted(chain: Array, authType: String) = Unit - - override fun checkServerTrusted(chain: Array, authType: String) = Unit - - override fun getAcceptedIssuers(): Array = emptyArray() - } - val sslContext = SSLContext.getInstance("SSL") - sslContext.init(null, arrayOf(trustAllCerts), SecureRandom()) - val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory - builder.sslSocketFactory(sslSocketFactory, trustAllCerts) - builder.hostnameVerifier { _, _ -> true } - }.onFailure { - it.printStackTraceDebug() - } +@SuppressLint("CustomX509TrustManager, TrustAllX509TrustManager") +fun OkHttpClient.Builder.applyTlsConfiguration() = also { builder -> + runCatching { + val trustAllCerts = object : X509TrustManager { + override fun checkClientTrusted(p0: Array?, p1: String?) {} + override fun checkServerTrusted(p0: Array?, p1: String?) {} + override fun getAcceptedIssuers(): Array = emptyArray() + } + + val sslContext = SSLContext.getInstance("TLS", Conscrypt.newProvider()) + sslContext.init(null, arrayOf(trustAllCerts), SecureRandom()) + + val spec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions( + TlsVersion.TLS_1_3, + TlsVersion.TLS_1_2, + TlsVersion.TLS_1_1, + TlsVersion.TLS_1_0, + ) + .cipherSuites( + CipherSuite.TLS_AES_128_GCM_SHA256, + CipherSuite.TLS_AES_256_GCM_SHA384, + CipherSuite.TLS_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + ) + .build() + + builder.sslSocketFactory(sslContext.socketFactory, trustAllCerts) + builder.connectionSpecs(listOf(spec, ConnectionSpec.CLEARTEXT)) + builder.hostnameVerifier { _, _ -> true } + + // "Fake" browser to avoid 403s/Handshake blocks because Cloudflare checks the User-Agent + // against the TLS Fingerprint and if they don't match, it triggers a challenge or a block. + builder.addInterceptor { chain -> + val request = chain.request().newBuilder() + .header( + "User-Agent", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36", + ) + .header("Sec-CH-UA", "\"Chromium\";v=\"146\", \"Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"146\"") + .header("Sec-CH-UA-Mobile", "?0") + .header("Sec-CH-UA-Platform", "\"Windows\"") + .build() + chain.proceed(request) + } + }.onFailure { it.printStackTraceDebug("SSLUtils::applyTlsConfiguration") } } fun OkHttpClient.Builder.installExtraCertificates(context: Context) = also { builder -> - val certificatesBuilder = HandshakeCertificates.Builder() - .addPlatformTrustedCertificates() - val assets = context.assets.list("").orEmpty() - for (path in assets) { - if (path.endsWith(".pem")) { - val cert = loadCert(context, path) ?: continue - certificatesBuilder.addTrustedCertificate(cert) - } - } - val certificates = certificatesBuilder.build() - builder.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager) + val certificatesBuilder = HandshakeCertificates.Builder() + .addPlatformTrustedCertificates() + val assets = context.assets.list("").orEmpty() + for (path in assets) { + if (path.endsWith(".pem")) { + val cert = loadCert(context, path) ?: continue + certificatesBuilder.addTrustedCertificate(cert) + } + } + val certificates = certificatesBuilder.build() + builder.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager) } private fun loadCert(context: Context, path: String): X509Certificate? = runCatching { - val cf = CertificateFactory.getInstance("X.509") - context.assets.open(path, AssetManager.ACCESS_STREAMING).use { - cf.generateCertificate(it) - } as X509Certificate -}.onFailure { e -> - e.printStackTraceDebug() -}.onSuccess { - if (BuildConfig.DEBUG) { - Log.i("ExtraCerts", "Loaded cert $path") - } -}.getOrNull() + val cf = CertificateFactory.getInstance("X.509") + context.assets.open(path, AssetManager.ACCESS_STREAMING).use { + cf.generateCertificate(it) + } as X509Certificate +}.onFailure { it.printStackTraceDebug("SSLUtils::loadCert") } + .onSuccess { + if (BuildConfig.DEBUG) { + Log.i("ExtraCerts", "Loaded cert $path") + } + }.getOrNull() diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/cookies/PreferencesCookieJar.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/cookies/PreferencesCookieJar.kt index 2ef68ca4c4..b71e81d207 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/cookies/PreferencesCookieJar.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/cookies/PreferencesCookieJar.kt @@ -5,11 +5,11 @@ import androidx.annotation.WorkerThread import androidx.collection.ArrayMap import androidx.core.content.edit import androidx.core.util.Predicate +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.Cookie import okhttp3.HttpUrl -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug private const val PREFS_NAME = "cookies" @@ -91,7 +91,7 @@ class PreferencesCookieJar( val cookie = try { CookieWrapper(v as String) } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("PreferencesCookieJar::loadPersistent") continue } cache[k] = cookie diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/WebViewExecutor.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/WebViewExecutor.kt index f9bdaa2ac7..5358b8cec3 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/WebViewExecutor.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/WebViewExecutor.kt @@ -7,12 +7,6 @@ import android.webkit.WebView import android.webkit.WebViewClient import androidx.annotation.MainThread import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import kotlinx.coroutines.withTimeout import io.github.landwarderer.futon.core.exceptions.CloudFlareException import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.network.cookies.MutableCookieJar @@ -23,6 +17,12 @@ import io.github.landwarderer.futon.core.util.ext.configureForParser import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeout import java.lang.ref.WeakReference import javax.inject.Inject import javax.inject.Provider @@ -45,7 +45,7 @@ class WebViewExecutor @Inject constructor( try { WebSettings.getDefaultUserAgent(context) } catch (e: AndroidRuntimeException) { - e.printStackTraceDebug() + e.printStackTraceDebug("WebViewExecutor::defaultUserAgent") // Probably WebView is not available null } @@ -96,7 +96,7 @@ class WebViewExecutor @Inject constructor( } }.onFailure { e -> exception.addSuppressed(e) - e.printStackTraceDebug() + e.printStackTraceDebug("WebViewExecutor::tryResolveCaptcha") }.isSuccess } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/adblock/AdBlock.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/adblock/AdBlock.kt index dfb729186f..d26a9b3ef8 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/adblock/AdBlock.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/network/webview/adblock/AdBlock.kt @@ -5,11 +5,6 @@ import android.util.Log import androidx.annotation.WorkerThread import dagger.Reusable import dagger.hilt.android.qualifiers.ApplicationContext -import okhttp3.HttpUrl -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import okhttp3.OkHttpClient -import okhttp3.Request -import okio.sink import io.github.landwarderer.futon.core.network.BaseHttpClient import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.prefs.AppSettings @@ -18,6 +13,11 @@ import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.util.await import io.github.landwarderer.futon.parsers.util.requireBody import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.OkHttpClient +import okhttp3.Request +import okio.sink import java.io.File import java.net.HttpURLConnection import java.text.SimpleDateFormat @@ -66,7 +66,7 @@ class AdBlock @Inject constructor( rules } }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("AdBlock::parseRules") }.getOrNull() class Updater @Inject constructor( diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/os/AppShortcutManager.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/os/AppShortcutManager.kt index f4fdc1ffb8..5e4388590a 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/os/AppShortcutManager.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/os/AppShortcutManager.kt @@ -15,10 +15,6 @@ import coil3.request.ImageRequest import coil3.request.transformations import coil3.size.Scale import coil3.size.Size -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.LocalizedAppContext import io.github.landwarderer.futon.core.db.TABLE_HISTORY @@ -39,6 +35,10 @@ import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.util.ifNullOrEmpty import io.github.landwarderer.futon.parsers.util.mapNotNullToSet import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Singleton @@ -84,14 +84,14 @@ class AppShortcutManager @Inject constructor( suspend fun requestPinShortcut(manga: Manga): Boolean = try { ShortcutManagerCompat.requestPinShortcut(context, buildShortcutInfo(manga), null) } catch (e: IllegalStateException) { - e.printStackTraceDebug() + e.printStackTraceDebug("AppShortcutManager::requestPinShortcut") false } suspend fun requestPinShortcut(source: MangaSource): Boolean = try { ShortcutManagerCompat.requestPinShortcut(context, buildShortcutInfo(source), null) } catch (e: IllegalStateException) { - e.printStackTraceDebug() + e.printStackTraceDebug("AppShortcutManager::requestPinShortcut") false } @@ -124,7 +124,7 @@ class AppShortcutManager @Inject constructor( .map { buildShortcutInfo(it) } ShortcutManagerCompat.setDynamicShortcuts(context, shortcuts) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("AppShortcutManager::updateShortcutsImpl") } private fun clearShortcuts() { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/external/ExternalMangaRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/external/ExternalMangaRepository.kt index ac4c65113d..0fd9cdee03 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/external/ExternalMangaRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/external/ExternalMangaRepository.kt @@ -1,8 +1,6 @@ package io.github.landwarderer.futon.core.parser.external import android.content.ContentResolver -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runInterruptible import io.github.landwarderer.futon.core.cache.MemoryContentCache import io.github.landwarderer.futon.core.parser.CachingMangaRepository import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug @@ -14,6 +12,8 @@ import io.github.landwarderer.futon.parsers.model.MangaListFilterOptions import io.github.landwarderer.futon.parsers.model.MangaPage import io.github.landwarderer.futon.parsers.model.SortOrder import io.github.landwarderer.futon.parsers.util.suspendlazy.suspendLazy +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runInterruptible import java.util.EnumSet class ExternalMangaRepository( @@ -28,7 +28,7 @@ class ExternalMangaRepository( runCatching { contentSource.getCapabilities() }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ExternalMangaRepository::capabilities") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/favicon/FaviconFetcher.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/favicon/FaviconFetcher.kt index 03ac95596d..c03f8d4d79 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/favicon/FaviconFetcher.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/parser/favicon/FaviconFetcher.kt @@ -19,12 +19,6 @@ import coil3.request.Options import coil3.size.pxOrElse import coil3.toAndroidUri import coil3.toBitmap -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.ensureActive -import kotlinx.coroutines.runInterruptible -import okio.FileSystem -import okio.IOException -import okio.Path.Companion.toOkioPath import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.exceptions.CloudFlareProtectedException import io.github.landwarderer.futon.core.model.MangaSource @@ -40,6 +34,12 @@ import io.github.landwarderer.futon.local.data.FaviconCache import io.github.landwarderer.futon.local.data.LocalMangaRepository import io.github.landwarderer.futon.local.data.LocalStorageCache import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.runInterruptible +import okio.FileSystem +import okio.IOException +import okio.Path.Companion.toOkioPath import java.io.File import javax.inject.Inject import coil3.Uri as CoilUri @@ -146,7 +146,7 @@ class FaviconFetcher( } } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("FaviconFetcher::writeToCache") }.getOrDefault(result) private fun File.asFetchResult() = SourceFetchResult( diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/BaseViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/BaseViewModel.kt index 033ca38c06..64d29ae9ff 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/BaseViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/BaseViewModel.kt @@ -2,6 +2,10 @@ package io.github.landwarderer.futon.core.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import io.github.landwarderer.futon.core.util.ext.EventFlow +import io.github.landwarderer.futon.core.util.ext.MutableEventFlow +import io.github.landwarderer.futon.core.util.ext.call +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope @@ -18,10 +22,6 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import io.github.landwarderer.futon.core.util.ext.EventFlow -import io.github.landwarderer.futon.core.util.ext.MutableEventFlow -import io.github.landwarderer.futon.core.util.ext.call -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -66,7 +66,7 @@ abstract class BaseViewModel : ViewModel() { } protected fun Flow.withErrorHandling() = catch { error -> - error.printStackTraceDebug() + error.printStackTraceDebug("BaseViewModel::launchLoadingJob") errorEvent.call(error) } @@ -99,7 +99,7 @@ abstract class BaseViewModel : ViewModel() { CoroutineExceptionHandler { override fun handleException(context: CoroutineContext, exception: Throwable) { - exception.printStackTraceDebug() + exception.printStackTraceDebug("BaseViewModel::handleException") if (context[SkipErrors.key] == null && exception !is CancellationException) { event.call(exception) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/CoroutineIntentService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/CoroutineIntentService.kt index 049e2f7120..35c87bc2a8 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/CoroutineIntentService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/CoroutineIntentService.kt @@ -14,6 +14,7 @@ import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat import androidx.core.net.toUri import androidx.lifecycle.lifecycleScope +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -22,7 +23,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug abstract class CoroutineIntentService : BaseService() { @@ -46,7 +46,7 @@ abstract class CoroutineIntentService : BaseService() { } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("CoroutineIntentService::launchCoroutine") intentJobContext.onError(e) } finally { intentJobContext.stop() @@ -100,7 +100,7 @@ abstract class CoroutineIntentService : BaseService() { try { unregisterReceiver(it) } catch (e: IllegalArgumentException) { - e.printStackTraceDebug() + e.printStackTraceDebug("CoroutineIntentService::stop") } } isStopped = true diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/util/ReversibleHandle.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/util/ReversibleHandle.kt index 9ea6235ceb..2e2e551f9d 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/util/ReversibleHandle.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/util/ReversibleHandle.kt @@ -1,13 +1,13 @@ package io.github.landwarderer.futon.core.ui.util +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug +import io.github.landwarderer.futon.core.util.ext.processLifecycleScope +import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug -import io.github.landwarderer.futon.core.util.ext.processLifecycleScope -import io.github.landwarderer.futon.parsers.util.runCatchingCancellable fun interface ReversibleHandle { @@ -20,6 +20,6 @@ fun ReversibleHandle.reverseAsync() = processLifecycleScope.launch(Dispatchers.I reverse() } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ReversibleHandle::reverseAsync") } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/AcraCoroutineErrorHandler.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/AcraCoroutineErrorHandler.kt index f128794be7..0139c14b48 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/AcraCoroutineErrorHandler.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/AcraCoroutineErrorHandler.kt @@ -1,8 +1,8 @@ package io.github.landwarderer.futon.core.util -import kotlinx.coroutines.CoroutineExceptionHandler import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.report +import kotlinx.coroutines.CoroutineExceptionHandler import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.coroutines.CoroutineContext @@ -10,7 +10,7 @@ class AcraCoroutineErrorHandler : AbstractCoroutineContextElement(CoroutineExcep CoroutineExceptionHandler { override fun handleException(context: CoroutineContext, exception: Throwable) { - exception.printStackTraceDebug() + exception.printStackTraceDebug("AcraCoroutineErrorHandler::handleException") exception.report() } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Android.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Android.kt index c5f53c85db..52682ed0d7 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Android.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Android.kt @@ -43,6 +43,10 @@ import androidx.lifecycle.coroutineScope import androidx.webkit.WebViewCompat import androidx.webkit.WebViewFeature import androidx.work.CoroutineWorker +import io.github.landwarderer.futon.BuildConfig +import io.github.landwarderer.futon.R +import io.github.landwarderer.futon.main.ui.MainActivity +import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -51,10 +55,6 @@ import okio.IOException import okio.use import org.json.JSONException import org.jsoup.internal.StringUtil.StringJoiner -import io.github.landwarderer.futon.BuildConfig -import io.github.landwarderer.futon.R -import io.github.landwarderer.futon.main.ui.MainActivity -import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.File @@ -89,7 +89,7 @@ fun ActivityResultLauncher.tryLaunch( ): Boolean = runCatching { launch(input, options) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("AndroidKt::CoroutineWorker") }.isSuccess fun Lifecycle.postDelayed(delay: Long, runnable: Runnable) { @@ -108,7 +108,7 @@ fun SyncResult.onError(error: Throwable) { is JSONException -> stats.numParseExceptions++ else -> if (BuildConfig.DEBUG) throw error } - error.printStackTraceDebug() + error.printStackTraceDebug("AndroidKt::SyncResult") } val Context.animatorDurationScale: Float @@ -158,9 +158,9 @@ fun Context.getLocalesConfig(): LocaleListCompat { xpp.next() } } catch (e: XmlPullParserException) { - e.printStackTraceDebug() + e.printStackTraceDebug("AndroidKt::Context") } catch (e: IOException) { - e.printStackTraceDebug() + e.printStackTraceDebug("AndroidKt::Context") } return LocaleListCompat.forLanguageTags(tagsList.complete()) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/ContentResolver.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/ContentResolver.kt index 5fac02cce0..e653ae5093 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/ContentResolver.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/ContentResolver.kt @@ -46,7 +46,7 @@ fun ContentResolver.getFileDisplayName(uri: Uri): String? = runCatching { } } }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("ContentResolver::getFileDisplayName") }.getOrNull() private fun getVolumePath(volumeId: String, context: Context): String? { @@ -78,7 +78,7 @@ private fun getVolumePathBeforeAndroid11(volumeId: String, context: Context): St } } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ContentResolver::getVolumePathBeforeAndroid11") }.getOrNull() @RequiresApi(Build.VERSION_CODES.R) @@ -93,7 +93,7 @@ private fun getVolumePathForAndroid11AndAbove(volumeId: String, context: Context } } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ContentResolver::getVolumePathForAndroid11AndAbove") }.getOrNull() private fun getVolumeIdFromTreeUri(treeUri: Uri): String? { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Resources.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Resources.kt index 5cb35d850a..dc919a717c 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Resources.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/Resources.kt @@ -34,7 +34,7 @@ fun Resources.getQuantityStringSafe(@PluralsRes resId: Int, quantity: Int, varar getQuantityString(resId, quantity, *formatArgs) } catch (e: Resources.NotFoundException) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.VANILLA_ICE_CREAM) { // known issue - e.printStackTraceDebug() + e.printStackTraceDebug("Resources::getQuantityStringSafe") formatArgs.firstOrNull()?.toString() ?: quantity.toString() } else { throw e diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/String.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/String.kt index 19ef935aa4..7b1946f1a4 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/String.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/util/ext/String.kt @@ -10,7 +10,7 @@ import java.util.UUID fun String.toUUIDOrNull(): UUID? = try { UUID.fromString(this) } catch (e: IllegalArgumentException) { - e.printStackTraceDebug() + e.printStackTraceDebug("String::toUUIDOrNull") null } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/zip/ZipOutput.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/zip/ZipOutput.kt index 465b955576..63a3df635e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/zip/ZipOutput.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/zip/ZipOutput.kt @@ -2,10 +2,10 @@ package io.github.landwarderer.futon.core.zip import androidx.annotation.WorkerThread import androidx.collection.ArraySet -import okio.Closeable -import org.jetbrains.annotations.Blocking import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.withChildren +import okio.Closeable +import org.jetbrains.annotations.Blocking import java.io.File import java.io.FileInputStream import java.io.FileOutputStream @@ -139,7 +139,7 @@ class ZipOutput( append = true // after 1st success write } } catch (e: NullPointerException) { // probably NullPointerException: Deflater has been closed - e.printStackTraceDebug() + e.printStackTraceDebug("ZipOutput::withOutput") newOutput(append).withOutputImpl(block) } } @@ -161,7 +161,7 @@ class ZipOutput( close() } catch (e: NullPointerException) { // Don't throw the "Deflater has been closed" exception - e.printStackTraceDebug() + e.printStackTraceDebug("ZipOutput::closeSafe") } } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/details/domain/RelatedMangaUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/details/domain/RelatedMangaUseCase.kt index f1a64a25db..e6c9436c01 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/details/domain/RelatedMangaUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/details/domain/RelatedMangaUseCase.kt @@ -13,6 +13,6 @@ class RelatedMangaUseCase @Inject constructor( suspend operator fun invoke(seed: Manga) = runCatchingCancellable { mangaRepositoryFactory.create(seed.source).getRelated(seed) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("RelatedMangaUseCase::invoke") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/details/service/MangaPrefetchService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/details/service/MangaPrefetchService.kt index 9f304fd0b7..883bc6eaf1 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/details/service/MangaPrefetchService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/details/service/MangaPrefetchService.kt @@ -127,7 +127,7 @@ class MangaPrefetchService : CoroutineIntentService() { context.startService(intent) } catch (e: IllegalStateException) { // probably app is in background - e.printStackTraceDebug() + e.printStackTraceDebug("MangaPrefetchService::tryStart") } } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/pager/chapters/ChaptersSelectionCallback.kt b/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/pager/chapters/ChaptersSelectionCallback.kt index 5fd5dfaff0..6db59179cb 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/pager/chapters/ChaptersSelectionCallback.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/pager/chapters/ChaptersSelectionCallback.kt @@ -87,7 +87,7 @@ class ChaptersSelectionCallback( Snackbar.LENGTH_LONG, ).show() } catch (e: IllegalArgumentException) { - e.printStackTraceDebug() + e.printStackTraceDebug("ChaptersSelectionCallback::onActionItemClicked") Toast.makeText( recyclerView.context, R.string.chapters_will_removed_background, diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/related/RelatedListViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/related/RelatedListViewModel.kt index 3c73a563d3..cb700e61f8 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/related/RelatedListViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/details/ui/related/RelatedListViewModel.kt @@ -3,15 +3,6 @@ package io.github.landwarderer.futon.details.ui.related import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.plus import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.model.parcelable.ParcelableManga import io.github.landwarderer.futon.core.nav.AppRouter @@ -29,6 +20,15 @@ import io.github.landwarderer.futon.list.ui.model.toErrorState import io.github.landwarderer.futon.local.data.LocalStorageChanges import io.github.landwarderer.futon.local.domain.model.LocalManga import io.github.landwarderer.futon.parsers.model.Manga +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.plus import javax.inject.Inject @HiltViewModel @@ -83,7 +83,7 @@ class RelatedListViewModel @Inject constructor( } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("RelatedListViewModel::loadList") listError.value = e if (!mangaList.value.isNullOrEmpty()) { errorEvent.call(e) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/dialog/DownloadDialogViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/dialog/DownloadDialogViewModel.kt index 1c413ed850..4c8c863c6d 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/dialog/DownloadDialogViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/dialog/DownloadDialogViewModel.kt @@ -5,11 +5,6 @@ import androidx.collection.ArraySet import androidx.collection.MutableLongLongMap import androidx.lifecycle.SavedStateHandle import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.MutableStateFlow import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.model.getPreferredBranch import io.github.landwarderer.futon.core.model.parcelable.ParcelableManga @@ -33,6 +28,11 @@ import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.parsers.util.sizeOrZero import io.github.landwarderer.futon.parsers.util.suspendlazy.suspendLazy import io.github.landwarderer.futon.settings.storage.DirectoryModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.MutableStateFlow import javax.inject.Inject @HiltViewModel @@ -231,7 +231,7 @@ class DownloadDialogViewModel @Inject constructor( private suspend fun Manga.getDetails(): Manga = runCatchingCancellable { mangaRepositoryFactory.create(source).getDetails(this) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("DownloadDialogViewModel::Manga") }.getOrDefault(this) private fun MutableMap.increment(key: T) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadNotificationFactory.kt b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadNotificationFactory.kt index 7568a5dd8f..92159c739a 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadNotificationFactory.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadNotificationFactory.kt @@ -19,8 +19,6 @@ import coil3.size.Scale import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.ErrorReporterReceiver import io.github.landwarderer.futon.core.LocalizedAppContext @@ -37,6 +35,8 @@ import io.github.landwarderer.futon.download.ui.list.DownloadsActivity import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.util.format import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import java.util.UUID import androidx.appcompat.R as appcompatR @@ -284,7 +284,7 @@ class DownloadNotificationFactory @AssistedInject constructor( }.onSuccess { covers[manga] = it }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DownloadNotificationFactory::getCover") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadWorker.kt b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadWorker.kt index 476729fe80..b2b3970eaa 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadWorker.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/download/ui/worker/DownloadWorker.kt @@ -24,25 +24,6 @@ import dagger.Reusable import dagger.assisted.Assisted import dagger.assisted.AssistedInject import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import kotlinx.coroutines.runInterruptible -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.internal.closeQuietly -import okio.IOException -import okio.buffer -import okio.sink -import okio.use import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.image.BitmapDecoderCompat import io.github.landwarderer.futon.core.model.ids @@ -93,6 +74,25 @@ import io.github.landwarderer.futon.parsers.util.mapToSet import io.github.landwarderer.futon.parsers.util.requireBody import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.domain.PageLoader +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import kotlinx.coroutines.runInterruptible +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withPermit +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.internal.closeQuietly +import okio.IOException +import okio.buffer +import okio.sink +import okio.use import java.io.File import java.util.UUID import java.util.concurrent.TimeUnit @@ -151,7 +151,7 @@ class DownloadWorker @AssistedInject constructor( currentState.copy(eta = -1L, isStuck = false).toWorkData(), ) } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("DownloadWorker::doWork") Result.failure( currentState.copy( error = e, diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/ExploreRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/ExploreRepository.kt index 612019f6aa..e513b6df06 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/ExploreRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/ExploreRepository.kt @@ -88,6 +88,6 @@ class ExploreRepository @Inject constructor( list.shuffle() list }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ExploreRepository::getList") }.getOrDefault(emptyList()) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/RecoverMangaUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/RecoverMangaUseCase.kt index d7d4767703..0861a54300 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/RecoverMangaUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/explore/domain/RecoverMangaUseCase.kt @@ -27,7 +27,7 @@ class RecoverMangaUseCase @Inject constructor( mangaDataRepository.storeManga(merged, replaceExisting = true) merged }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("RecoverMangaUseCase::invoke") }.getOrNull() private fun merge( diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/filter/data/SavedFiltersRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/filter/data/SavedFiltersRepository.kt index 8d838d9be8..f411179581 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/filter/data/SavedFiltersRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/filter/data/SavedFiltersRepository.kt @@ -5,6 +5,10 @@ import android.content.SharedPreferences import androidx.core.content.edit import dagger.Reusable import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.landwarderer.futon.core.util.ext.observeChanges +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug +import io.github.landwarderer.futon.parsers.model.MangaListFilter +import io.github.landwarderer.futon.parsers.model.MangaSource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged @@ -14,10 +18,6 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.withContext import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json -import io.github.landwarderer.futon.core.util.ext.observeChanges -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug -import io.github.landwarderer.futon.parsers.model.MangaListFilter -import io.github.landwarderer.futon.parsers.model.MangaSource import java.io.File import javax.inject.Inject @@ -41,7 +41,7 @@ class SavedFiltersRepository @Inject constructor( try { Json.decodeFromString(value) } catch (e: SerializationException) { - e.printStackTraceDebug() + e.printStackTraceDebug("SavedFiltersRepository::getAll") null } } @@ -99,7 +99,7 @@ class SavedFiltersRepository @Inject constructor( return try { Json.decodeFromString(json) } catch (e: SerializationException) { - e.printStackTraceDebug() + e.printStackTraceDebug("SavedFiltersRepository::load") null } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/history/domain/HistoryUpdateUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/history/domain/HistoryUpdateUseCase.kt index 86cc998770..8d25d9d68e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/history/domain/HistoryUpdateUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/history/domain/HistoryUpdateUseCase.kt @@ -1,16 +1,16 @@ package io.github.landwarderer.futon.history.domain -import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.core.util.ext.processLifecycleScope import io.github.landwarderer.futon.history.data.HistoryRepository import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.ui.ReaderState +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject class HistoryUpdateUseCase @Inject constructor( @@ -38,7 +38,7 @@ class HistoryUpdateUseCase @Inject constructor( invoke(manga, readerState, percent) } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("HistoryUpdateUseCase::invokeAsync") } } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalMangaRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalMangaRepository.kt index 69a12a4b0f..e67d11aa3e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalMangaRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalMangaRepository.kt @@ -2,14 +2,6 @@ package io.github.landwarderer.futon.local.data import androidx.core.net.toFile import androidx.core.net.toUri -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.toCollection -import kotlinx.coroutines.launch -import kotlinx.coroutines.runInterruptible import io.github.landwarderer.futon.core.model.LocalMangaSource import io.github.landwarderer.futon.core.model.isLocal import io.github.landwarderer.futon.core.model.isNsfw @@ -38,6 +30,14 @@ import io.github.landwarderer.futon.parsers.model.SortOrder import io.github.landwarderer.futon.parsers.util.levenshteinDistance import io.github.landwarderer.futon.parsers.util.mapToSet import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toCollection +import kotlinx.coroutines.launch +import kotlinx.coroutines.runInterruptible import java.io.File import java.util.EnumSet import javax.inject.Inject @@ -162,7 +162,7 @@ class LocalMangaRepository @Inject constructor( return runCatchingCancellable { LocalMangaParser(localManga.url.toUri()).getMangaInfo()?.takeUnless { it.isLocal } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalMangaRepository::getRemoteManga") }.getOrNull() } @@ -187,7 +187,7 @@ class LocalMangaRepository @Inject constructor( send(mangaInput) } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalMangaRepository::findSavedManga") } } } @@ -197,7 +197,7 @@ class LocalMangaRepository @Inject constructor( localMangaIndex.put(x) } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalMangaRepository::findSavedManga") }.getOrNull() override suspend fun getPageUrl(page: MangaPage) = page.url @@ -243,7 +243,7 @@ class LocalMangaRepository @Inject constructor( runCatchingCancellable { LocalMangaParser.getOrNull(file)?.getManga(withDetails = false) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("LocalMangaRepository::getRawListAsFlow") }.onSuccess { m -> if (m != null) send(m) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalStorageCache.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalStorageCache.kt index 3ab47046a4..ab714cdb11 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalStorageCache.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/LocalStorageCache.kt @@ -5,13 +5,6 @@ import android.graphics.Bitmap import android.os.StatFs import android.webkit.MimeTypeMap import com.tomclaw.cache.DiskLruCache -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runInterruptible -import kotlinx.coroutines.withContext -import okio.Source -import okio.buffer -import okio.sink -import okio.use import io.github.landwarderer.futon.core.exceptions.NoDataReceivedException import io.github.landwarderer.futon.core.util.MimeTypes import io.github.landwarderer.futon.core.util.ext.MimeType @@ -24,6 +17,13 @@ import io.github.landwarderer.futon.core.util.ext.writeAllCancellable import io.github.landwarderer.futon.parsers.util.ifNullOrEmpty import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.parsers.util.suspendlazy.suspendLazy +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runInterruptible +import kotlinx.coroutines.withContext +import okio.Source +import okio.buffer +import okio.sink +import okio.use import java.io.File import java.util.UUID @@ -47,7 +47,7 @@ class LocalStorageCache( runCatchingCancellable { DiskLruCache.create(dir, size) }.recoverCatching { error -> - error.printStackTraceDebug() + error.printStackTraceDebug("LocalStorageCache::lruCache") dir.deleteRecursively() dir.mkdir() DiskLruCache.create(dir, size) @@ -106,7 +106,7 @@ class LocalStorageCache( statFs.availableBytes } }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalStorageCache::getAvailableSize") }.getOrDefault(defaultSize) private suspend fun createBufferFile(url: String, mimeType: MimeType?): File { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/MangaIndex.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/MangaIndex.kt index 306668f39c..d254730bfa 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/MangaIndex.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/MangaIndex.kt @@ -1,13 +1,6 @@ package io.github.landwarderer.futon.local.data import androidx.annotation.WorkerThread -import okio.FileSystem -import okio.Path -import okio.Path.Companion.toOkioPath -import okio.buffer -import org.jetbrains.annotations.Blocking -import org.json.JSONArray -import org.json.JSONObject import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.core.model.MangaSource import io.github.landwarderer.futon.core.model.isLocal @@ -29,6 +22,13 @@ import io.github.landwarderer.futon.parsers.util.json.mapJSONToSet import io.github.landwarderer.futon.parsers.util.json.toStringSet import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.parsers.util.toTitleCase +import okio.FileSystem +import okio.Path +import okio.Path.Companion.toOkioPath +import okio.buffer +import org.jetbrains.annotations.Blocking +import org.json.JSONArray +import org.json.JSONObject import java.io.File class MangaIndex(source: String?) { @@ -248,7 +248,7 @@ class MangaIndex(source: String?) { null } }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("MangaIndex::read") }.getOrNull() @Blocking diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/index/LocalMangaIndex.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/index/LocalMangaIndex.kt index 5a8fcd6fa0..3ac5de20d7 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/index/LocalMangaIndex.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/index/LocalMangaIndex.kt @@ -4,9 +4,6 @@ import android.content.Context import androidx.core.content.edit import androidx.room.withTransaction import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import io.github.landwarderer.futon.core.db.MangaDatabase import io.github.landwarderer.futon.core.parser.MangaDataRepository import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug @@ -14,6 +11,9 @@ import io.github.landwarderer.futon.local.data.LocalMangaRepository import io.github.landwarderer.futon.local.data.input.LocalMangaParser import io.github.landwarderer.futon.local.domain.model.LocalManga import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import java.io.File import javax.inject.Inject import javax.inject.Provider @@ -69,7 +69,7 @@ class LocalMangaIndex @Inject constructor( return runCatchingCancellable { LocalMangaParser(File(path)).getManga(withDetails) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalMangaIndex::get") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/input/LocalMangaParser.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/input/LocalMangaParser.kt index 52fbbbb661..4cb2a67d87 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/input/LocalMangaParser.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/input/LocalMangaParser.kt @@ -3,18 +3,6 @@ package io.github.landwarderer.futon.local.data.input import android.net.Uri import androidx.core.net.toFile import androidx.core.net.toUri -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.launch -import kotlinx.coroutines.runInterruptible -import okio.FileSystem -import okio.Path -import okio.Path.Companion.toOkioPath -import okio.Path.Companion.toPath -import okio.openZip -import org.jetbrains.annotations.Blocking import io.github.landwarderer.futon.core.model.LocalMangaSource import io.github.landwarderer.futon.core.util.AlphanumComparator import io.github.landwarderer.futon.core.util.MimeTypes @@ -38,6 +26,18 @@ import io.github.landwarderer.futon.parsers.model.MangaPage import io.github.landwarderer.futon.parsers.util.longHashCode import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.parsers.util.toTitleCase +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.launch +import kotlinx.coroutines.runInterruptible +import okio.FileSystem +import okio.Path +import okio.Path.Companion.toOkioPath +import okio.Path.Companion.toPath +import okio.openZip +import org.jetbrains.annotations.Blocking import java.io.File /** @@ -220,7 +220,7 @@ class LocalMangaParser(private val uri: Uri) { findFirstImageUri(rootPath, recursive = true) } }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("LocalMangaParser::FileSystem") }.getOrNull() private fun Path.userFriendlyName(): String = name.substringBeforeLast('.') diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/output/LocalMangaOutput.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/output/LocalMangaOutput.kt index ccab5f945d..87bc0ad2aa 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/data/output/LocalMangaOutput.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/data/output/LocalMangaOutput.kt @@ -1,10 +1,5 @@ package io.github.landwarderer.futon.local.data.output -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import okio.Closeable import io.github.landwarderer.futon.core.prefs.DownloadFormat import io.github.landwarderer.futon.core.util.ext.MimeType import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug @@ -13,6 +8,11 @@ import io.github.landwarderer.futon.local.data.input.LocalMangaParser import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.model.MangaChapter import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext +import okio.Closeable import java.io.File sealed class LocalMangaOutput( @@ -103,7 +103,7 @@ sealed class LocalMangaOutput( val info = runCatchingCancellable { LocalMangaParser(file).getMangaInfo() }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("LocalMangaOutput::canWriteTo") }.getOrNull() ?: return false return info.id == manga.id } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteLocalMangaUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteLocalMangaUseCase.kt index d3c4df8a9b..a7f79429a2 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteLocalMangaUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteLocalMangaUseCase.kt @@ -22,7 +22,7 @@ class DeleteLocalMangaUseCase @Inject constructor( runCatchingCancellable { historyRepository.deleteOrSwap(victim, original) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DeleteLocalMangaUseCase::invoke") } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteReadChaptersUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteReadChaptersUseCase.kt index 671150235a..bbf011f48e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteReadChaptersUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/domain/DeleteReadChaptersUseCase.kt @@ -1,11 +1,5 @@ package io.github.landwarderer.futon.local.domain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.buffer -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.fold -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch import io.github.landwarderer.futon.core.model.ids import io.github.landwarderer.futon.core.model.isLocal import io.github.landwarderer.futon.core.parser.MangaRepository @@ -18,6 +12,12 @@ import io.github.landwarderer.futon.parsers.model.MangaChapter import io.github.landwarderer.futon.parsers.util.findById import io.github.landwarderer.futon.parsers.util.recoverCatchingCancellable import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.fold +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import javax.inject.Inject class DeleteReadChaptersUseCase @Inject constructor( @@ -48,7 +48,7 @@ class DeleteReadChaptersUseCase @Inject constructor( val task = runCatchingCancellable { getDeletionTask(LocalManga(manga)) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DeleteReadChaptersUseCase::invoke") }.getOrNull() if (task != null) { send(task) @@ -60,7 +60,7 @@ class DeleteReadChaptersUseCase @Inject constructor( localMangaRepository.deleteChapters(it.manga.manga, it.chaptersIds) it.chaptersIds.size }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DeleteReadChaptersUseCase::invoke") }.getOrDefault(0) }.fold(0) { acc, x -> acc + x } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/local/ui/ImportService.kt b/app/src/main/kotlin/io/github/landwarderer/futon/local/ui/ImportService.kt index 9daf1a83d8..2c7e29dc1d 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/local/ui/ImportService.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/local/ui/ImportService.kt @@ -15,7 +15,6 @@ import androidx.core.content.ContextCompat import coil3.ImageLoader import coil3.request.ImageRequest import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.runBlocking import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.ErrorReporterReceiver import io.github.landwarderer.futon.core.model.isNsfw @@ -32,6 +31,7 @@ import io.github.landwarderer.futon.core.util.ext.withPartialWakeLock import io.github.landwarderer.futon.local.data.importer.SingleMangaImporter import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.util.runCatchingCancellable +import kotlinx.coroutines.runBlocking import javax.inject.Inject @AndroidEntryPoint @@ -167,7 +167,7 @@ class ImportService : CoroutineIntentService() { } true } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("ImportService::start") false } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/main/domain/CoverRestoreInterceptor.kt b/app/src/main/kotlin/io/github/landwarderer/futon/main/domain/CoverRestoreInterceptor.kt index 1d0375e482..d7d8ea158e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/main/domain/CoverRestoreInterceptor.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/main/domain/CoverRestoreInterceptor.kt @@ -57,7 +57,7 @@ class CoverRestoreInterceptor @Inject constructor( val restored = runCatchingCancellable { restoreMangaImpl(manga) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("CoverRestoreInterceptor::restoreManga") }.getOrDefault(false) if (restored) { blacklist.remove(key) @@ -87,7 +87,7 @@ class CoverRestoreInterceptor @Inject constructor( val restored = runCatchingCancellable { restoreBookmarkImpl(bookmark) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("CoverRestoreInterceptor::restoreBookmark") }.getOrDefault(false) if (restored) { blacklist.remove(key) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt index 475b909230..838f601d66 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt @@ -1,8 +1,6 @@ package io.github.landwarderer.futon.main.ui import android.Manifest -import android.app.BackgroundServiceStartNotAllowedException -import android.app.ServiceStartNotAllowedException import android.content.Intent import android.content.pm.PackageManager.PERMISSION_GRANTED import android.os.Build @@ -34,16 +32,6 @@ import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP import com.google.android.material.search.SearchView import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.trySendBlocking -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.backups.ui.periodical.PeriodicalBackupService import io.github.landwarderer.futon.browser.AdListUpdateService @@ -77,6 +65,16 @@ import io.github.landwarderer.futon.search.ui.suggestion.SearchSuggestionListene import io.github.landwarderer.futon.search.ui.suggestion.SearchSuggestionMenuProvider import io.github.landwarderer.futon.search.ui.suggestion.SearchSuggestionViewModel import io.github.landwarderer.futon.search.ui.suggestion.adapter.SearchSuggestionAdapter +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import com.google.android.material.R as materialR @@ -313,7 +311,7 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav } } } catch (e: IllegalStateException) { - e.printStackTraceDebug() + e.printStackTraceDebug("MainActivity::onFirstStart") } private fun adjustAppbar(topFragment: Fragment) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/DetectReaderModeUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/DetectReaderModeUseCase.kt index 5c1be0b58f..6bfa4424c5 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/DetectReaderModeUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/DetectReaderModeUseCase.kt @@ -4,9 +4,6 @@ import android.graphics.BitmapFactory import android.util.Size import androidx.core.net.toFile import androidx.core.net.toUri -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runInterruptible -import okhttp3.OkHttpClient import io.github.landwarderer.futon.core.network.MangaHttpClient import io.github.landwarderer.futon.core.network.imageproxy.ImageProxyInterceptor import io.github.landwarderer.futon.core.parser.MangaDataRepository @@ -20,6 +17,9 @@ import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.model.MangaPage import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.ui.ReaderState +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runInterruptible +import okhttp3.OkHttpClient import java.io.InputStream import java.util.zip.ZipFile import javax.inject.Inject @@ -50,7 +50,7 @@ class DetectReaderModeUseCase @Inject constructor( }.onSuccess { dataRepository.saveReaderMode(manga, it) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DetectReaderModeUseCase::invoke") }.getOrDefault(defaultMode) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/PageLoader.kt b/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/PageLoader.kt index 0e7338c699..71eaa0c2df 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/PageLoader.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/reader/domain/PageLoader.kt @@ -19,22 +19,6 @@ import coil3.toBitmap import com.davemorrissey.labs.subscaleview.ImageSource import dagger.hilt.android.ActivityRetainedLifecycle import dagger.hilt.android.scopes.ActivityRetainedScoped -import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.plus -import kotlinx.coroutines.runInterruptible -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.sync.withPermit -import okhttp3.OkHttpClient -import okhttp3.Request -import okio.use -import org.jetbrains.annotations.Blocking import io.github.landwarderer.futon.core.LocalizedAppContext import io.github.landwarderer.futon.core.image.BitmapDecoderCompat import io.github.landwarderer.futon.core.network.CommonHeaders @@ -72,6 +56,22 @@ import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.util.requireBody import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.ui.pager.ReaderPage +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.plus +import kotlinx.coroutines.runInterruptible +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.sync.withPermit +import okhttp3.OkHttpClient +import okhttp3.Request +import okio.use +import org.jetbrains.annotations.Blocking import java.io.File import java.util.LinkedList import java.util.concurrent.atomic.AtomicInteger @@ -219,7 +219,7 @@ class PageLoader @Inject constructor( suspend fun getTrimmedBounds(uri: Uri): Rect? = runCatchingCancellable { edgeDetector.getBounds(ImageSource.uri(uri)) }.onFailure { error -> - error.printStackTraceDebug() + error.printStackTraceDebug("PageLoader::getTrimmedBounds") }.getOrNull() suspend fun getPageUrl(page: MangaPage): String { @@ -333,7 +333,7 @@ class PageLoader @Inject constructor( CoroutineExceptionHandler { override fun handleException(context: CoroutineContext, exception: Throwable) { - exception.printStackTraceDebug() + exception.printStackTraceDebug("PageLoader::handleException") } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/ReaderInfoBarView.kt b/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/ReaderInfoBarView.kt index 8a683cb26b..ea3719bc15 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/ReaderInfoBarView.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/ReaderInfoBarView.kt @@ -342,6 +342,6 @@ class ReaderInfoBarView @JvmOverloads constructor( val resId = resources.getIdentifier(name, "dimen", "com.android.systemui") resources.getDimensionPixelOffset(resId) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ReaderInfoBarView::getSystemUiDimensionOffset") }.getOrDefault(fallback) } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/pager/vm/PageViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/pager/vm/PageViewModel.kt index bd9523539b..a45152f309 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/pager/vm/PageViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/reader/ui/pager/vm/PageViewModel.kt @@ -5,6 +5,13 @@ import android.net.Uri import androidx.annotation.WorkerThread import com.davemorrissey.labs.subscaleview.DefaultOnImageEventListener import com.davemorrissey.labs.subscaleview.ImageSource +import io.github.landwarderer.futon.core.exceptions.resolve.ExceptionResolver +import io.github.landwarderer.futon.core.os.NetworkState +import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug +import io.github.landwarderer.futon.core.util.ext.throttle +import io.github.landwarderer.futon.parsers.model.MangaPage +import io.github.landwarderer.futon.reader.domain.PageLoader +import io.github.landwarderer.futon.reader.ui.config.ReaderSettings import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -20,13 +27,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.plus import kotlinx.coroutines.withContext import okio.IOException -import io.github.landwarderer.futon.core.exceptions.resolve.ExceptionResolver -import io.github.landwarderer.futon.core.os.NetworkState -import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug -import io.github.landwarderer.futon.core.util.ext.throttle -import io.github.landwarderer.futon.parsers.model.MangaPage -import io.github.landwarderer.futon.reader.domain.PageLoader -import io.github.landwarderer.futon.reader.ui.config.ReaderSettings class PageViewModel( private val loader: PageLoader, @@ -90,7 +90,7 @@ class PageViewModel( } override fun onImageLoadError(e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("PageViewModel::onImageLoadError") state.update { currentState -> if (currentState is PageState.Loaded) { @@ -154,7 +154,7 @@ class PageViewModel( } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("PageViewModel::doLoad") state.value = PageState.Error(e) if (e is IOException && !networkState.value) { networkState.awaitForConnection() diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/remotelist/ui/RemoteListViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/remotelist/ui/RemoteListViewModel.kt index 64533354f9..d9d9d25fed 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/remotelist/ui/RemoteListViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/remotelist/ui/RemoteListViewModel.kt @@ -3,21 +3,6 @@ package io.github.landwarderer.futon.remotelist.ui import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.plus import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.model.MangaSource import io.github.landwarderer.futon.core.model.distinctById @@ -46,6 +31,21 @@ import io.github.landwarderer.futon.local.domain.model.LocalManga import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.model.MangaParserSource import io.github.landwarderer.futon.parsers.util.sizeOrZero +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.plus import javax.inject.Inject private const val FILTER_MIN_INTERVAL = 250L @@ -166,7 +166,7 @@ open class RemoteListViewModel @Inject constructor( } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("RemoteListViewModel::loadList") listError.value = e if (!mangaList.value.isNullOrEmpty()) { errorEvent.call(e) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/AniListAuthenticator.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/AniListAuthenticator.kt index 1bf9e0143c..fd725acee3 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/AniListAuthenticator.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/AniListAuthenticator.kt @@ -1,15 +1,15 @@ package io.github.landwarderer.futon.scrobbling.anilist.data -import kotlinx.coroutines.runBlocking -import okhttp3.Authenticator -import okhttp3.Request -import okhttp3.Response -import okhttp3.Route import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.scrobbling.common.data.ScrobblerStorage import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerService import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerType +import kotlinx.coroutines.runBlocking +import okhttp3.Authenticator +import okhttp3.Request +import okhttp3.Response +import okhttp3.Route import javax.inject.Inject import javax.inject.Provider @@ -49,6 +49,6 @@ class AniListAuthenticator @Inject constructor( runBlocking { repository.authorize(null) } return storage.accessToken }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("AniListAuthenticator::refreshAccessToken") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/ScoreFormat.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/ScoreFormat.kt index 2b2cac8c51..0e56214f7b 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/ScoreFormat.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/anilist/data/ScoreFormat.kt @@ -20,7 +20,7 @@ enum class ScoreFormat { fun of(rawValue: String?): ScoreFormat { rawValue ?: return POINT_10_DECIMAL return runCatching { valueOf(rawValue) } - .onFailure { it.printStackTraceDebug() } + .onFailure { it.printStackTraceDebug("ScoreFormat::of") } .getOrDefault(POINT_10_DECIMAL) } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/domain/Scrobbler.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/domain/Scrobbler.kt index c887aa9979..3113cef237 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/domain/Scrobbler.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/domain/Scrobbler.kt @@ -4,12 +4,6 @@ import androidx.annotation.FloatRange import androidx.collection.LongSparseArray import androidx.collection.getOrElse import androidx.core.text.parseAsHtml -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.map import io.github.landwarderer.futon.core.db.MangaDatabase import io.github.landwarderer.futon.core.parser.MangaRepository import io.github.landwarderer.futon.core.util.ext.findKeyByValue @@ -26,6 +20,12 @@ import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerServ import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerUser import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblingInfo import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblingStatus +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map import java.util.EnumMap abstract class Scrobbler( @@ -47,7 +47,7 @@ abstract class Scrobbler( }.onSuccess { emit(it) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("Scrobbler::user") } } @@ -133,7 +133,7 @@ abstract class Scrobbler( runCatchingCancellable { getMangaInfo(targetId) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("Scrobbler::toScrobblingInfo") }.onSuccess { infoCache.put(targetId, it) }.getOrNull() ?: return null @@ -158,6 +158,6 @@ suspend fun Scrobbler.tryScrobble(manga: Manga, chapterId: Long): Boolean { return runCatchingCancellable { scrobble(manga, chapterId) }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("Scrobbler::tryScrobble") }.isSuccess } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/ui/selector/ScrobblingSelectorViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/ui/selector/ScrobblingSelectorViewModel.kt index fb2aa4125a..dbdcb5fe03 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/ui/selector/ScrobblingSelectorViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/common/ui/selector/ScrobblingSelectorViewModel.kt @@ -4,14 +4,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView.NO_ID import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.plus import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.exceptions.resolve.ExceptionResolver import io.github.landwarderer.futon.core.model.parcelable.ParcelableManga @@ -33,6 +25,14 @@ import io.github.landwarderer.futon.scrobbling.common.domain.Scrobbler import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerManga import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblingStatus import io.github.landwarderer.futon.scrobbling.common.ui.selector.model.ScrobblerHint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.plus import javax.inject.Inject import javax.inject.Provider @@ -138,7 +138,7 @@ class ScrobblingSelectorViewModel @Inject constructor( scrobblerMangaList.value = newList hasNextPage.value = changed && newList.isNotEmpty() }.onFailure { error -> - error.printStackTraceDebug() + error.printStackTraceDebug("ScrobblingSelectorViewModel::loadList") hasNextPage.value = false listError.value = error } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/discord/ui/DiscordRpc.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/discord/ui/DiscordRpc.kt index f3274785aa..a9ce76b91c 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/discord/ui/DiscordRpc.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/discord/ui/DiscordRpc.kt @@ -12,13 +12,6 @@ import com.my.kizzyrpc.entities.presence.Timestamps import dagger.hilt.android.ViewModelLifecycle import dagger.hilt.android.lifecycle.RetainedLifecycle import dagger.hilt.android.scopes.ViewModelScoped -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.plus -import okio.utf8Size import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.LocalizedAppContext import io.github.landwarderer.futon.core.model.appUrl @@ -31,6 +24,13 @@ import io.github.landwarderer.futon.parsers.model.Manga import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.ui.pager.ReaderUiState import io.github.landwarderer.futon.scrobbling.discord.data.DiscordRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.plus +import okio.utf8Size import java.util.Collections import javax.inject.Inject @@ -156,7 +156,7 @@ class DiscordRpc @Inject constructor( }.onSuccess { url -> mpCache[this] = url }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("DiscordRpc::toMediaProxyUrl") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/kitsu/data/KitsuAuthenticator.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/kitsu/data/KitsuAuthenticator.kt index 89db1fb4a8..e9527aa8fc 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/kitsu/data/KitsuAuthenticator.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/kitsu/data/KitsuAuthenticator.kt @@ -1,15 +1,15 @@ package io.github.landwarderer.futon.scrobbling.kitsu.data -import kotlinx.coroutines.runBlocking -import okhttp3.Authenticator -import okhttp3.Request -import okhttp3.Response -import okhttp3.Route import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.scrobbling.common.data.ScrobblerStorage import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerService import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerType +import kotlinx.coroutines.runBlocking +import okhttp3.Authenticator +import okhttp3.Request +import okhttp3.Response +import okhttp3.Route import javax.inject.Inject import javax.inject.Provider @@ -49,7 +49,7 @@ class KitsuAuthenticator @Inject constructor( runBlocking { repository.authorize(null) } return storage.accessToken }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("KitsuAuthenticator::refreshAccessToken") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/mal/data/MALAuthenticator.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/mal/data/MALAuthenticator.kt index 135820b0d0..249d3e51fb 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/mal/data/MALAuthenticator.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/mal/data/MALAuthenticator.kt @@ -1,15 +1,15 @@ package io.github.landwarderer.futon.scrobbling.mal.data -import kotlinx.coroutines.runBlocking -import okhttp3.Authenticator -import okhttp3.Request -import okhttp3.Response -import okhttp3.Route import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.scrobbling.common.data.ScrobblerStorage import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerService import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerType +import kotlinx.coroutines.runBlocking +import okhttp3.Authenticator +import okhttp3.Request +import okhttp3.Response +import okhttp3.Route import javax.inject.Inject import javax.inject.Provider @@ -49,7 +49,7 @@ class MALAuthenticator @Inject constructor( runBlocking { repository.authorize(null) } return storage.accessToken }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("MALAuthenticator::refreshAccessToken") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/shikimori/data/ShikimoriAuthenticator.kt b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/shikimori/data/ShikimoriAuthenticator.kt index 3ee731288c..64eb363d81 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/shikimori/data/ShikimoriAuthenticator.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/scrobbling/shikimori/data/ShikimoriAuthenticator.kt @@ -1,15 +1,15 @@ package io.github.landwarderer.futon.scrobbling.shikimori.data -import kotlinx.coroutines.runBlocking -import okhttp3.Authenticator -import okhttp3.Request -import okhttp3.Response -import okhttp3.Route import io.github.landwarderer.futon.core.network.CommonHeaders import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.scrobbling.common.data.ScrobblerStorage import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerService import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerType +import kotlinx.coroutines.runBlocking +import okhttp3.Authenticator +import okhttp3.Request +import okhttp3.Response +import okhttp3.Route import javax.inject.Inject import javax.inject.Provider @@ -49,6 +49,6 @@ class ShikimoriAuthenticator @Inject constructor( runBlocking { repository.authorize(null) } return storage.accessToken }.onFailure { - it.printStackTraceDebug() + it.printStackTraceDebug("ShikimoriAuthenticator::refreshAccessToken") }.getOrNull() } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/search/domain/SearchV2Helper.kt b/app/src/main/kotlin/io/github/landwarderer/futon/search/domain/SearchV2Helper.kt index 04e6d895bc..3677f421ce 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/search/domain/SearchV2Helper.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/search/domain/SearchV2Helper.kt @@ -63,7 +63,7 @@ class SearchV2Helper @AssistedInject constructor( val tags = this@SearchV2Helper.dataRepository.findTags(this.source) + runCatchingCancellable { this@getFilter.getFilterOptions().availableTags }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchV2Helper::MangaRepository") }.getOrDefault(emptySet()) val tag = tags.find { x -> x.title.equals(query, ignoreCase = true) } if (tag != null) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/multi/SearchViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/multi/SearchViewModel.kt index fe1a64d277..4bcf268c4f 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/multi/SearchViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/multi/SearchViewModel.kt @@ -5,20 +5,6 @@ import androidx.collection.LongSet import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.dropWhile -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.joinAll -import kotlinx.coroutines.launch -import kotlinx.coroutines.plus -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.model.LocalMangaSource import io.github.landwarderer.futon.core.model.UnknownMangaSource @@ -43,6 +29,20 @@ import io.github.landwarderer.futon.parsers.model.MangaSource import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.search.domain.SearchKind import io.github.landwarderer.futon.search.domain.SearchV2Helper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.dropWhile +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.joinAll +import kotlinx.coroutines.launch +import kotlinx.coroutines.plus +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withPermit import java.util.Locale import javax.inject.Inject @@ -206,7 +206,7 @@ class SearchViewModel @Inject constructor( } }, onFailure = { error -> - error.printStackTraceDebug() + error.printStackTraceDebug("SearchViewModel::searchSource", source.toString()) if (source is MangaParserSource && source.isBroken) { null } else { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/suggestion/SearchSuggestionViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/suggestion/SearchSuggestionViewModel.kt index b9847f15b1..3748f27104 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/suggestion/SearchSuggestionViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/search/ui/suggestion/SearchSuggestionViewModel.kt @@ -2,18 +2,6 @@ package io.github.landwarderer.futon.search.ui.suggestion import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.plus import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.prefs.SearchSuggestionType import io.github.landwarderer.futon.core.prefs.observeAsFlow @@ -28,6 +16,18 @@ import io.github.landwarderer.futon.parsers.util.mapToSet import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.search.domain.MangaSearchRepository import io.github.landwarderer.futon.search.ui.suggestion.model.SearchSuggestionItem +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.plus import javax.inject.Inject private const val DEBOUNCE_TIMEOUT = 300L @@ -150,7 +150,7 @@ class SearchSuggestionViewModel @Inject constructor( repository.getAuthorsSuggestion(searchQuery, MAX_AUTHORS_ITEMS) .map { SearchSuggestionItem.Author(it) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getAuthors") listOf(SearchSuggestionItem.Text(0, e)) } @@ -158,7 +158,7 @@ class SearchSuggestionViewModel @Inject constructor( repository.getQueryHintSuggestion(searchQuery, MAX_HINTS_ITEMS) .map { SearchSuggestionItem.Hint(it) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getQueryHints") listOf(SearchSuggestionItem.Text(0, e)) } @@ -166,7 +166,7 @@ class SearchSuggestionViewModel @Inject constructor( repository.getQuerySuggestion(searchQuery, MAX_QUERY_ITEMS) .map { SearchSuggestionItem.RecentQuery(it) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getRecentQueries") listOf(SearchSuggestionItem.Text(0, e)) } @@ -178,7 +178,7 @@ class SearchSuggestionViewModel @Inject constructor( listOf(SearchSuggestionItem.Tags(mapTags(tags))) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getTags") listOf(SearchSuggestionItem.Text(0, e)) } @@ -190,7 +190,7 @@ class SearchSuggestionViewModel @Inject constructor( listOf(SearchSuggestionItem.MangaList(manga)) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getManga") listOf(SearchSuggestionItem.Text(0, e)) } @@ -199,7 +199,7 @@ class SearchSuggestionViewModel @Inject constructor( repository.getSourcesSuggestion(searchQuery, MAX_SOURCES_ITEMS) .map { SearchSuggestionItem.Source(it, it.name in enabledSources) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getSources") listOf(SearchSuggestionItem.Text(0, e)) } @@ -208,7 +208,7 @@ class SearchSuggestionViewModel @Inject constructor( repository.getSourcesSuggestion(MAX_SOURCES_TIPS_ITEMS) .map { SearchSuggestionItem.SourceTip(it) } }.getOrElse { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("SearchSuggestionViewModel::getRecentSources") listOf(SearchSuggestionItem.Text(0, e)) } } else { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/DownloadsSettingsFragment.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/DownloadsSettingsFragment.kt index 217e0ca84b..2e163926f7 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/DownloadsSettingsFragment.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/DownloadsSettingsFragment.kt @@ -10,9 +10,6 @@ import androidx.preference.ListPreference import androidx.preference.Preference import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.nav.router import io.github.landwarderer.futon.core.os.OpenDocumentTreeHelper @@ -30,6 +27,9 @@ import io.github.landwarderer.futon.download.ui.worker.DownloadWorker import io.github.landwarderer.futon.local.data.LocalStorageManager import io.github.landwarderer.futon.parsers.util.names import io.github.landwarderer.futon.settings.utils.DozeHelper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @AndroidEntryPoint @@ -174,7 +174,7 @@ class DownloadsSettingsFragment : downloadsScheduler.updateConstraints(option) } } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("DownloadsSettingsFragment::updateDownloadsConstraints") } finally { preference?.isEnabled = true } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/ProxySettingsFragment.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/ProxySettingsFragment.kt index e8a26295ea..b6dd77c14a 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/ProxySettingsFragment.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/ProxySettingsFragment.kt @@ -9,12 +9,6 @@ import androidx.preference.Preference import androidx.preference.PreferenceCategory import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.Request import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.network.BaseHttpClient import io.github.landwarderer.futon.core.prefs.AppSettings @@ -27,6 +21,12 @@ import io.github.landwarderer.futon.settings.utils.EditTextBindListener import io.github.landwarderer.futon.settings.utils.PasswordSummaryProvider import io.github.landwarderer.futon.settings.utils.validation.DomainValidator import io.github.landwarderer.futon.settings.utils.validation.PortNumberValidator +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request import java.net.Proxy import javax.inject.Inject import kotlin.coroutines.cancellation.CancellationException @@ -130,7 +130,7 @@ class ProxySettingsFragment : BasePreferenceFragment(R.string.proxy), } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("ProxySettingsFragment::testConnection") showTestResult(e) } finally { pref?.run { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/ServicesSettingsFragment.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/ServicesSettingsFragment.kt index 134cbba947..bd8e7fe92f 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/ServicesSettingsFragment.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/ServicesSettingsFragment.kt @@ -7,9 +7,6 @@ import android.view.View import androidx.preference.Preference import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.nav.router import io.github.landwarderer.futon.core.prefs.AppSettings @@ -22,6 +19,9 @@ import io.github.landwarderer.futon.scrobbling.common.domain.model.ScrobblerServ import io.github.landwarderer.futon.scrobbling.common.ui.ScrobblerAuthHelper import io.github.landwarderer.futon.settings.utils.SplitSwitchPreference import io.github.landwarderer.futon.sync.domain.SyncController +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @AndroidEntryPoint @@ -133,7 +133,7 @@ class ServicesSettingsFragment : BasePreferenceFragment(R.string.services), val user = scrobblerAuthHelper.getUser(scrobblerService) getString(R.string.logged_in_as, user.nickname) }.getOrElse { - it.printStackTraceDebug() + it.printStackTraceDebug("ServicesSettingsFragment::bindScrobblerSummary") it.getDisplayMessage(resources) } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/utils/ActivityListPreference.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/utils/ActivityListPreference.kt index d06a3fa0bc..6869c65641 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/utils/ActivityListPreference.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/utils/ActivityListPreference.kt @@ -32,7 +32,7 @@ class ActivityListPreference : ListPreference { try { context.startActivity(intent) } catch (e: ActivityNotFoundException) { - e.printStackTraceDebug() + e.printStackTraceDebug("ActivityListPreference::onClick") super.onClick() } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/stats/domain/StatsCollector.kt b/app/src/main/kotlin/io/github/landwarderer/futon/stats/domain/StatsCollector.kt index 10d31f9919..ce75e8b172 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/stats/domain/StatsCollector.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/stats/domain/StatsCollector.kt @@ -4,8 +4,6 @@ import androidx.collection.LongSparseArray import androidx.collection.set import dagger.hilt.android.ViewModelLifecycle import dagger.hilt.android.scopes.ViewModelScoped -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import io.github.landwarderer.futon.core.db.MangaDatabase import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.util.RetainedLifecycleCoroutineScope @@ -13,6 +11,8 @@ import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import io.github.landwarderer.futon.parsers.util.runCatchingCancellable import io.github.landwarderer.futon.reader.ui.ReaderState import io.github.landwarderer.futon.stats.data.StatsEntity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import javax.inject.Inject @ViewModelScoped @@ -67,7 +67,7 @@ class StatsCollector @Inject constructor( runCatchingCancellable { db.getStatsDao().upsert(entity) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("StatsCollector::commit") } } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt b/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt index 40e80bead0..331ce0b9d6 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt @@ -36,14 +36,6 @@ import coil3.request.ImageRequest import dagger.Reusable import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.exceptions.CloudFlareException import io.github.landwarderer.futon.core.exceptions.resolve.CaptchaHandler @@ -82,6 +74,14 @@ import io.github.landwarderer.futon.settings.work.PeriodicWorkScheduler import io.github.landwarderer.futon.suggestions.domain.MangaSuggestion import io.github.landwarderer.futon.suggestions.domain.SuggestionRepository import io.github.landwarderer.futon.suggestions.domain.TagsBlacklist +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withPermit import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.pow @@ -239,7 +239,7 @@ class SuggestionsWorker @AssistedInject constructor( } catch (e: CancellationException) { throw e } catch (e: Exception) { - e.printStackTraceDebug() + e.printStackTraceDebug("SuggestionsWorker::doWorkImpl") } } } @@ -287,7 +287,7 @@ class SuggestionsWorker @AssistedInject constructor( if (e is CloudFlareException) { captchaHandler.handle(e) } - e.printStackTraceDebug() + e.printStackTraceDebug("SuggestionsWorker::getList") }.getOrDefault(emptyList()) @RequiresPermission(Manifest.permission.POST_NOTIFICATIONS) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/sync/domain/SyncHelper.kt b/app/src/main/kotlin/io/github/landwarderer/futon/sync/domain/SyncHelper.kt index 58c1cbf5b7..43636a111e 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/sync/domain/SyncHelper.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/sync/domain/SyncHelper.kt @@ -16,14 +16,6 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.Response -import okio.IOException -import org.jetbrains.annotations.Blocking import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.db.TABLE_FAVOURITES @@ -47,6 +39,14 @@ import io.github.landwarderer.futon.sync.data.model.HistorySyncDto import io.github.landwarderer.futon.sync.data.model.MangaSyncDto import io.github.landwarderer.futon.sync.data.model.MangaTagSyncDto import io.github.landwarderer.futon.sync.data.model.SyncDto +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response +import okio.IOException +import org.jetbrains.annotations.Blocking import java.net.HttpURLConnection import java.util.concurrent.TimeUnit @@ -126,7 +126,7 @@ class SyncHelper @AssistedInject constructor( } fun onError(e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("SyncHelper::onError") } fun onSyncComplete(result: SyncResult) { diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/tracker/domain/CheckNewChaptersUseCase.kt b/app/src/main/kotlin/io/github/landwarderer/futon/tracker/domain/CheckNewChaptersUseCase.kt index 9759cf51d2..447afcf050 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/tracker/domain/CheckNewChaptersUseCase.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/tracker/domain/CheckNewChaptersUseCase.kt @@ -68,7 +68,7 @@ class CheckNewChaptersUseCase @Inject constructor( ) repository.mergeWith(tracking) }.onFailure { e -> - e.printStackTraceDebug() + e.printStackTraceDebug("CheckNewChaptersUseCase::invoke") }.isSuccess } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/tracker/work/TrackWorker.kt b/app/src/main/kotlin/io/github/landwarderer/futon/tracker/work/TrackWorker.kt index 446ab89254..23793982e3 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/tracker/work/TrackWorker.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/tracker/work/TrackWorker.kt @@ -29,17 +29,6 @@ import dagger.Lazy import dagger.Reusable import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit -import kotlinx.coroutines.withContext import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.db.MangaDatabase @@ -66,6 +55,17 @@ import io.github.landwarderer.futon.tracker.domain.GetTracksUseCase import io.github.landwarderer.futon.tracker.domain.model.MangaTracking import io.github.landwarderer.futon.tracker.domain.model.MangaUpdates import io.github.landwarderer.futon.tracker.work.TrackerNotificationHelper.NotificationInfo +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Semaphore +import kotlinx.coroutines.sync.withPermit +import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Provider @@ -96,7 +96,7 @@ class TrackWorker @AssistedInject constructor( } catch (e: CancellationException) { throw e } catch (e: Throwable) { - e.printStackTraceDebug() + e.printStackTraceDebug("TrackWorker::doWork") Result.failure() } finally { withContext(NonCancellable) { diff --git a/app/src/nightly/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt b/app/src/nightly/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt index 1311b75ac5..83a1a117af 100644 --- a/app/src/nightly/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt +++ b/app/src/nightly/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt @@ -5,4 +5,8 @@ package io.github.landwarderer.futon.core.util.ext @Suppress("NOTHING_TO_INLINE") inline fun Throwable.printStackTraceDebug() = Unit +fun Throwable.printStackTraceDebug(tag: String) = Unit + +fun Throwable.printStackTraceDebug(tag: String, source: String) = Unit + fun assertNotInMainThread() = Unit diff --git a/app/src/release/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt b/app/src/release/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt index 1311b75ac5..467698b50f 100644 --- a/app/src/release/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt +++ b/app/src/release/kotlin/io/github/landwarderer/futon/core/util/ext/Debug.kt @@ -5,4 +5,7 @@ package io.github.landwarderer.futon.core.util.ext @Suppress("NOTHING_TO_INLINE") inline fun Throwable.printStackTraceDebug() = Unit +fun Throwable.printStackTraceDebug(tag: String) = Unit + +fun Throwable.printStackTraceDebug(tag: String, source: String) = Unit fun assertNotInMainThread() = Unit diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed4a160a84..b0a0d4ad01 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -107,9 +107,10 @@ lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", v markwon = { module = "io.noties.markwon:core", version.ref = "markwon" } material = { module = "com.google.android.material:material", version.ref = "material" } moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } -okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } -okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" } -okhttp-tls = { module = "com.squareup.okhttp3:okhttp-tls", version.ref = "okhttp" } +okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp" } +okhttp = { module = "com.squareup.okhttp3:okhttp" } +okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps" } +okhttp-tls = { module = "com.squareup.okhttp3:okhttp-tls" } okio = { module = "com.squareup.okio:okio", version.ref = "okio" } ssiv = { module = "com.github.AppFuton:subsampling-scale-image-view", version.ref = "ssiv" } workinspector = { module = "com.github.Koitharu:WorkInspector", version.ref = "workinspector" }