mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-18 15:56:24 +01:00
Re-organize gradle modules.
This commit is contained in:
committed by
jeffrey-signal
parent
f4863efb2e
commit
e162eb27c7
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.debuglogsviewer
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.webkit.ValueCallback
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import kotlinx.coroutines.Runnable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.function.Consumer
|
||||
|
||||
object DebugLogsViewer {
|
||||
@JvmStatic
|
||||
fun initWebView(webview: WebView, context: Context, onFinished: Runnable) {
|
||||
webview.settings.apply {
|
||||
javaScriptEnabled = true
|
||||
builtInZoomControls = true
|
||||
displayZoomControls = false
|
||||
}
|
||||
webview.isVerticalScrollBarEnabled = false
|
||||
webview.isHorizontalScrollBarEnabled = false
|
||||
|
||||
webview.setBackgroundColor(Color.TRANSPARENT)
|
||||
webview.background = null
|
||||
|
||||
webview.loadUrl("file:///android_asset/debuglogs-viewer.html")
|
||||
|
||||
webview.webViewClient = object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
if (context.isDarkTheme) {
|
||||
webview.evaluateJavascript("document.body.classList.add('dark');", null)
|
||||
}
|
||||
onFinished.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun appendLines(webview: WebView, lines: String) {
|
||||
// Set the debug log lines
|
||||
val escaped = JSONObject.quote(lines)
|
||||
val latch = CountDownLatch(1)
|
||||
ThreadUtil.runOnMain {
|
||||
webview.evaluateJavascript("appendLines($escaped)") { latch.countDown() }
|
||||
}
|
||||
latch.await()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun readLogs(webview: WebView): LogReader {
|
||||
var position = 0
|
||||
return LogReader { size ->
|
||||
val latch = CountDownLatch(1)
|
||||
var result: String? = null
|
||||
ThreadUtil.runOnMain {
|
||||
webview.evaluateJavascript("readLines($position, $size)") { value ->
|
||||
// Annoying, string returns from javascript land are always encoded as JSON strings (wrapped in quotes, various strings escaped, etc)
|
||||
val parsed = JSONArray("[$value]").getString(0)
|
||||
result = parsed.takeUnless { it == "<<END OF INPUT>>" }
|
||||
position += size
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
|
||||
latch.await()
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun scrollToTop(webview: WebView) {
|
||||
webview.evaluateJavascript("editor.scrollToRow(0);", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun scrollToBottom(webview: WebView) {
|
||||
webview.evaluateJavascript("editor.scrollToRow(editor.session.getLength() - 1);", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchInput(webview: WebView, query: String) {
|
||||
val escaped = JSONObject.quote(query)
|
||||
webview.evaluateJavascript("onSearchInput($escaped)", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearch(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearch()", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onFilter(webview: WebView) {
|
||||
webview.evaluateJavascript("onFilter()", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onFilterClose(webview: WebView) {
|
||||
webview.evaluateJavascript("onFilterClose()", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onFilterLevel(webview: WebView, selectedLevels: String) {
|
||||
webview.evaluateJavascript("if (isFiltered) { onFilter(); }", null)
|
||||
webview.evaluateJavascript("onFilterLevel($selectedLevels)", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchUp(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchUp();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchDown(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchDown();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSearchPosition(webView: WebView, callback: Consumer<String?>) {
|
||||
webView.evaluateJavascript("getSearchPosition();", ValueCallback { value: String? -> callback.accept(value?.trim('"') ?: "") })
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onToggleCaseSensitive(webview: WebView) {
|
||||
webview.evaluateJavascript("onToggleCaseSensitive();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchClose(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchClose();", null)
|
||||
}
|
||||
|
||||
private val Context.isDarkTheme
|
||||
get() = (this.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
fun interface LogReader {
|
||||
/** Returns the next bit of log, containing at most [size] lines (but may be less), or null if there are no logs remaining. */
|
||||
fun nextChunk(size: Int): String?
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user