[Android] Add the user changed settings to the logs
Nicolas Pomepuy
git at videolan.org
Wed Sep 8 06:52:31 UTC 2021
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Tue Sep 7 09:15:04 2021 +0200| [ce93b882c6a186e95e754b4b9d0d63eb9a2efdb0] | committer: Nicolas Pomepuy
Add the user changed settings to the logs
> https://code.videolan.org/videolan/vlc-android/commit/ce93b882c6a186e95e754b4b9d0d63eb9a2efdb0
---
.../src/org/videolan/vlc/DebugLogService.kt | 12 +++
.../vlc/gui/preferences/search/PreferenceParser.kt | 92 ++++++++++++++++++----
2 files changed, 88 insertions(+), 16 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt b/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
index dd6bfc651..681a268a7 100644
--- a/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
@@ -29,6 +29,7 @@ import android.content.Intent
import android.content.ServiceConnection
import android.os.*
import android.text.format.DateFormat
+import android.util.Log
import androidx.core.app.NotificationCompat
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.resources.AndroidDevices
@@ -39,6 +40,7 @@ import org.videolan.tools.Logcat
import org.videolan.tools.getContextWithLocale
import org.videolan.vlc.gui.DebugLogActivity
import org.videolan.vlc.gui.helpers.NotificationHelper
+import org.videolan.vlc.gui.preferences.search.PreferenceParser
import java.io.*
import java.util.*
@@ -176,7 +178,17 @@ class DebugLogService : Service(), Logcat.Callback, Runnable {
output = OutputStreamWriter(fos)
bw = BufferedWriter(output)
synchronized(this) {
+ bw.write("____________________________\r\n")
+ bw.write("Useful info\r\n")
+ bw.write("____________________________\r\n")
bw.write("App version: ${BuildConfig.VLC_VERSION_CODE} / ${BuildConfig.VLC_VERSION_NAME}\r\n")
+ try {
+ bw.write("Changed settings:\r\n${PreferenceParser.getChangedPrefsString(this)}\r\n")
+ } catch (e: Exception) {
+ bw.write("Cannot retrieve changed settings\r\n")
+ bw.write(Log.getStackTraceString(e))
+ }
+ bw.write("____________________________\r\n")
for (line in logList) {
bw.write(line)
bw.newLine()
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/preferences/search/PreferenceParser.kt b/application/vlc-android/src/org/videolan/vlc/gui/preferences/search/PreferenceParser.kt
index 3bc575c3b..58c95ccfd 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/preferences/search/PreferenceParser.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/preferences/search/PreferenceParser.kt
@@ -26,17 +26,23 @@ package org.videolan.vlc.gui.preferences.search
import android.content.Context
import android.content.ContextWrapper
+import android.content.SharedPreferences
import android.content.res.XmlResourceParser
import android.os.Parcelable
-import android.util.Log
+import androidx.annotation.XmlRes
import kotlinx.android.parcel.Parcelize
import org.videolan.tools.Settings
import org.videolan.tools.wrap
-import org.videolan.vlc.BuildConfig
import org.videolan.vlc.R
object PreferenceParser {
+ /**
+ * Parses all the preferences available in the app.
+ * @param context the context to be used to retrieve the preferences
+ *
+ * @return a list of [PreferenceItem]
+ */
fun parsePreferences(context: Context): ArrayList<PreferenceItem> {
val result = ArrayList<PreferenceItem>()
arrayOf(R.xml.preferences, R.xml.preferences_adv, R.xml.preferences_audio, R.xml.preferences_casting, R.xml.preferences_perf, R.xml.preferences_subtitles, R.xml.preferences_ui, R.xml.preferences_video).forEach {
@@ -45,7 +51,59 @@ object PreferenceParser {
return result
}
- private fun parsePreferences(context: Context, id: Int): ArrayList<PreferenceItem> {
+ /**
+ * Compares the preference list with the set settings to get the list of the changed settings by the user
+ * @param context the context to be used to retrieve the preferences
+ *
+ * @return a list of changed settings in the form a of pair of the key and the value
+ */
+ private fun getAllChangedPrefs(context: Context): ArrayList<Pair<String, Any>> {
+ val allPrefs = parsePreferences(context)
+ val allSettings = Settings.getInstance(context).all
+ val changedSettings = ArrayList<Pair<String, Any>>()
+ allPrefs.forEach { pref ->
+ allSettings.forEach { setting ->
+ if (pref.key == setting.key) {
+ setting.value?.let {
+ if (!isSame(it, pref.defaultValue)) changedSettings.add(Pair(pref.key, it))
+ }
+ }
+ }
+ }
+ return changedSettings
+ }
+
+ /**
+ * Compares a [SharedPreferences] item value to a retrieved String from the preference parsing
+ * @param settingValue the found preference value
+ * @param defaultValue the defaultValue [String] found by parsing the pref xml
+ *
+ * @return true if values are considered to be the same
+ */
+ private fun isSame(settingValue: Any, defaultValue: String?) = when {
+ defaultValue == null -> false
+ settingValue is Boolean -> settingValue.toString() == defaultValue
+ else -> settingValue == defaultValue
+ }
+
+ /**
+ * Get a string describing the preferences changed by the user
+ * @param context the context to be used to retrieve the preferences
+ *
+ * @return a string of all the changed preferences
+ */
+ fun getChangedPrefsString(context: Context) = buildString {
+ getAllChangedPrefs(context).forEach { append("\t* ${it.first} -> ${it.second}\r\n") }
+ }
+
+ /**
+ * Parse a preference xml resource to get a list of [PreferenceItem]
+ * @param context the context to be used to retrieve the preferences
+ * @param id the xml resource id to parse
+ *
+ * @return all the parsed items in the form of a [PreferenceItem] list
+ */
+ private fun parsePreferences(context: Context, @XmlRes id: Int): ArrayList<PreferenceItem> {
var category = ""
var categoryEng = ""
val result = ArrayList<PreferenceItem>()
@@ -69,10 +127,10 @@ object PreferenceParser {
val titleEng = getValue(englishContext, parser, namespace, "title")
var summary = getValue(context, parser, namespace, "summary")
var summaryEng = getValue(englishContext, parser, namespace, "summary")
+ val defaultValue = getValue(context, parser, namespace, "defaultValue")
if (summary.contains("%s") && element == "ListPreference") {
//get the current value for the string substitution
try {
- val defaultValue = getValue(context, parser, namespace, "defaultValue")
val rawValue = Settings.getInstance(context).getString(key, defaultValue) ?: ""
val entriesId = parser.getAttributeResourceValue(namespace, "entries", -1)
val entryValuesId = parser.getAttributeResourceValue(namespace, "entryValues", -1)
@@ -82,7 +140,7 @@ object PreferenceParser {
} catch (e: Exception) {
}
}
- if (key.isNotBlank()) result.add(PreferenceItem(key, id, title, summary, titleEng, summaryEng, category, categoryEng))
+ if (key.isNotBlank()) result.add(PreferenceItem(key, id, title, summary, titleEng, summaryEng, category, categoryEng, defaultValue))
}
}
eventType = parser.next()
@@ -90,6 +148,15 @@ object PreferenceParser {
return result
}
+ /**
+ * Get the value of an xml node
+ * @param context the context to be used to retrieve the value. This context can be localized in English to retrieve the strings
+ * @param parser the [XmlResourceParser] to use to parse the attributes
+ * @param namespace the namespace to use to parse the attributes
+ * @param node the node to be parsed
+ *
+ * @return the parsed value
+ */
private fun getValue(context: Context, parser: XmlResourceParser, namespace: String, node: String): String {
try {
val titleResId = parser.getAttributeResourceValue(namespace, node, -1)
@@ -102,17 +169,10 @@ object PreferenceParser {
}
return ""
}
-
- private fun getSummary (context: Context, parser: XmlResourceParser, namespace: String, node: String, defaultValue:String, key:String):String {
-
- val value = getValue(context, parser, namespace, node)
- if (value.contains("%s")) if (BuildConfig.DEBUG) Log.d(this::class.java.simpleName, "Found string replacement for $key")
- return if (value.contains("%s"))
- value.replace("%s", Settings.getInstance(context).getString(key, defaultValue) ?: "")
- else value
-
- }
}
+/**
+ * Object describing a [androidx.preference.Preference] with useful values to search / display them
+ */
@Parcelize
-data class PreferenceItem(val key: String, val parentScreen: Int, val title: String, val summary: String, val titleEng:String, val summaryEng: String, val category: String, val categoryEng: String) : Parcelable
\ No newline at end of file
+data class PreferenceItem(val key: String, val parentScreen: Int, val title: String, val summary: String, val titleEng:String, val summaryEng: String, val category: String, val categoryEng: String, val defaultValue:String?) : Parcelable
\ No newline at end of file
More information about the Android
mailing list