Added ability to view logs

This commit is contained in:
Gaurav Ujjwal 2021-04-08 21:26:51 +05:30
parent f0625ebc18
commit f12ed7ef2d
6 changed files with 215 additions and 2 deletions

View 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)
}

View 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()
}
}

View 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>

View 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>

View file

@ -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>

View file

@ -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>