Replace DebugOverlay library with a custom composable
This commit is contained in:
parent
0663928b6b
commit
266b4c4dd7
@ -298,13 +298,6 @@ dependencies {
|
|||||||
// Better logging (EH)
|
// Better logging (EH)
|
||||||
implementation(sylibs.xlog)
|
implementation(sylibs.xlog)
|
||||||
|
|
||||||
// Debug utils (EH)
|
|
||||||
debugImplementation(sylibs.debugOverlay.standard)
|
|
||||||
"releaseTestImplementation"(sylibs.debugOverlay.noop)
|
|
||||||
"benchmarkImplementation"(sylibs.debugOverlay.noop)
|
|
||||||
releaseImplementation(sylibs.debugOverlay.noop)
|
|
||||||
testImplementation(sylibs.debugOverlay.noop)
|
|
||||||
|
|
||||||
// RatingBar (SY)
|
// RatingBar (SY)
|
||||||
implementation(sylibs.ratingbar)
|
implementation(sylibs.ratingbar)
|
||||||
implementation(sylibs.composeRatingbar)
|
implementation(sylibs.composeRatingbar)
|
||||||
|
@ -8,7 +8,6 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@ -36,8 +35,6 @@ import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
|
|||||||
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
|
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
|
||||||
import com.google.firebase.analytics.ktx.analytics
|
import com.google.firebase.analytics.ktx.analytics
|
||||||
import com.google.firebase.ktx.Firebase
|
import com.google.firebase.ktx.Firebase
|
||||||
import com.ms_square.debugoverlay.DebugOverlay
|
|
||||||
import com.ms_square.debugoverlay.modules.FpsModule
|
|
||||||
import eu.kanade.data.DatabaseHandler
|
import eu.kanade.data.DatabaseHandler
|
||||||
import eu.kanade.domain.DomainModule
|
import eu.kanade.domain.DomainModule
|
||||||
import eu.kanade.domain.SYDomainModule
|
import eu.kanade.domain.SYDomainModule
|
||||||
@ -63,14 +60,11 @@ import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
|||||||
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.notification
|
import eu.kanade.tachiyomi.util.system.notification
|
||||||
import exh.debug.DebugToggles
|
|
||||||
import exh.log.CrashlyticsPrinter
|
import exh.log.CrashlyticsPrinter
|
||||||
import exh.log.EHDebugModeOverlay
|
|
||||||
import exh.log.EHLogLevel
|
import exh.log.EHLogLevel
|
||||||
import exh.log.EnhancedFilePrinter
|
import exh.log.EnhancedFilePrinter
|
||||||
import exh.log.XLogLogcatLogger
|
import exh.log.XLogLogcatLogger
|
||||||
import exh.log.xLogD
|
import exh.log.xLogD
|
||||||
import exh.log.xLogE
|
|
||||||
import exh.syDebugVersion
|
import exh.syDebugVersion
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
@ -126,9 +120,6 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
|
|||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
setupNotificationChannels()
|
setupNotificationChannels()
|
||||||
if ((BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest") && DebugToggles.ENABLE_DEBUG_OVERLAY.enabled) {
|
|
||||||
setupDebugOverlay()
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
|
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
|
||||||
|
|
||||||
@ -327,22 +318,6 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXH
|
|
||||||
private fun setupDebugOverlay() {
|
|
||||||
try {
|
|
||||||
DebugOverlay.Builder(this)
|
|
||||||
.modules(FpsModule(), EHDebugModeOverlay(this))
|
|
||||||
.bgColor(Color.parseColor("#7F000000"))
|
|
||||||
.notification(false)
|
|
||||||
.allowSystemLayer(false)
|
|
||||||
.build()
|
|
||||||
.install()
|
|
||||||
} catch (e: IllegalStateException) {
|
|
||||||
// Crashes if app is in background
|
|
||||||
xLogE("Failed to initialize debug overlay, app in background?", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class DisableIncognitoReceiver : BroadcastReceiver() {
|
private inner class DisableIncognitoReceiver : BroadcastReceiver() {
|
||||||
private var registered = false
|
private var registered = false
|
||||||
|
|
||||||
|
@ -65,7 +65,9 @@ import eu.kanade.tachiyomi.util.system.toast
|
|||||||
import eu.kanade.tachiyomi.util.view.setComposeContent
|
import eu.kanade.tachiyomi.util.view.setComposeContent
|
||||||
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
||||||
import exh.EXHMigrations
|
import exh.EXHMigrations
|
||||||
|
import exh.debug.DebugToggles
|
||||||
import exh.eh.EHentaiUpdateWorker
|
import exh.eh.EHentaiUpdateWorker
|
||||||
|
import exh.log.DebugModeOverlay
|
||||||
import exh.source.BlacklistedSources
|
import exh.source.BlacklistedSources
|
||||||
import exh.source.EH_SOURCE_ID
|
import exh.source.EH_SOURCE_ID
|
||||||
import exh.source.EXH_SOURCE_ID
|
import exh.source.EXH_SOURCE_ID
|
||||||
@ -162,6 +164,9 @@ class MainActivity : BaseActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("KotlinConstantConditions")
|
||||||
|
val hasDebugOverlay = (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest")
|
||||||
|
|
||||||
// Draw edge-to-edge
|
// Draw edge-to-edge
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
@ -206,6 +211,15 @@ class MainActivity : BaseActivity() {
|
|||||||
CheckForUpdate()
|
CheckForUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasDebugOverlay) {
|
||||||
|
val isDebugOverlayEnabled by remember {
|
||||||
|
DebugToggles.ENABLE_DEBUG_OVERLAY.asPref(lifecycleScope)
|
||||||
|
}
|
||||||
|
if (isDebugOverlayEnabled) {
|
||||||
|
DebugModeOverlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var showChangelog by remember { mutableStateOf(didMigration && !BuildConfig.DEBUG) }
|
var showChangelog by remember { mutableStateOf(didMigration && !BuildConfig.DEBUG) }
|
||||||
if (showChangelog) {
|
if (showChangelog) {
|
||||||
// SY -->
|
// SY -->
|
||||||
|
@ -1,70 +1,170 @@
|
|||||||
package exh.log
|
package exh.log
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.Choreographer
|
||||||
import android.view.ViewGroup
|
import androidx.compose.foundation.background
|
||||||
import android.widget.LinearLayout
|
import androidx.compose.foundation.layout.Box
|
||||||
import android.widget.TextView
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import com.ms_square.debugoverlay.DataObserver
|
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||||
import com.ms_square.debugoverlay.OverlayModule
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
|
import androidx.compose.foundation.layout.only
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.RememberObserver
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.withStyle
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import eu.kanade.core.prefs.asState
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.api.get
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.text.DecimalFormatSymbols
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.time.Duration.Companion.nanoseconds
|
||||||
|
|
||||||
class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(null, null) {
|
@Composable
|
||||||
private var textView: TextView? = null
|
fun DebugModeOverlay() {
|
||||||
private val preferences: SourcePreferences by injectLazy()
|
Box(Modifier.fillMaxSize()) {
|
||||||
|
Column(
|
||||||
override fun start() {}
|
Modifier
|
||||||
override fun stop() {}
|
.windowInsetsPadding(
|
||||||
override fun notifyObservers() {}
|
WindowInsets.navigationBars
|
||||||
override fun addObserver(observer: DataObserver<Any>) {
|
.only(WindowInsetsSides.Bottom.plus(WindowInsetsSides.Start)),
|
||||||
observer.onDataAvailable(buildInfo())
|
)
|
||||||
}
|
.align(Alignment.BottomStart)
|
||||||
override fun removeObserver(observer: DataObserver<Any>) {}
|
.background(Color(0x7F000000))
|
||||||
override fun onDataAvailable(data: String?) {
|
.padding(4.dp),
|
||||||
textView?.text = HtmlCompat.fromHtml(data.orEmpty(), HtmlCompat.FROM_HTML_MODE_LEGACY)
|
) {
|
||||||
}
|
FpsDebugModeOverlay()
|
||||||
|
EHDebugModeOverlay()
|
||||||
override fun createView(root: ViewGroup, textColor: Int, textSize: Float, textAlpha: Float): View {
|
|
||||||
val view = LinearLayout(root.context).apply {
|
|
||||||
layoutParams = ViewGroup.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
)
|
|
||||||
setPadding(4.dpToPx, 0, 4.dpToPx, 4.dpToPx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val textView = TextView(view.context).apply {
|
|
||||||
setTextColor(textColor)
|
|
||||||
this.textSize = textSize
|
|
||||||
alpha = textAlpha
|
|
||||||
text = HtmlCompat.fromHtml(buildInfo(), HtmlCompat.FROM_HTML_MODE_LEGACY)
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
view.addView(textView)
|
|
||||||
this.textView = textView
|
|
||||||
return view
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun buildInfo() =
|
|
||||||
"""
|
@Composable
|
||||||
<font color='green'>===[ ${context.getString(R.string.app_name)} ]===</font><br>
|
private fun FpsDebugModeOverlay() {
|
||||||
<b>Build type:</b> ${BuildConfig.BUILD_TYPE}<br>
|
val fps by remember { FpsState(FpsState.DEFAULT_INTERVAL) }
|
||||||
<b>Debug mode:</b> ${BuildConfig.DEBUG.asEnabledString()}<br>
|
val format = remember {
|
||||||
<b>Version code:</b> ${BuildConfig.VERSION_CODE}<br>
|
DecimalFormat(
|
||||||
<b>Commit SHA:</b> ${BuildConfig.COMMIT_SHA}<br>
|
"'fps:' 0.0",
|
||||||
<b>Log level:</b> ${EHLogLevel.currentLogLevel.name.lowercase(Locale.getDefault())}<br>
|
DecimalFormatSymbols.getInstance(Locale.ENGLISH),
|
||||||
<b>Source blacklist:</b> ${preferences.enableSourceBlacklist().get().asEnabledString()}
|
)
|
||||||
""".trimIndent()
|
}
|
||||||
|
|
||||||
private fun Boolean.asEnabledString() = if (this) "enabled" else "disabled"
|
Text(
|
||||||
|
text = remember(fps) {
|
||||||
|
format.format(fps)
|
||||||
|
},
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun EHDebugModeOverlay() {
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val enableSourceBlacklist by remember {
|
||||||
|
Injekt.get<SourcePreferences>().enableSourceBlacklist().asState(scope)
|
||||||
|
}
|
||||||
|
val context = LocalContext.current
|
||||||
|
Text(
|
||||||
|
text = remember(enableSourceBlacklist) {
|
||||||
|
buildInfo(context, enableSourceBlacklist)
|
||||||
|
},
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 14.sp,
|
||||||
|
letterSpacing = 0.1f.sp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildInfo(context: Context, sourceBlacklist: Boolean) = buildAnnotatedString {
|
||||||
|
withStyle(SpanStyle(color = Color.Green)) {
|
||||||
|
append("===[ ")
|
||||||
|
append(context.getString(R.string.app_name))
|
||||||
|
append(" ]===")
|
||||||
|
}
|
||||||
|
append('\n')
|
||||||
|
appendItem("Build type:", BuildConfig.BUILD_TYPE)
|
||||||
|
appendItem("Debug mode:", BuildConfig.DEBUG.asEnabledString())
|
||||||
|
appendItem("Version code:", BuildConfig.VERSION_CODE.toString())
|
||||||
|
appendItem("Commit SHA:", BuildConfig.COMMIT_SHA)
|
||||||
|
appendItem("Log level:", EHLogLevel.currentLogLevel.name.lowercase(Locale.getDefault()))
|
||||||
|
appendItem("Source blacklist:", sourceBlacklist.asEnabledString(), newLine = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnnotatedString.Builder.appendItem(title: String, item: String, newLine: Boolean = true) {
|
||||||
|
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||||
|
append(title)
|
||||||
|
}
|
||||||
|
append(' ')
|
||||||
|
append(item)
|
||||||
|
if (newLine) {
|
||||||
|
append('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Boolean.asEnabledString() = if (this) "enabled" else "disabled"
|
||||||
|
|
||||||
|
private class FpsState(private val interval: Int) :
|
||||||
|
Choreographer.FrameCallback,
|
||||||
|
RememberObserver,
|
||||||
|
MutableState<Double> by mutableStateOf(0.0) {
|
||||||
|
private val choreographer = Choreographer.getInstance()
|
||||||
|
private var startFrameTimeMillis: Long = 0
|
||||||
|
private var numFramesRendered = 0
|
||||||
|
|
||||||
|
override fun onRemembered() {
|
||||||
|
choreographer.postFrameCallback(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAbandoned() {
|
||||||
|
choreographer.removeFrameCallback(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onForgotten() {
|
||||||
|
choreographer.removeFrameCallback(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doFrame(frameTimeNanos: Long) {
|
||||||
|
val currentFrameTimeMillis = frameTimeNanos.nanoseconds.inWholeMilliseconds
|
||||||
|
if (startFrameTimeMillis > 0) {
|
||||||
|
val duration = currentFrameTimeMillis - startFrameTimeMillis
|
||||||
|
numFramesRendered++
|
||||||
|
if (duration > interval) {
|
||||||
|
value = (numFramesRendered * 1000f / duration).toDouble()
|
||||||
|
startFrameTimeMillis = currentFrameTimeMillis
|
||||||
|
numFramesRendered = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startFrameTimeMillis = currentFrameTimeMillis
|
||||||
|
}
|
||||||
|
choreographer.postFrameCallback(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DEFAULT_INTERVAL = 1000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
[versions]
|
[versions]
|
||||||
debugOverlay = "1.1.3"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
firebase-analytics = "com.google.firebase:firebase-analytics-ktx:21.0.0"
|
firebase-analytics = "com.google.firebase:firebase-analytics-ktx:21.0.0"
|
||||||
@ -9,8 +8,5 @@ firebase-crashlytics-gradle = "com.google.firebase:firebase-crashlytics-gradle:2
|
|||||||
simularity = "info.debatty:java-string-similarity:2.0.0"
|
simularity = "info.debatty:java-string-similarity:2.0.0"
|
||||||
xlog = "com.elvishew:xlog:1.11.0"
|
xlog = "com.elvishew:xlog:1.11.0"
|
||||||
|
|
||||||
debugOverlay-standard = { module = "com.ms-square:debugoverlay", version.ref = "debugOverlay" }
|
|
||||||
debugOverlay-noop = { module = "com.ms-square:debugoverlay-no-op", version.ref = "debugOverlay" }
|
|
||||||
|
|
||||||
ratingbar = "me.zhanghai.android.materialratingbar:library:1.4.0"
|
ratingbar = "me.zhanghai.android.materialratingbar:library:1.4.0"
|
||||||
composeRatingbar = "com.github.a914-gowtham:compose-ratingbar:1.2.3"
|
composeRatingbar = "com.github.a914-gowtham:compose-ratingbar:1.2.3"
|
Loading…
x
Reference in New Issue
Block a user