komikku/app/src/main/java/eu/kanade/tachiyomi/App.kt

260 lines
9.1 KiB
Kotlin
Raw Normal View History

package eu.kanade.tachiyomi
import android.app.Application
2016-10-15 11:12:16 +02:00
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
2019-08-07 21:47:43 +02:00
import android.os.Build
2019-04-14 05:47:57 +02:00
import android.os.Environment
2020-05-04 00:34:46 +02:00
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.multidex.MultiDex
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
2019-08-07 21:47:43 +02:00
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
import com.google.android.gms.security.ProviderInstaller
2020-08-24 03:57:06 +02:00
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.ms_square.debugoverlay.DebugOverlay
import com.ms_square.debugoverlay.modules.FpsModule
import eu.kanade.tachiyomi.data.notification.Notifications
2020-05-04 00:34:46 +02:00
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.LocaleHelper
import exh.debug.DebugToggles
2019-04-14 05:47:57 +02:00
import exh.log.CrashlyticsPrinter
import exh.log.EHDebugModeOverlay
2019-04-14 16:46:06 +02:00
import exh.log.EHLogLevel
2020-11-11 23:28:09 +01:00
import exh.log.EnhancedFilePrinter
2020-08-22 02:26:56 +02:00
import exh.syDebugVersion
2017-08-25 23:31:38 +02:00
import io.realm.Realm
import io.realm.RealmConfiguration
2019-04-14 05:47:57 +02:00
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.conscrypt.Conscrypt
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.InjektScope
2020-02-22 04:58:19 +01:00
import uy.kohesive.injekt.injectLazy
import uy.kohesive.injekt.registry.default.DefaultRegistrar
import java.io.File
import java.security.NoSuchAlgorithmException
import java.security.Security
2020-11-11 23:28:09 +01:00
import java.text.SimpleDateFormat
import java.util.Locale
import javax.net.ssl.SSLContext
import kotlin.concurrent.thread
import kotlin.time.ExperimentalTime
import kotlin.time.days
2020-02-22 04:58:19 +01:00
open class App : Application(), LifecycleObserver {
2020-08-24 03:57:06 +02:00
private lateinit var firebaseAnalytics: FirebaseAnalytics
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
2019-04-14 18:48:59 +02:00
setupExhLogging() // EXH logging
2020-08-24 03:57:06 +02:00
if (!BuildConfig.DEBUG) addAnalytics()
2019-08-07 21:47:43 +02:00
workaroundAndroid7BrokenSSL()
// Debug tool; see https://fbflipper.com/
// SoLoader.init(this, false)
// if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
// val client = AndroidFlipperClient.getInstance(this)
// client.addPlugin(InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()))
// client.addPlugin(DatabasesFlipperPlugin(this))
// client.start()
// }
// TLS 1.3 support for Android < 10
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
}
Injekt = InjektScope(DefaultRegistrar())
Injekt.importModule(AppModule(this))
setupNotificationChannels()
Realm.init(this)
2019-04-14 05:47:57 +02:00
GlobalScope.launch { deleteOldMetadataRealm() } // Delete old metadata DB (EH)
2020-05-04 00:34:46 +02:00
if ((BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest") && DebugToggles.ENABLE_DEBUG_OVERLAY.enabled) {
setupDebugOverlay()
}
LocaleHelper.updateConfiguration(this, resources.configuration)
2020-02-22 04:58:19 +01:00
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
2016-10-15 11:12:16 +02:00
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
2019-04-13 15:10:44 +02:00
MultiDex.install(this)
2016-10-15 11:12:16 +02:00
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
LocaleHelper.updateConfiguration(this, newConfig, true)
}
2019-08-07 21:47:43 +02:00
private fun workaroundAndroid7BrokenSSL() {
2020-05-04 00:34:46 +02:00
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N ||
Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1
) {
2019-08-07 21:47:43 +02:00
try {
SSLContext.getInstance("TLSv1.2")
} catch (e: NoSuchAlgorithmException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
}
try {
ProviderInstaller.installIfNeeded(applicationContext)
} catch (e: GooglePlayServicesRepairableException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
} catch (e: GooglePlayServicesNotAvailableException) {
XLog.e("Could not install Android 7 broken SSL workaround!", e)
}
}
}
2020-08-24 03:57:06 +02:00
private fun addAnalytics() {
firebaseAnalytics = Firebase.analytics
if (syDebugVersion != "0") {
firebaseAnalytics.setUserProperty("preview_version", syDebugVersion)
}
}
2020-02-22 04:58:19 +01:00
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
2020-04-14 23:13:45 +02:00
@Suppress("unused")
2020-02-22 04:58:19 +01:00
fun onAppBackgrounded() {
val preferences: PreferencesHelper by injectLazy()
if (preferences.lockAppAfter().get() >= 0) {
2020-02-22 19:30:36 +01:00
SecureActivityDelegate.locked = true
}
}
protected open fun setupNotificationChannels() {
Notifications.createChannels(this)
}
2017-11-24 03:03:49 +01:00
// EXH
2019-04-14 05:47:57 +02:00
private fun deleteOldMetadataRealm() {
2017-08-25 23:31:38 +02:00
val config = RealmConfiguration.Builder()
2020-05-04 00:34:46 +02:00
.name("gallery-metadata.realm")
.schemaVersion(3)
.deleteRealmIfMigrationNeeded()
.build()
2019-04-14 05:47:57 +02:00
Realm.deleteRealm(config)
2017-08-25 23:31:38 +02:00
2020-05-04 00:34:46 +02:00
// Delete old paper db files
2017-08-25 23:31:38 +02:00
listOf(
2020-05-04 00:34:46 +02:00
File(filesDir, "gallery-ex"),
File(filesDir, "gallery-perveden"),
File(filesDir, "gallery-nhentai")
2017-08-25 23:31:38 +02:00
).forEach {
2020-05-04 00:34:46 +02:00
if (it.exists()) {
2017-08-25 23:31:38 +02:00
thread {
it.deleteRecursively()
}
}
}
}
2019-04-14 05:47:57 +02:00
// EXH
private fun setupExhLogging() {
2019-04-14 18:48:59 +02:00
EHLogLevel.init(this)
val logLevel = when {
EHLogLevel.shouldLog(EHLogLevel.EXTRA) -> LogLevel.ALL
BuildConfig.DEBUG -> LogLevel.DEBUG
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)
.st(2)
.nb()
.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),
"logs"
)
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())
@OptIn(ExperimentalTime::class)
2020-11-11 23:28:09 +01:00
printers += EnhancedFilePrinter
2020-05-04 00:34:46 +02:00
.Builder(logFolder.absolutePath)
.fileNameGenerator(
object : DateFileNameGenerator() {
override fun generateFileName(logLevel: Int, timestamp: Long): String {
2020-11-11 23:28:09 +01:00
return super.generateFileName(
logLevel,
timestamp
) + "-${BuildConfig.BUILD_TYPE}.log"
}
2020-05-04 00:34:46 +02:00
}
)
2020-11-11 23:28:09 +01:00
.flattener { timeMillis, level, tag, message ->
"${dateFormat.format(timeMillis)} ${LogLevel.getShortLevelName(level)}/$tag: $message"
}
.cleanStrategy(FileLastModifiedCleanStrategy(7.days.toLongMilliseconds()))
2020-05-04 00:34:46 +02:00
.backupStrategy(NeverBackupStrategy())
.build()
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,
*printers.toTypedArray()
2019-04-14 05:47:57 +02:00
)
XLog.d("Application booting...")
2020-08-22 02:26:56 +02:00
XLog.nst().d(
"App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE})\n" +
"Preview build: $syDebugVersion\n" +
"Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}) \n" +
"Android build ID: ${Build.DISPLAY}\n" +
"Device brand: ${Build.BRAND}\n" +
"Device manufacturer: ${Build.MANUFACTURER}\n" +
"Device name: ${Build.DEVICE}\n" +
"Device model: ${Build.MODEL}\n" +
"Device product name: ${Build.PRODUCT}"
)
2019-04-14 05:47:57 +02:00
}
// EXH
private fun setupDebugOverlay() {
try {
DebugOverlay.Builder(this)
2020-05-04 00:34:46 +02:00
.modules(FpsModule(), EHDebugModeOverlay(this))
.bgColor(Color.parseColor("#7F000000"))
.notification(false)
.allowSystemLayer(false)
.build()
.install()
} catch (e: IllegalStateException) {
// Crashes if app is in background
XLog.e("Failed to initialize debug overlay, app in background?", e)
}
}
}