Added ability to view logs
This commit is contained in:
parent
f0625ebc18
commit
f12ed7ef2d
6 changed files with 215 additions and 2 deletions
97
app/src/main/java/com/gaurav/avnc/ui/prefs/InfoFragment.kt
Normal file
97
app/src/main/java/com/gaurav/avnc/ui/prefs/InfoFragment.kt
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Gaurav Ujjwal.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* See COPYING.txt for more details.
|
||||
*/
|
||||
|
||||
package com.gaurav.avnc.ui.prefs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.annotation.Keep
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.gaurav.avnc.R
|
||||
import com.gaurav.avnc.databinding.FragmentInfoBinding
|
||||
import com.gaurav.avnc.util.Debugging
|
||||
import com.gaurav.avnc.viewmodel.PrefsViewModel
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* Simple fragment which shows different types of info in scrollable text view.
|
||||
* It also allows copying the value to clipboard.
|
||||
*/
|
||||
@Keep
|
||||
abstract class InfoFragment : Fragment() {
|
||||
|
||||
var text = ""
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
val binding = FragmentInfoBinding.inflate(inflater, container, false)
|
||||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
withContext(Dispatchers.IO) {
|
||||
text = getInfo()
|
||||
}
|
||||
|
||||
binding.text.text = text
|
||||
delay(100)
|
||||
binding.scrollV.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.title = getTitle()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
menu.add(getString(android.R.string.copy))
|
||||
.setOnMenuItemClickListener { copyToClipboard(); true }
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
}
|
||||
|
||||
private fun copyToClipboard() {
|
||||
activityViewModels<PrefsViewModel>().value.setClipboardText(text)
|
||||
Snackbar.make(requireView(), "Copied!", Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
abstract fun getInfo(): String
|
||||
abstract fun getTitle(): String
|
||||
}
|
||||
|
||||
|
||||
@Keep
|
||||
class LogsFragment : InfoFragment() {
|
||||
override fun getInfo() = Debugging.logcat()
|
||||
override fun getTitle() = getString(R.string.pref_logs)
|
||||
|
||||
/**
|
||||
* In addition to Copy, users can Clear the logs
|
||||
*/
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
menu.add("Clear").setOnMenuItemClickListener {
|
||||
Debugging.clearLogs()
|
||||
Snackbar.make(requireView(), "Cleared!", Snackbar.LENGTH_SHORT).show()
|
||||
parentFragmentManager.popBackStack()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
class KeyCodeMapFragment : InfoFragment() {
|
||||
override fun getInfo() = Debugging.keyCodeMap()
|
||||
override fun getTitle() = getString(R.string.pref_keycode_map)
|
||||
}
|
||||
62
app/src/main/java/com/gaurav/avnc/util/Debugging.kt
Normal file
62
app/src/main/java/com/gaurav/avnc/util/Debugging.kt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Gaurav Ujjwal.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* See COPYING.txt for more details.
|
||||
*/
|
||||
|
||||
package com.gaurav.avnc.util
|
||||
|
||||
import android.view.KeyEvent
|
||||
|
||||
/**
|
||||
* Utilities to aid in debugging
|
||||
*/
|
||||
object Debugging {
|
||||
|
||||
/**
|
||||
* Returns logcat output.
|
||||
* Should not be called from main thread.
|
||||
*/
|
||||
fun logcat(): String {
|
||||
try {
|
||||
return ProcessBuilder("logcat", "-d")
|
||||
.redirectErrorStream(true)
|
||||
.start()
|
||||
.inputStream
|
||||
.bufferedReader()
|
||||
.readText()
|
||||
} catch (t: Throwable) {
|
||||
return "Error getting logs: ${t.message}"
|
||||
}
|
||||
}
|
||||
|
||||
fun clearLogs() {
|
||||
try {
|
||||
ProcessBuilder("logcat", "-c").start()
|
||||
} catch (t: Throwable) {
|
||||
//Ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a map of various properties of key-codes.
|
||||
* Can be useful if some keys are not working as intended.
|
||||
*/
|
||||
fun keyCodeMap(): String {
|
||||
val builder = StringBuilder()
|
||||
|
||||
builder.append("# Keycode Unicode Printing? Label\n")
|
||||
for (i in 0..KeyEvent.getMaxKeyCode()) {
|
||||
val e = KeyEvent(KeyEvent.ACTION_DOWN, i)
|
||||
|
||||
val s = String.format("%4d %-40s %5d %5b %c \n",
|
||||
i, KeyEvent.keyCodeToString(i), e.unicodeChar, e.isPrintingKey, e.displayLabel);
|
||||
|
||||
builder.append(s)
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
9
app/src/main/res/drawable/ic_bug.xml
Normal file
9
app/src/main/res/drawable/ic_bug.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?colorOnSurface"
|
||||
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z" />
|
||||
</vector>
|
||||
30
app/src/main/res/layout/fragment_info.xml
Normal file
30
app/src/main/res/layout/fragment_info.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2021 Gaurav Ujjwal.
|
||||
~
|
||||
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
~
|
||||
~ See COPYING.txt for more details.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scroll_v"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_normal"
|
||||
android:text="@string/msg_loading"
|
||||
android:typeface="monospace"
|
||||
android:textSize="12sp"/>
|
||||
</HorizontalScrollView>
|
||||
</ScrollView>
|
||||
</layout>
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
<string name="msg_server_profile_deleted">Server deleted.</string>
|
||||
<string name="msg_pip_not_supported">Picture-in-Picture is not supported on this device</string>
|
||||
<string name="msg_loading">Loading …</string>
|
||||
<string name="desc_navigation_btn">Open Navigation Drawer</string>
|
||||
<string name="desc_disconnected_icon">Disconnected state indicator icon</string>
|
||||
<string name="desc_connect_btn">Connect to this URL</string>
|
||||
|
|
@ -71,7 +72,7 @@
|
|||
<string name="pref_servers">Servers</string>
|
||||
<string name="pref_server_summary">Discovery, Credentials</string>
|
||||
<string name="pref_tools">Tools</string>
|
||||
<string name="pref_tools_summary">Import/Export</string>
|
||||
<string name="pref_tools_summary">Import/Export, Debugging</string>
|
||||
<string name="pref_experimental">Experimental</string>
|
||||
<string name="pref_experimental_summary">Extra goodies!</string>
|
||||
|
||||
|
|
@ -107,6 +108,9 @@
|
|||
<string name="pref_discovery_restart_summary">Restart Discovery after it stops</string>
|
||||
<string name="pref_discovery_restart_delay">Restart Delay (Minutes)</string>
|
||||
<string name="pref_import_export">Import/Export Servers</string>
|
||||
<string name="pref_debugging">Debugging</string>
|
||||
<string name="pref_logs">Logs</string>
|
||||
<string name="pref_keycode_map">Keycode Map</string>
|
||||
<string name="pref_experimental_indicator">Availability Indicator</string>
|
||||
<string name="pref_experimental_indicator_summary">Indicate saved servers which are also found by Discovery.\nRequires App restart.</string>
|
||||
</resources>
|
||||
|
|
@ -11,7 +11,18 @@
|
|||
|
||||
<Preference
|
||||
app:fragment="com.gaurav.avnc.ui.prefs.ImportExportFragment"
|
||||
app:defaultValue="false"
|
||||
app:title="@string/pref_import_export" />
|
||||
|
||||
<PreferenceCategory
|
||||
app:icon="@drawable/ic_bug"
|
||||
app:title="@string/pref_debugging">
|
||||
|
||||
<Preference
|
||||
app:fragment="com.gaurav.avnc.ui.prefs.LogsFragment"
|
||||
app:title="@string/pref_logs" />
|
||||
|
||||
<Preference
|
||||
app:fragment="com.gaurav.avnc.ui.prefs.KeyCodeMapFragment"
|
||||
app:title="@string/pref_keycode_map" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
Loading…
Add table
Reference in a new issue