You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.5 KiB
Kotlin
92 lines
2.5 KiB
Kotlin
package org.koitharu.kotatsu
|
|
|
|
import android.content.Context
|
|
import android.content.SharedPreferences
|
|
import android.os.Build
|
|
import android.os.StrictMode
|
|
import androidx.core.content.edit
|
|
import androidx.fragment.app.strictmode.FragmentStrictMode
|
|
import leakcanary.LeakCanary
|
|
import org.koitharu.kotatsu.core.BaseApp
|
|
|
|
class KotatsuApp : BaseApp() {
|
|
|
|
var isLeakCanaryEnabled: Boolean
|
|
get() = getDebugPreferences(this).getBoolean(KEY_LEAK_CANARY, true)
|
|
set(value) {
|
|
getDebugPreferences(this).edit { putBoolean(KEY_LEAK_CANARY, value) }
|
|
configureLeakCanary()
|
|
}
|
|
|
|
override fun attachBaseContext(base: Context) {
|
|
super.attachBaseContext(base)
|
|
enableStrictMode()
|
|
configureLeakCanary()
|
|
}
|
|
|
|
private fun configureLeakCanary() {
|
|
LeakCanary.config = LeakCanary.config.copy(
|
|
dumpHeap = isLeakCanaryEnabled,
|
|
)
|
|
}
|
|
|
|
private fun enableStrictMode() {
|
|
val notifier = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
StrictModeNotifier(this)
|
|
} else {
|
|
null
|
|
}
|
|
StrictMode.setThreadPolicy(
|
|
StrictMode.ThreadPolicy.Builder().apply {
|
|
detectNetwork()
|
|
detectDiskWrites()
|
|
detectCustomSlowCalls()
|
|
detectResourceMismatches()
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) detectUnbufferedIo()
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) detectExplicitGc()
|
|
penaltyLog()
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && notifier != null) {
|
|
penaltyListener(notifier.executor, notifier)
|
|
}
|
|
}.build(),
|
|
)
|
|
StrictMode.setVmPolicy(
|
|
StrictMode.VmPolicy.Builder().apply {
|
|
detectActivityLeaks()
|
|
detectLeakedSqlLiteObjects()
|
|
detectLeakedClosableObjects()
|
|
detectLeakedRegistrationObjects()
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
detectContentUriWithoutPermission()
|
|
}
|
|
detectFileUriExposure()
|
|
penaltyLog()
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && notifier != null) {
|
|
penaltyListener(notifier.executor, notifier)
|
|
}
|
|
}.build(),
|
|
)
|
|
FragmentStrictMode.defaultPolicy = FragmentStrictMode.Policy.Builder().apply {
|
|
detectWrongFragmentContainer()
|
|
detectFragmentTagUsage()
|
|
detectRetainInstanceUsage()
|
|
detectSetUserVisibleHint()
|
|
detectWrongNestedHierarchy()
|
|
detectFragmentReuse()
|
|
penaltyLog()
|
|
if (notifier != null) {
|
|
penaltyListener(notifier)
|
|
}
|
|
}.build()
|
|
}
|
|
|
|
private companion object {
|
|
|
|
const val PREFS_DEBUG = "_debug"
|
|
const val KEY_LEAK_CANARY = "leak_canary"
|
|
|
|
fun getDebugPreferences(context: Context): SharedPreferences =
|
|
context.getSharedPreferences(PREFS_DEBUG, MODE_PRIVATE)
|
|
}
|
|
}
|