Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 209 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
* SPDX-License-Identifier: apache2
*/


import groovy.xml.Namespace

plugins {
id 'com.android.application'
id 'androidx.navigation.safeargs'
Expand Down Expand Up @@ -169,6 +172,209 @@ dependencies {
implementation "com.squareup.moshi:moshi-adapters:1.15.2"
}

configurations.implementation {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}

tasks.register('generatePrefsDoc') {
def resXmlDir = file("$projectDir/src/main/res/xml")
def stringsFile = file("$projectDir/src/main/res/values/strings.xml")
def arraysFile = file("$projectDir/src/main/res/values/arrays.xml")
def outputFile = file("$projectDir/../docs/preferences.md")
def jsonOutputFileDoc = file("$projectDir/../docs/config.json")
def jsonOutputFileResources = file("$projectDir/src/main/res/raw/config.json")

doLast {
def parseStringsXml = { File xmlFile ->
def parser = new XmlSlurper()
def root = parser.parse(xmlFile)
def map = [:]
root.string.each { s ->
map[s.@name.toString()] = s.text().trim()
}
return map
}

def parseArraysXml = { File xmlFile ->
if (!xmlFile.exists()) return [:]
def parser = new XmlSlurper()
def root = parser.parse(xmlFile)
def map = [:]
root.array.each { arr ->
def name = arr.@name.toString()
map[name] = arr.item.collect { it.text().trim() }
}
return map
}

def stringsMap = stringsFile.exists() ? parseStringsXml(stringsFile) : [:]
def arraysMap = arraysFile.exists() ? parseArraysXml(arraysFile) : [:]

def resolveRef = { String ref ->
if (!ref) return ""
if (ref.startsWith("@string/")) {
def key = ref.substring(8)
return stringsMap.get(key, ref)
} else if (ref.startsWith("@array/")) {
def key = ref.substring(7)
def arr = arraysMap.get(key)
return arr ? arr.join(", ") : ref
}
return ref
}

def getAttrValue = { attrs, List<String> keys ->
for (k in keys) {
if (attrs.containsKey(k)) {
return attrs[k]
}
}
return null
}

def md = new StringBuilder("# Preferences Documentation\n\n")
def jsonList = [] // full JSON list to serialize

resXmlDir.eachFile { xmlFile ->
if (xmlFile.name.toLowerCase().startsWith("preference") && xmlFile.name.endsWith(".xml")) {
def logicalName = xmlFile.name
.replaceFirst(/^preference_/, '')
.replaceFirst(/\.xml$/, '')
.replaceAll(/_/, ' ')
.capitalize()

md.append("## ${logicalName}\n\n")

def xml = new XmlSlurper(false, false).parse(xmlFile)
def categories = [:]


def processPrefs
processPrefs = { node, categoryName = null ->
def attrs = node.attributes()
def prefType
switch (node.name()) {
case "SwitchPreferenceCompat":
case "SwitchPreference":
case "CheckBoxPreference":
prefType = "boolean"
break
case "EditTextPreference":
case "ListPreference":
prefType = "string"
break
case "SeekBarPreference":
prefType = "int"
break
case "MultiSelectListPreference":
prefType = "set"
break
default:
prefType = "string"
}
if (node.name() == "PreferenceCategory") {
def catTitleRaw = getAttrValue(attrs, ['android:title', 'app:title', 'title'])
def catSummaryRaw = getAttrValue(attrs, ['android:summary', 'app:summary', 'summary'])
def catTitle = resolveRef(catTitleRaw) ?: "Unnamed Category"
def catSummary = resolveRef(catSummaryRaw) ?: ""

if (!categories.containsKey(catTitle)) {
categories[catTitle] = [summary: catSummary, prefs: []]
}

node.children().each { child ->
processPrefs(child, catTitle)
}
} else if (node.name() == "PreferenceScreen") {
node.children().each { child ->
processPrefs(child, categoryName)
}
} else {
def keyRaw = getAttrValue(attrs, ['android:key', 'app:key', 'key'])
if (keyRaw) {
def titleRaw = getAttrValue(attrs, ['android:title', 'app:title', 'title'])
def summaryRaw = getAttrValue(attrs, ['android:summary', 'app:summary', 'summary'])
def defaultValueRaw = getAttrValue(attrs, ['android:defaultValue', 'app:defaultValue', 'defaultValue'])

def title = resolveRef(titleRaw)
def summary = resolveRef(summaryRaw)
def defaultValue = resolveRef(defaultValueRaw)

if (categoryName == null) {
categoryName = "General Preferences"
if (!categories.containsKey(categoryName)) {
categories[categoryName] = [summary: "", prefs: []]
}
}

categories[categoryName].prefs << [
key : keyRaw,
title : title,
nodeName : node.name(),
summary : summary,
defaultValue: defaultValue,
type : prefType
]
}
}
}

processPrefs(xml)

def jsonEntry = [
setting: logicalName.toLowerCase().replaceAll(" ", "_"),
categories: []
]

categories.each { catName, info ->
md.append("### ${catName}\n\n")
if (info.summary) {
md.append("_${info.summary}_\n\n")
}

md.append("| Key | Title | Summary | Default Value |\n")
md.append("| --- | ----- | ------- | ------------- |\n")
info.prefs.each { p ->
def escTitle = p.title?.replaceAll("\\|", "\\\\|") ?: ""
def escSummary = p.summary?.replaceAll("\\|", "\\\\|") ?: ""
def escDefault = p.defaultValue ? "`${p.defaultValue.replaceAll("\\|", "\\\\|")}`" : ""
md.append("| **${p.key}** | ${escTitle} | ${escSummary} | ${escDefault} |\n")
}
md.append("\n")
jsonEntry.categories += info.prefs
.findAll { p -> p.nodeName != "Preference" && p.key?.trim() }
.groupBy { catName.replaceAll(" ", "_").toLowerCase() }
.collect { cat, prefs ->
[
name: cat,
preferences: prefs.collect { p -> [key: p.key, value: null, type: p.type] }
]
}
.findAll { it.preferences }
}

jsonList << jsonEntry
}
}

outputFile.parentFile.mkdirs()
outputFile.text = md.toString()

jsonList.add([
metadata: [
version: android.defaultConfig.versionName,
code : android.defaultConfig.versionCode,
gitHash: getGitHash()
]
])
def json = groovy.json.JsonOutput.prettyPrint(
groovy.json.JsonOutput.toJson(jsonList)
)


jsonOutputFileDoc.text = json
jsonOutputFileResources.text = json

println "Preferences Markdown generated at: ${outputFile.path}"
println "Preferences JSON generated at: ${jsonOutputFileDoc.path}"
}
}

preBuild.dependsOn(tasks.named("generatePrefsDoc"))
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ public List<CellInformation> getNeighbourCellInformation() {
@SuppressLint("ObsoleteSdkInt")
public List<Point> getCellInformationPoint() {
List<Point> points = new ArrayList<>();
boolean nc = spg.getSharedPreference(SPType.logging_sp).getBoolean("log_neighbour_cells", false);
boolean nc = spg.getSharedPreference(SPType.LOGGING).getBoolean("log_neighbour_cells", false);
for (CellInformation ci_ : ci) {
// check if want to log neighbour cells and skip non registered cells
if (!nc) {
Expand Down Expand Up @@ -612,7 +612,7 @@ public Point getLocationPoint() {
point.time(System.currentTimeMillis(), WritePrecision.MS);
// falling back to fake if no location is available is not the best solution.
// We should ask the user / add configuration what to do
if (spg.getSharedPreference(SPType.logging_sp).getBoolean("fake_location", false) || li == null) {
if (spg.getSharedPreference(SPType.LOGGING).getBoolean("fake_location", false) || li == null) {
point.addField("longitude", 13.3143266);
point.addField("latitude", 52.5259678);
point.addField("altitude", 34.0);
Expand Down Expand Up @@ -719,7 +719,7 @@ public Point getBatteryInformationPoint() {
*/
@SuppressLint("ObsoleteSdkInt")
public Map<String, String> getTagsMap() {
String tags = spg.getSharedPreference(SPType.logging_sp).getString("tags", "").strip().replace(" ", "");
String tags = spg.getSharedPreference(SPType.LOGGING).getString("tags", "").strip().replace(" ", "");
Map<String, String> tags_map = Collections.emptyMap();
if (!tags.isEmpty()) {
try {
Expand All @@ -731,13 +731,13 @@ public Map<String, String> getTagsMap() {
DeviceInformation di = getDeviceInformation();

Map<String, String> tags_map_modifiable = new HashMap<>(tags_map);
tags_map_modifiable.put("measurement_name", spg.getSharedPreference(SPType.logging_sp).getString("measurement_name", "OMNT"));
tags_map_modifiable.put("measurement_name", spg.getSharedPreference(SPType.LOGGING).getString("measurement_name", "OMNT"));
tags_map_modifiable.put("manufacturer", di.getManufacturer());
tags_map_modifiable.put("model", di.getModel());
tags_map_modifiable.put("sdk_version", String.valueOf(di.getAndroidSDK()));
tags_map_modifiable.put("android_version", di.getAndroidRelease());
tags_map_modifiable.put("security_patch", di.getSecurityPatchLevel());
String device = spg.getSharedPreference(SPType.default_sp).getString("device_name", "null").strip();
String device = spg.getSharedPreference(SPType.MAIN).getString("device_name", "null").strip();
//if(device.equals("null")); TODO handle this
tags_map_modifiable.put("device", device);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ private CardView get_cell_card_view() {
List<CellInformation> cil = dp.getCellInformation();
int cell = 1;
for (CellInformation ci : cil) {
if (!spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false) && !ci.isRegistered()) {
if (!spg.getSharedPreference(SPType.MAIN).getBoolean("show_neighbour_cells", false) && !ci.isRegistered()) {
continue;
}
TableRow title = rowBuilder("Cell " + cell, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,19 @@ public void open_write_api() {
writeApi.listenEvents(BackpressureEvent.class, value -> Log.d(TAG, "open_write_api: Could not write to InfluxDBv2 due to backpressure"));
writeApi.listenEvents(WriteSuccessEvent.class, value -> {
//Log.d(TAG, "open_write_api: Write to InfluxDBv2 was successful");
if ( spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) {
if ( spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) {
gv.getLog_status().setColorFilter(Color.argb(255, 0, 255, 0));
}
});
writeApi.listenEvents(WriteErrorEvent.class, value -> {
Log.d(TAG, "open_write_api: Could not write to InfluxDBv2 due to error");
if ( spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) {
if ( spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) {
gv.getLog_status().setColorFilter(Color.argb(255, 255, 0, 0));
}
});
writeApi.listenEvents(WriteRetriableErrorEvent.class, value -> {
Log.d(TAG, "open_write_api: Could not write to InfluxDBv2 due to retriable error");
if ( spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) {
if ( spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) {
gv.getLog_status().setColorFilter(Color.argb(255, 255, 0, 0));
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ private InfluxdbConnections() {
public static InfluxdbConnection getRicInstance(Context context) {
if (ric == null) {
SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(context);
String url = spg.getSharedPreference(SPType.logging_sp).getString("influx_URL", "");
String org = spg.getSharedPreference(SPType.logging_sp).getString("influx_org", "");
String bucket = spg.getSharedPreference(SPType.logging_sp).getString("influx_bucket", "");
String token = spg.getSharedPreference(SPType.logging_sp).getString("influx_token", "");
String url = spg.getSharedPreference(SPType.LOGGING).getString("influx_URL", "");
String org = spg.getSharedPreference(SPType.LOGGING).getString("influx_org", "");
String bucket = spg.getSharedPreference(SPType.LOGGING).getString("influx_bucket", "");
String token = spg.getSharedPreference(SPType.LOGGING).getString("influx_token", "");
if (url.isEmpty() || org.isEmpty() || bucket.isEmpty() || token.isEmpty()) {
Log.e(TAG, "Influx parameters incomplete, can't setup logging");
// if we are an UI thread we make a toast, if not logging have to be enough
Expand Down
Loading