2016-03-19 17:48:55 +01:00
|
|
|
package eu.kanade.tachiyomi
|
|
|
|
|
|
2022-04-15 19:43:54 +02:00
|
|
|
import android.annotation.SuppressLint
|
2021-04-28 14:32:00 +02:00
|
|
|
import android.app.ActivityManager
|
2016-03-19 17:48:55 +01:00
|
|
|
import android.app.Application
|
2021-05-01 04:36:54 +02:00
|
|
|
import android.app.PendingIntent
|
|
|
|
|
import android.content.BroadcastReceiver
|
2016-10-15 11:12:16 +02:00
|
|
|
import android.content.Context
|
2021-05-01 04:36:54 +02:00
|
|
|
import android.content.Intent
|
|
|
|
|
import android.content.IntentFilter
|
2019-08-07 21:47:43 +02:00
|
|
|
import android.os.Build
|
2019-04-14 05:47:57 +02:00
|
|
|
import android.os.Environment
|
2022-04-15 00:15:47 +02:00
|
|
|
import android.os.Looper
|
2021-05-29 04:34:26 +02:00
|
|
|
import android.webkit.WebView
|
2021-04-28 14:32:00 +02:00
|
|
|
import androidx.core.content.getSystemService
|
2021-09-20 20:33:35 +02:00
|
|
|
import androidx.lifecycle.DefaultLifecycleObserver
|
|
|
|
|
import androidx.lifecycle.LifecycleOwner
|
2020-05-04 00:34:46 +02:00
|
|
|
import androidx.lifecycle.ProcessLifecycleOwner
|
2021-05-01 04:36:54 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2021-04-28 14:32:00 +02:00
|
|
|
import coil.ImageLoader
|
|
|
|
|
import coil.ImageLoaderFactory
|
|
|
|
|
import coil.decode.GifDecoder
|
|
|
|
|
import coil.decode.ImageDecoderDecoder
|
2022-03-04 22:04:32 +01:00
|
|
|
import coil.disk.DiskCache
|
2021-10-08 04:12:55 +02:00
|
|
|
import coil.util.DebugLogger
|
2019-04-14 05:47:57 +02:00
|
|
|
import com.elvishew.xlog.LogConfiguration
|
|
|
|
|
import com.elvishew.xlog.LogLevel
|
|
|
|
|
import com.elvishew.xlog.XLog
|
|
|
|
|
import com.elvishew.xlog.printer.AndroidPrinter
|
|
|
|
|
import com.elvishew.xlog.printer.Printer
|
2019-04-14 19:57:14 +02:00
|
|
|
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy
|
2019-04-14 05:47:57 +02:00
|
|
|
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
|
|
|
|
|
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
|
2020-08-24 03:57:06 +02:00
|
|
|
import com.google.firebase.analytics.ktx.analytics
|
|
|
|
|
import com.google.firebase.ktx.Firebase
|
2022-04-23 01:40:09 +02:00
|
|
|
import eu.kanade.domain.DomainModule
|
2022-06-16 18:04:27 +02:00
|
|
|
import eu.kanade.domain.SYDomainModule
|
2022-09-25 16:07:06 +02:00
|
|
|
import eu.kanade.domain.base.BasePreferences
|
2022-10-19 18:57:05 +02:00
|
|
|
import eu.kanade.domain.ui.UiPreferences
|
|
|
|
|
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
|
2022-10-16 22:35:20 +02:00
|
|
|
import eu.kanade.tachiyomi.crash.CrashActivity
|
|
|
|
|
import eu.kanade.tachiyomi.crash.GlobalExceptionHandler
|
2022-06-18 04:21:29 +02:00
|
|
|
import eu.kanade.tachiyomi.data.coil.DomainMangaKeyer
|
2021-04-28 14:32:00 +02:00
|
|
|
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
|
2022-03-04 22:04:32 +01:00
|
|
|
import eu.kanade.tachiyomi.data.coil.MangaCoverKeyer
|
2022-06-18 04:21:29 +02:00
|
|
|
import eu.kanade.tachiyomi.data.coil.MangaKeyer
|
2022-07-16 22:44:55 +02:00
|
|
|
import eu.kanade.tachiyomi.data.coil.PagePreviewFetcher
|
|
|
|
|
import eu.kanade.tachiyomi.data.coil.PagePreviewKeyer
|
2021-07-10 21:44:34 +02:00
|
|
|
import eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder
|
2017-10-10 14:15:41 +02:00
|
|
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
2021-04-28 14:32:00 +02:00
|
|
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
2022-09-17 17:48:24 +02:00
|
|
|
import eu.kanade.tachiyomi.network.NetworkPreferences
|
2022-04-02 15:54:21 +02:00
|
|
|
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
|
2022-04-02 16:49:42 +02:00
|
|
|
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
2021-08-27 14:44:09 +02:00
|
|
|
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
2022-10-22 21:47:09 +02:00
|
|
|
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
2021-05-01 04:36:54 +02:00
|
|
|
import eu.kanade.tachiyomi.util.system.notification
|
2023-02-18 23:10:45 +01:00
|
|
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
2019-04-14 05:47:57 +02:00
|
|
|
import exh.log.CrashlyticsPrinter
|
2019-04-14 16:46:06 +02:00
|
|
|
import exh.log.EHLogLevel
|
2020-11-11 23:28:09 +01:00
|
|
|
import exh.log.EnhancedFilePrinter
|
2021-10-08 04:12:55 +02:00
|
|
|
import exh.log.XLogLogcatLogger
|
2021-03-07 06:23:23 +01:00
|
|
|
import exh.log.xLogD
|
2020-08-22 02:26:56 +02:00
|
|
|
import exh.syDebugVersion
|
2022-11-19 04:57:54 +01:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
2021-05-01 04:36:54 +02:00
|
|
|
import kotlinx.coroutines.flow.launchIn
|
|
|
|
|
import kotlinx.coroutines.flow.onEach
|
2021-11-13 23:43:40 +01:00
|
|
|
import logcat.LogPriority
|
2021-10-08 04:12:55 +02:00
|
|
|
import logcat.LogcatLogger
|
2020-06-07 21:47:42 +02:00
|
|
|
import org.conscrypt.Conscrypt
|
2023-01-28 04:31:12 +01:00
|
|
|
import tachiyomi.core.util.system.logcat
|
2023-01-26 23:53:24 +01:00
|
|
|
import tachiyomi.presentation.widget.TachiyomiWidgetManager
|
2016-06-14 15:13:48 +02:00
|
|
|
import uy.kohesive.injekt.Injekt
|
2021-04-28 14:32:00 +02:00
|
|
|
import uy.kohesive.injekt.api.get
|
2020-02-22 04:58:19 +01:00
|
|
|
import uy.kohesive.injekt.injectLazy
|
2020-09-14 00:48:20 +02:00
|
|
|
import java.io.File
|
|
|
|
|
import java.security.Security
|
2020-11-11 23:28:09 +01:00
|
|
|
import java.text.SimpleDateFormat
|
|
|
|
|
import java.util.Locale
|
2021-12-25 18:05:06 +01:00
|
|
|
import kotlin.time.Duration.Companion.days
|
2016-03-19 17:48:55 +01:00
|
|
|
|
2022-05-15 23:03:57 +02:00
|
|
|
class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
|
2016-03-19 17:48:55 +01:00
|
|
|
|
2022-09-25 16:07:06 +02:00
|
|
|
private val basePreferences: BasePreferences by injectLazy()
|
2022-09-17 17:48:24 +02:00
|
|
|
private val networkPreferences: NetworkPreferences by injectLazy()
|
2021-01-17 17:09:29 +01:00
|
|
|
|
2021-05-01 04:36:54 +02:00
|
|
|
private val disableIncognitoReceiver = DisableIncognitoReceiver()
|
|
|
|
|
|
2022-04-15 19:43:54 +02:00
|
|
|
@SuppressLint("LaunchActivityFromNotification")
|
2016-03-19 17:48:55 +01:00
|
|
|
override fun onCreate() {
|
2021-09-20 20:33:35 +02:00
|
|
|
super<Application>.onCreate()
|
2021-03-07 06:23:23 +01:00
|
|
|
// if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
|
2019-04-14 18:48:59 +02:00
|
|
|
setupExhLogging() // EXH logging
|
2021-10-08 04:12:55 +02:00
|
|
|
LogcatLogger.install(XLogLogcatLogger()) // SY Redirect Logcat to XLog
|
2020-08-24 03:57:06 +02:00
|
|
|
if (!BuildConfig.DEBUG) addAnalytics()
|
2018-01-09 12:27:45 +01:00
|
|
|
|
2022-10-16 22:35:20 +02:00
|
|
|
GlobalExceptionHandler.initialize(applicationContext, CrashActivity::class.java)
|
|
|
|
|
|
2020-07-04 16:27:57 +02:00
|
|
|
// TLS 1.3 support for Android < 10
|
2020-06-07 21:47:42 +02:00
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
|
|
|
|
Security.insertProviderAt(Conscrypt.newProvider(), 1)
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-29 04:34:26 +02:00
|
|
|
// Avoid potential crashes
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
|
|
|
val process = getProcessName()
|
|
|
|
|
if (packageName != process) WebView.setDataDirectorySuffix(process)
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-14 15:13:48 +02:00
|
|
|
Injekt.importModule(AppModule(this))
|
2022-09-17 17:48:24 +02:00
|
|
|
Injekt.importModule(PreferenceModule(this))
|
2022-04-23 01:40:09 +02:00
|
|
|
Injekt.importModule(DomainModule())
|
2022-06-16 18:04:27 +02:00
|
|
|
// SY -->
|
2022-09-17 17:48:24 +02:00
|
|
|
Injekt.importModule(SYPreferenceModule(this))
|
2022-06-16 18:04:27 +02:00
|
|
|
Injekt.importModule(SYDomainModule())
|
|
|
|
|
// SY <--
|
2016-06-15 17:58:28 +02:00
|
|
|
|
2017-10-10 14:15:41 +02:00
|
|
|
setupNotificationChannels()
|
2016-12-13 20:47:46 +01:00
|
|
|
|
2020-02-22 04:58:19 +01:00
|
|
|
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
|
2021-04-25 16:57:14 +02:00
|
|
|
|
2021-05-01 04:36:54 +02:00
|
|
|
// Show notification to disable Incognito Mode when it's enabled
|
2022-09-25 16:07:06 +02:00
|
|
|
basePreferences.incognitoMode().changes()
|
2021-05-01 04:36:54 +02:00
|
|
|
.onEach { enabled ->
|
|
|
|
|
if (enabled) {
|
|
|
|
|
disableIncognitoReceiver.register()
|
|
|
|
|
val notification = notification(Notifications.CHANNEL_INCOGNITO_MODE) {
|
|
|
|
|
setContentTitle(getString(R.string.pref_incognito_mode))
|
|
|
|
|
setContentText(getString(R.string.notification_incognito_text))
|
2021-06-09 23:16:09 +02:00
|
|
|
setSmallIcon(R.drawable.ic_glasses_24dp)
|
2021-05-01 04:36:54 +02:00
|
|
|
setOngoing(true)
|
|
|
|
|
|
|
|
|
|
val pendingIntent = PendingIntent.getBroadcast(
|
|
|
|
|
this@App,
|
|
|
|
|
0,
|
|
|
|
|
Intent(ACTION_DISABLE_INCOGNITO_MODE),
|
2022-05-10 23:39:45 +02:00
|
|
|
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE,
|
2021-05-01 04:36:54 +02:00
|
|
|
)
|
|
|
|
|
setContentIntent(pendingIntent)
|
|
|
|
|
}
|
|
|
|
|
notificationManager.notify(Notifications.ID_INCOGNITO_MODE, notification)
|
|
|
|
|
} else {
|
|
|
|
|
disableIncognitoReceiver.unregister()
|
|
|
|
|
notificationManager.cancel(Notifications.ID_INCOGNITO_MODE)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
|
2021-10-08 04:12:55 +02:00
|
|
|
|
2022-10-19 18:57:05 +02:00
|
|
|
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
|
|
|
|
|
|
2022-07-31 17:31:40 +02:00
|
|
|
// Updates widget update
|
2023-01-27 20:49:57 +01:00
|
|
|
with(TachiyomiWidgetManager(Injekt.get())) {
|
|
|
|
|
init(ProcessLifecycleOwner.get().lifecycleScope)
|
2023-01-26 23:53:24 +01:00
|
|
|
}
|
2022-07-31 17:31:40 +02:00
|
|
|
|
2022-09-17 17:48:24 +02:00
|
|
|
/*if (!LogcatLogger.isInstalled && networkPreferences.verboseLogging().get()) {
|
2021-10-08 04:12:55 +02:00
|
|
|
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))
|
|
|
|
|
}*/
|
2016-03-19 17:48:55 +01:00
|
|
|
}
|
|
|
|
|
|
2021-04-28 14:32:00 +02:00
|
|
|
override fun newImageLoader(): ImageLoader {
|
|
|
|
|
return ImageLoader.Builder(this).apply {
|
2022-03-04 22:04:32 +01:00
|
|
|
val callFactoryInit = { Injekt.get<NetworkHelper>().client }
|
|
|
|
|
val diskCacheInit = { CoilDiskCache.get(this@App) }
|
|
|
|
|
components {
|
2021-04-28 14:32:00 +02:00
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
2022-03-04 22:04:32 +01:00
|
|
|
add(ImageDecoderDecoder.Factory())
|
2021-04-28 14:32:00 +02:00
|
|
|
} else {
|
2022-03-04 22:04:32 +01:00
|
|
|
add(GifDecoder.Factory())
|
2021-04-28 14:32:00 +02:00
|
|
|
}
|
2022-03-04 22:04:32 +01:00
|
|
|
add(TachiyomiImageDecoder.Factory())
|
|
|
|
|
add(MangaCoverFetcher.Factory(lazy(callFactoryInit), lazy(diskCacheInit)))
|
2022-06-18 04:21:29 +02:00
|
|
|
add(MangaCoverFetcher.DomainMangaFactory(lazy(callFactoryInit), lazy(diskCacheInit)))
|
|
|
|
|
add(MangaCoverFetcher.MangaCoverFactory(lazy(callFactoryInit), lazy(diskCacheInit)))
|
|
|
|
|
add(MangaKeyer())
|
|
|
|
|
add(DomainMangaKeyer())
|
2022-03-04 22:04:32 +01:00
|
|
|
add(MangaCoverKeyer())
|
2022-07-16 22:44:55 +02:00
|
|
|
// SY -->
|
|
|
|
|
add(PagePreviewKeyer())
|
|
|
|
|
add(PagePreviewFetcher.Factory(lazy(callFactoryInit), lazy(diskCacheInit)))
|
|
|
|
|
// SY <--
|
2021-04-28 14:32:00 +02:00
|
|
|
}
|
2022-03-04 22:04:32 +01:00
|
|
|
callFactory(callFactoryInit)
|
|
|
|
|
diskCache(diskCacheInit)
|
2021-08-27 14:44:09 +02:00
|
|
|
crossfade((300 * this@App.animatorDurationScale).toInt())
|
2021-04-28 14:32:00 +02:00
|
|
|
allowRgb565(getSystemService<ActivityManager>()!!.isLowRamDevice)
|
2022-09-17 17:48:24 +02:00
|
|
|
if (networkPreferences.verboseLogging().get()) logger(DebugLogger())
|
2022-11-19 04:57:54 +01:00
|
|
|
|
|
|
|
|
// Coil spawns a new thread for every image load by default
|
|
|
|
|
fetcherDispatcher(Dispatchers.IO.limitedParallelism(8))
|
|
|
|
|
decoderDispatcher(Dispatchers.IO.limitedParallelism(2))
|
|
|
|
|
transformationDispatcher(Dispatchers.IO.limitedParallelism(2))
|
2021-04-28 14:32:00 +02:00
|
|
|
}.build()
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-22 21:07:44 +02:00
|
|
|
override fun onStart(owner: LifecycleOwner) {
|
|
|
|
|
SecureActivityDelegate.onApplicationStart()
|
2022-09-16 14:34:46 +02:00
|
|
|
}
|
|
|
|
|
|
2020-08-24 03:57:06 +02:00
|
|
|
private fun addAnalytics() {
|
2022-10-22 21:47:09 +02:00
|
|
|
if (isPreviewBuildType) {
|
2021-03-07 06:23:23 +01:00
|
|
|
Firebase.analytics.setUserProperty("preview_version", syDebugVersion)
|
2020-08-24 03:57:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-20 20:33:35 +02:00
|
|
|
override fun onStop(owner: LifecycleOwner) {
|
2022-09-02 17:48:48 +02:00
|
|
|
SecureActivityDelegate.onApplicationStopped()
|
2016-11-06 18:44:14 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-02 16:49:42 +02:00
|
|
|
override fun getPackageName(): String {
|
2022-04-15 19:43:54 +02:00
|
|
|
// This causes freezes in Android 6/7 for some reason
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
|
try {
|
|
|
|
|
// Override the value passed as X-Requested-With in WebView requests
|
|
|
|
|
val stackTrace = Looper.getMainLooper().thread.stackTrace
|
|
|
|
|
val chromiumElement = stackTrace.find {
|
2022-04-15 21:52:48 +02:00
|
|
|
it.className.equals(
|
|
|
|
|
"org.chromium.base.BuildInfo",
|
|
|
|
|
ignoreCase = true,
|
|
|
|
|
)
|
2022-04-15 19:43:54 +02:00
|
|
|
}
|
|
|
|
|
if (chromiumElement?.methodName.equals("getAll", ignoreCase = true)) {
|
|
|
|
|
return WebViewUtil.SPOOF_PACKAGE_NAME
|
|
|
|
|
}
|
|
|
|
|
} catch (e: Exception) {
|
2022-04-02 16:49:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return super.getPackageName()
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-06 22:23:13 +02:00
|
|
|
private fun setupNotificationChannels() {
|
2021-11-07 15:11:41 +01:00
|
|
|
try {
|
|
|
|
|
Notifications.createChannels(this)
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
logcat(LogPriority.ERROR, e) { "Failed to modify notification channels" }
|
|
|
|
|
}
|
2017-10-10 14:15:41 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-14 05:47:57 +02:00
|
|
|
// EXH
|
|
|
|
|
private fun setupExhLogging() {
|
2019-04-14 18:48:59 +02:00
|
|
|
EHLogLevel.init(this)
|
|
|
|
|
|
2020-08-17 02:40:30 +02:00
|
|
|
val logLevel = when {
|
2021-03-07 06:23:23 +01:00
|
|
|
EHLogLevel.shouldLog(EHLogLevel.EXTREME) -> LogLevel.ALL
|
|
|
|
|
EHLogLevel.shouldLog(EHLogLevel.EXTRA) || BuildConfig.DEBUG -> LogLevel.DEBUG
|
2020-08-17 02:40:30 +02:00
|
|
|
else -> LogLevel.WARN
|
2019-04-14 05:47:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val logConfig = LogConfiguration.Builder()
|
2020-05-04 00:34:46 +02:00
|
|
|
.logLevel(logLevel)
|
2020-11-25 21:57:05 +01:00
|
|
|
.disableStackTrace()
|
|
|
|
|
.disableBorder()
|
2020-05-04 00:34:46 +02:00
|
|
|
.build()
|
2019-04-14 05:47:57 +02:00
|
|
|
|
|
|
|
|
val printers = mutableListOf<Printer>(AndroidPrinter())
|
|
|
|
|
|
2020-05-04 00:34:46 +02:00
|
|
|
val logFolder = File(
|
|
|
|
|
Environment.getExternalStorageDirectory().absolutePath + File.separator +
|
|
|
|
|
getString(R.string.app_name),
|
2022-04-08 21:30:30 +02:00
|
|
|
"logs",
|
2020-05-04 00:34:46 +02:00
|
|
|
)
|
2019-04-14 05:47:57 +02:00
|
|
|
|
2020-11-11 23:28:09 +01:00
|
|
|
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
|
|
|
|
|
|
|
|
|
|
printers += EnhancedFilePrinter
|
2021-03-07 06:23:23 +01:00
|
|
|
.Builder(logFolder.absolutePath) {
|
|
|
|
|
fileNameGenerator = object : DateFileNameGenerator() {
|
2020-09-14 00:48:20 +02:00
|
|
|
override fun generateFileName(logLevel: Int, timestamp: Long): String {
|
2020-11-11 23:28:09 +01:00
|
|
|
return super.generateFileName(
|
|
|
|
|
logLevel,
|
2022-04-08 21:30:30 +02:00
|
|
|
timestamp,
|
2020-11-11 23:28:09 +01:00
|
|
|
) + "-${BuildConfig.BUILD_TYPE}.log"
|
2020-09-14 00:48:20 +02:00
|
|
|
}
|
2020-05-04 00:34:46 +02:00
|
|
|
}
|
2021-03-07 06:23:23 +01:00
|
|
|
flattener { timeMillis, level, tag, message ->
|
|
|
|
|
"${dateFormat.format(timeMillis)} ${LogLevel.getShortLevelName(level)}/$tag: $message"
|
|
|
|
|
}
|
2021-06-02 06:10:36 +02:00
|
|
|
cleanStrategy = FileLastModifiedCleanStrategy(7.days.inWholeMilliseconds)
|
2021-03-07 06:23:23 +01:00
|
|
|
backupStrategy = NeverBackupStrategy()
|
2020-11-11 23:28:09 +01:00
|
|
|
}
|
2019-04-14 05:47:57 +02:00
|
|
|
|
|
|
|
|
// Install Crashlytics in prod
|
2020-05-04 00:34:46 +02:00
|
|
|
if (!BuildConfig.DEBUG) {
|
2019-04-14 05:47:57 +02:00
|
|
|
printers += CrashlyticsPrinter(LogLevel.ERROR)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XLog.init(
|
2020-05-04 00:34:46 +02:00
|
|
|
logConfig,
|
2022-04-08 21:30:30 +02:00
|
|
|
*printers.toTypedArray(),
|
2019-04-14 05:47:57 +02:00
|
|
|
)
|
|
|
|
|
|
2021-03-07 06:23:23 +01:00
|
|
|
xLogD("Application booting...")
|
|
|
|
|
xLogD(
|
2021-06-03 03:04:51 +02:00
|
|
|
"""
|
|
|
|
|
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE})
|
|
|
|
|
Preview build: $syDebugVersion
|
|
|
|
|
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
|
|
|
|
|
Android build ID: ${Build.DISPLAY}
|
|
|
|
|
Device brand: ${Build.BRAND}
|
|
|
|
|
Device manufacturer: ${Build.MANUFACTURER}
|
|
|
|
|
Device name: ${Build.DEVICE}
|
|
|
|
|
Device model: ${Build.MODEL}
|
|
|
|
|
Device product name: ${Build.PRODUCT}
|
2022-04-08 21:30:30 +02:00
|
|
|
""".trimIndent(),
|
2020-08-22 02:26:56 +02:00
|
|
|
)
|
2019-04-14 05:47:57 +02:00
|
|
|
}
|
2019-04-14 19:51:20 +02:00
|
|
|
|
2021-05-01 04:36:54 +02:00
|
|
|
private inner class DisableIncognitoReceiver : BroadcastReceiver() {
|
|
|
|
|
private var registered = false
|
|
|
|
|
|
|
|
|
|
override fun onReceive(context: Context, intent: Intent) {
|
2022-09-25 16:07:06 +02:00
|
|
|
basePreferences.incognitoMode().set(false)
|
2021-05-01 04:36:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun register() {
|
|
|
|
|
if (!registered) {
|
|
|
|
|
registerReceiver(this, IntentFilter(ACTION_DISABLE_INCOGNITO_MODE))
|
|
|
|
|
registered = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun unregister() {
|
|
|
|
|
if (registered) {
|
|
|
|
|
unregisterReceiver(this)
|
|
|
|
|
registered = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-03-19 17:48:55 +01:00
|
|
|
}
|
2021-09-05 20:34:29 +02:00
|
|
|
|
|
|
|
|
private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE"
|
2022-03-04 22:04:32 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Direct copy of Coil's internal SingletonDiskCache so that [MangaCoverFetcher] can access it.
|
|
|
|
|
*/
|
|
|
|
|
internal object CoilDiskCache {
|
|
|
|
|
|
|
|
|
|
private const val FOLDER_NAME = "image_cache"
|
|
|
|
|
private var instance: DiskCache? = null
|
|
|
|
|
|
|
|
|
|
@Synchronized
|
|
|
|
|
fun get(context: Context): DiskCache {
|
|
|
|
|
return instance ?: run {
|
|
|
|
|
val safeCacheDir = context.cacheDir.apply { mkdirs() }
|
|
|
|
|
// Create the singleton disk cache instance.
|
|
|
|
|
DiskCache.Builder()
|
|
|
|
|
.directory(safeCacheDir.resolve(FOLDER_NAME))
|
|
|
|
|
.build()
|
|
|
|
|
.also { instance = it }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|