diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 271e7f49c..4fc1aede8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -234,6 +234,10 @@ dependencies { // Debug utilities debugImplementation("com.squareup.leakcanary:leakcanary-android:2.10") + debugImplementation("com.plutolib:pluto:2.0.9") + releaseImplementation("com.plutolib:pluto-no-op:2.0.9") + debugImplementation("com.plutolib.plugins:bundle-core:2.0.9") + releaseImplementation("com.plutolib.plugins:bundle-core-no-op:2.0.9") // Unit tests testImplementation("junit:junit:4.13.2") diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/MainApplication.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/MainApplication.kt index 7751c821a..bad42de86 100644 --- a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/MainApplication.kt +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/MainApplication.kt @@ -7,8 +7,18 @@ import android.content.Intent import android.content.IntentFilter import android.content.SharedPreferences import android.os.Build +import android.os.StrictMode import android.util.Log import androidx.appcompat.app.AppCompatDelegate +import com.pluto.Pluto +import com.pluto.plugins.exceptions.PlutoExceptions +import com.pluto.plugins.exceptions.PlutoExceptionsPlugin +import com.pluto.plugins.logger.PlutoLoggerPlugin +import com.pluto.plugins.logger.PlutoTimberTree +import com.pluto.plugins.network.PlutoNetworkPlugin +import com.pluto.plugins.preferences.PlutoSharePreferencesPlugin +import com.pluto.plugins.rooms.db.PlutoRoomsDBWatcher +import com.pluto.plugins.rooms.db.PlutoRoomsDatabasePlugin import fr.bipi.tressence.file.FileLoggerTree import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -89,6 +99,7 @@ class MainApplication : Application(), SharedPreferences.OnSharedPreferenceChang override fun onCreate() { Timber.plant(DebugTree()) + Timber.plant(PlutoTimberTree()) if(!BuildConfig.FOSS_ONLY) Timber.plant(CrashReportingTree()) @@ -112,6 +123,49 @@ class MainApplication : Application(), SharedPreferences.OnSharedPreferenceChang dumpFile.delete() } + if(BuildConfig.DEBUG) { + // Setup strict mode with death penalty + StrictMode.setThreadPolicy( + StrictMode.ThreadPolicy.Builder() + .detectCustomSlowCalls() + .detectNetwork() + .detectResourceMismatches() + .penaltyLog() + .penaltyDeath() + .build() + ) + + StrictMode.setVmPolicy( + StrictMode.VmPolicy.Builder() + .apply { + detectLeakedRegistrationObjects() + detectCleartextNetwork() + detectActivityLeaks() + detectLeakedClosableObjects() + detectLeakedSqlLiteObjects() + detectContentUriWithoutPermission() + penaltyLog() + penaltyDeath() + } + .build() + ) + + Pluto.Installer(this) + .addPlugin(PlutoNetworkPlugin("network")) + .addPlugin(PlutoExceptionsPlugin("exceptions")) + .addPlugin(PlutoLoggerPlugin("logger")) + .addPlugin(PlutoSharePreferencesPlugin("sharedPref")) + .addPlugin(PlutoRoomsDatabasePlugin("rooms-db")) + .install() + Pluto.showNotch(true) + + PlutoExceptions.setANRHandler { thread, exception -> + Timber.e("unhandled ANR handled on thread: " + thread.name, exception) + } + + PlutoRoomsDBWatcher.watch("blocked_apps.db", AppBlocklistDatabase::class.java) + } + Notifications.createChannels(this) val appModule = module { diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/api/AutoEqClient.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/api/AutoEqClient.kt index fab8a2b83..af3e736b8 100644 --- a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/api/AutoEqClient.kt +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/api/AutoEqClient.kt @@ -1,6 +1,7 @@ package me.timschneeberger.rootlessjamesdsp.api import android.content.Context +import com.pluto.plugins.network.PlutoInterceptor import me.timschneeberger.rootlessjamesdsp.BuildConfig import me.timschneeberger.rootlessjamesdsp.R import me.timschneeberger.rootlessjamesdsp.flavor.CrashlyticsImpl @@ -25,6 +26,7 @@ class AutoEqClient(val context: Context, callTimeout: Long = 10, customBaseUrl: private val http = OkHttpClient .Builder() .callTimeout(callTimeout, TimeUnit.SECONDS) + .addInterceptor(PlutoInterceptor()) .addInterceptor(UserAgentInterceptor("RootlessJamesDSP v${BuildConfig.VERSION_NAME}")) .build() diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 86210c9a5..33d58f3e6 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -22,7 +22,7 @@ - + diff --git a/app/src/root/java/me/timschneeberger/rootlessjamesdsp/flavor/updates/api/UpdateCheckClient.kt b/app/src/root/java/me/timschneeberger/rootlessjamesdsp/flavor/updates/api/UpdateCheckClient.kt index aa8bbfb83..2016a1e63 100644 --- a/app/src/root/java/me/timschneeberger/rootlessjamesdsp/flavor/updates/api/UpdateCheckClient.kt +++ b/app/src/root/java/me/timschneeberger/rootlessjamesdsp/flavor/updates/api/UpdateCheckClient.kt @@ -1,6 +1,7 @@ package me.timschneeberger.rootlessjamesdsp.flavor.updates.api import android.content.Context +import com.pluto.plugins.network.PlutoInterceptor import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged @@ -27,6 +28,7 @@ class UpdateCheckClient(val context: Context, callTimeout: Long = 10): KoinCompo private val http = OkHttpClient .Builder() .callTimeout(callTimeout, TimeUnit.SECONDS) + .addInterceptor(PlutoInterceptor()) .addInterceptor(UserAgentInterceptor("RootlessJamesDSP v${BuildConfig.VERSION_NAME}")) .build()