diff --git a/.github/PULL_REQUEST_TEMPLATE/default.md b/.github/PULL_REQUEST_TEMPLATE/default.md new file mode 100644 index 0000000..8472dda --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/default.md @@ -0,0 +1,20 @@ +--- +name: Defaukt Pull Request +about: Use this template for creating PR request. +title: "PR_TITLE" +labels: +assignees: "" +--- +## Added + +## Changed + +## Fixed + +## Removed + +## Breaking Changes + +## Related Issues + +## Screenshots (if applicable) \ No newline at end of file diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 5236833..b6f39d9 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -52,7 +52,7 @@ jobs: RELEASE_KEY_PASSWORD: ${{ secrets.KEY_PW }} run: ./gradlew assembleRelease --stacktrace - - name: Build Release APK + - name: Build Debug APK env: ENCODED_STRING: ${{ secrets.KEYSTORE }} RELEASE_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PW }} @@ -81,4 +81,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: omnt-${{ steps.releaseApk.outputs.sha_short }} - path: ./upload \ No newline at end of file + path: ./upload diff --git a/app/build.gradle b/app/build.gradle index 04a345e..b4a2c76 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,11 +4,10 @@ * * SPDX-License-Identifier: apache2 */ - plugins { id 'com.android.application' id 'androidx.navigation.safeargs' - id("org.spdx.sbom") version "0.8.0" + id("org.spdx.sbom") version "0.9.0" } def keystoreProperties = new Properties() @@ -60,8 +59,8 @@ android { applicationId "de.fraunhofer.fokus.OpenMobileNetworkToolkit" minSdk 31 targetSdk 36 - versionCode 6 - versionName "0.6" + versionCode 7 + versionName "0.7" resValue("string", "git_hash", getGitHash()) testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -127,12 +126,12 @@ spdxSbom { } dependencies { - def work_version = "2.10.1" + def work_version = "2.11.0" def room_version = "2.7.1" testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.2.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' + androidTestImplementation 'androidx.test.ext:junit:1.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0' annotationProcessor "androidx.room:room-compiler:$room_version" androidTestImplementation "androidx.work:work-testing:$work_version" @@ -142,33 +141,236 @@ dependencies { implementation "androidx.work:work-gcm:$work_version" implementation "androidx.work:work-multiprocess:$work_version" implementation 'com.google.android.flexbox:flexbox:3.0.0' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.7.3" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.10.2" implementation 'androidx.preference:preference:1.2.1' implementation "androidx.room:room-runtime:$room_version" implementation 'androidx.appcompat:appcompat:1.7.1' - implementation 'com.google.guava:guava:33.4.0-jre' - implementation 'androidx.concurrent:concurrent-futures:1.2.0' - implementation 'androidx.activity:activity:1.10.1' - implementation 'androidx.fragment:fragment:1.8.8' - implementation 'com.google.android.material:material:1.12.0' + implementation 'com.google.guava:guava:33.5.0-jre' + implementation 'androidx.concurrent:concurrent-futures:1.3.0' + implementation 'androidx.activity:activity:1.12.0' + implementation 'androidx.fragment:fragment:1.8.9' + implementation 'com.google.android.material:material:1.13.0' implementation 'androidx.constraintlayout:constraintlayout:2.2.1' - implementation 'androidx.navigation:navigation-fragment:2.9.0' - implementation 'androidx.navigation:navigation-ui:2.9.0' + implementation 'androidx.navigation:navigation-fragment:2.9.6' + implementation 'androidx.navigation:navigation-ui:2.9.6' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.4.0' implementation 'androidx.recyclerview:recyclerview-selection:1.2.0' - implementation 'com.influxdb:influxdb-client-java:7.3.0' + implementation 'com.influxdb:influxdb-client-java:7.4.0' implementation 'com.google.android.gms:play-services-location:21.3.0' implementation 'com.github.anastr:speedviewlib:1.6.1' implementation "androidx.viewpager2:viewpager2:1.1.0" - implementation "androidx.compose.material3:material3:1.3.2" - implementation "com.hivemq:hivemq-mqtt-client:1.3.4" - implementation "androidx.compose.material3:material3:1.3.2" + implementation "androidx.compose.material3:material3:1.4.0" + implementation "com.hivemq:hivemq-mqtt-client:1.3.10" + implementation "androidx.compose.material3:material3:1.4.0" implementation "com.squareup.moshi:moshi:1.15.2" - implementation "com.squareup.moshi:moshi-adapters:1.8.0" + implementation "com.squareup.moshi:moshi-adapters:1.15.2" +} + + +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 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}" + } } -configurations.implementation { - exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' -} \ No newline at end of file +preBuild.dependsOn(tasks.named("generatePrefsDoc")) \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 834cddb..cd98672 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,7 @@ + @@ -146,6 +147,19 @@ + + + + + + + + + + + getNeighbourCellInformation() { @SuppressLint("ObsoleteSdkInt") public List getCellInformationPoint() { List 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) { @@ -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); @@ -719,7 +719,7 @@ public Point getBatteryInformationPoint() { */ @SuppressLint("ObsoleteSdkInt") public Map getTagsMap() { - String tags = spg.getSharedPreference(SPType.logging_sp).getString("tags", "").strip().replace(" ", ""); + String tags = spg.getSharedPreference(SPType.LOGGING).getString("tags", "").strip().replace(" ", ""); Map tags_map = Collections.emptyMap(); if (!tags.isEmpty()) { try { @@ -731,13 +731,13 @@ public Map getTagsMap() { DeviceInformation di = getDeviceInformation(); Map 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) { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java index fdf6d88..95a236f 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java @@ -489,7 +489,7 @@ private CardView get_cell_card_view() { List 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, ""); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnection.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnection.java index 7ca858e..9ed37f0 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnection.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnection.java @@ -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)); } }); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnections.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnections.java index 931b14e..154c2b9 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnections.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/InfluxdbConnections.java @@ -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 diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/Worker/InfluxDB2xUploadWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/Worker/InfluxDB2xUploadWorker.java index 5511532..0782ff8 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/Worker/InfluxDB2xUploadWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/InfluxDB2x/Worker/InfluxDB2xUploadWorker.java @@ -65,17 +65,17 @@ public Result doWork() { } BufferedReader br; try { - br = new BufferedReader(new FileReader(input.getParameter().getLineProtocolFile())); + br = new BufferedReader(new FileReader(input.getParameter().getLineProtocolFilePath())); } catch (FileNotFoundException | NullPointerException e) { Log.d(TAG,e.toString()); return Result.failure(output); } List points = br.lines().collect(Collectors.toList()); try { - Log.d(TAG, String.format("doWork: uploading %s", input.getParameter().getLineProtocolFile())); + Log.d(TAG, String.format("doWork: uploading %s", input.getParameter().getLineProtocolFilePath())); influx.writeRecords(points); } catch (IOException e) { - Log.d(TAG, String.format("doWork: upload of %s failed!", input.getParameter().getLineProtocolFile())); + Log.d(TAG, String.format("doWork: upload of %s failed!", input.getParameter().getLineProtocolFilePath())); return Result.failure(output); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/Inputs.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/Inputs.java index 12203af..bda00df 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/Inputs.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/Inputs.java @@ -115,7 +115,6 @@ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(sequenceUUID); dest.writeString(measurementUUID); dest.writeString(testUUID); - dest.writeParcelable(parameter, flags); } public Data.Builder getInputAsDataBuilder(int i, String packageName) { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java index 8ff211b..69ee398 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java @@ -74,7 +74,7 @@ public class Iperf3Fragment extends Fragment { private TextInputEditText duration; private TextInputEditText interval; private TextInputEditText bytes; - private TextInputEditText streams; + private TextInputEditText parallel; private TextInputEditText cport; @@ -132,7 +132,7 @@ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { consumer.accept(charSequence.toString()); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(name, charSequence.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(name, charSequence.toString()).apply(); } @Override @@ -151,7 +151,7 @@ private void setupTextWatchers() { duration.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setTime(Integer.parseInt("0"+s)), Iperf3Parameter.TIME)); interval.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setInterval(Double.parseDouble("0"+s)), Iperf3Parameter.INTERVAL)); bytes.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setBytes(s), Iperf3Parameter.BYTES)); - streams.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setParallel(Integer.parseInt("0"+s)), Iperf3Parameter.PARALLEL)); + parallel.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setParallel(Integer.parseInt("0"+s)), Iperf3Parameter.PARALLEL)); cport.addTextChangedListener(createTextWatcher(s -> iperf3Input.getParameter().setCport(Integer.parseInt("0"+s) ), Iperf3Parameter.CPORT)); } @@ -161,8 +161,8 @@ private void setupTextWatchers() { * @param key */ private void setTextFromSharedPreferences(TextInputEditText editText, String key) { - if (spg.getSharedPreference(SPType.iperf3_sp).contains(key)) { - editText.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(key, "")); + if (spg.getSharedPreference(SPType.IPERF3).contains(key)) { + editText.setText(spg.getSharedPreference(SPType.IPERF3).getString(key, "")); } } @@ -256,7 +256,7 @@ private void setTextsFromSharedPreferences(){ setTextFromSharedPreferences(duration, Iperf3Parameter.TIME); setTextFromSharedPreferences(interval, Iperf3Parameter.INTERVAL); setTextFromSharedPreferences(bytes, Iperf3Parameter.BYTES); - setTextFromSharedPreferences(streams, Iperf3Parameter.STREAMS); + setTextFromSharedPreferences(parallel, Iperf3Parameter.PARALLEL); setTextFromSharedPreferences(cport, Iperf3Parameter.CPORT); } @@ -311,8 +311,8 @@ public void onClick(View view) { iperf3Input.getParameter().updatePaths(); iperf3Input.setTimestamp(new Timestamp(System.currentTimeMillis())); - File logFile = new File(iperf3Input.getParameter().getLogfile()); - File rawPath = new File(Iperf3Parameter.rawDirPath); + File logFile = new File(iperf3Input.getParameter().getRawLogFilePath()); + File rawPath = new File(iperf3Input.getParameter().getRawDirPath()); if(!rawPath.exists()) { rawPath.mkdirs(); @@ -347,7 +347,7 @@ public void onClick(View view) { duration = view.findViewById(R.id.iperf3_duration); interval = view.findViewById(R.id.iperf3_interval); bytes = view.findViewById(R.id.iperf3_bytes); - streams = view.findViewById(R.id.iperf3_streams); + parallel = view.findViewById(R.id.iperf3_parallel); cport = view.findViewById(R.id.iperf3_cport); @@ -368,7 +368,7 @@ public void onClick(View view) { setupTextWatchers(); setTextsFromSharedPreferences(); try { - switch (Iperf3Parameter.Iperf3Mode.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Parameter.MODE, String.valueOf(Iperf3Parameter.Iperf3Mode.UNDEFINED)))){ + switch (Iperf3Parameter.Iperf3Mode.valueOf(spg.getSharedPreference(SPType.IPERF3).getString(Iperf3Parameter.MODE, String.valueOf(Iperf3Parameter.Iperf3Mode.UNDEFINED)))){ case CLIENT: updateModeState(modeClient, modeServer, Iperf3Parameter.Iperf3Mode.CLIENT); break; @@ -379,14 +379,14 @@ public void onClick(View view) { default: modeClient.setBackgroundColor(Color.TRANSPARENT); modeServer.setBackgroundColor(Color.TRANSPARENT); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Parameter.MODE, Iperf3Parameter.Iperf3Mode.UNDEFINED.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(Iperf3Parameter.MODE, Iperf3Parameter.Iperf3Mode.UNDEFINED.toString()).apply(); break; } } catch (IllegalArgumentException e) { Log.e(TAG, "onCreateView: ", e); } try { - switch (Iperf3Parameter.Iperf3Protocol.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Parameter.PROTOCOL, Iperf3Parameter.Iperf3Protocol.UNDEFINED.toString()))){ + switch (Iperf3Parameter.Iperf3Protocol.valueOf(spg.getSharedPreference(SPType.IPERF3).getString(Iperf3Parameter.PROTOCOL, Iperf3Parameter.Iperf3Protocol.UNDEFINED.toString()))){ case TCP: updateProtocolState(protocolTCP, protocolUDP, Iperf3Parameter.Iperf3Protocol.TCP); break; @@ -397,14 +397,14 @@ public void onClick(View view) { default: protocolTCP.setBackgroundColor(Color.TRANSPARENT); protocolUDP.setBackgroundColor(Color.TRANSPARENT); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Parameter.PROTOCOL, Iperf3Parameter.Iperf3Protocol.UNDEFINED.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(Iperf3Parameter.PROTOCOL, Iperf3Parameter.Iperf3Protocol.UNDEFINED.toString()).apply(); break; } } catch (IllegalArgumentException e) { Log.e(TAG, "onCreateView: ", e); } try { - switch (Iperf3Parameter.Iperf3Direction.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Parameter.DIRECTION, Iperf3Parameter.Iperf3Direction.UNDEFINED.toString()))) { + switch (Iperf3Parameter.Iperf3Direction.valueOf(spg.getSharedPreference(SPType.IPERF3).getString(Iperf3Parameter.DIRECTION, Iperf3Parameter.Iperf3Direction.UNDEFINED.toString()))) { case UP: updateDirectionState(directionUp, directionDown, directonBidir, Iperf3Parameter.Iperf3Direction.UP); break; @@ -495,14 +495,14 @@ private void updateModeState(MaterialButton activeButton, MaterialButton inactiv activeButton.setBackgroundColor(getResources().getColor(R.color.purple_500, null)); inactiveButton.setBackgroundColor(Color.TRANSPARENT); iperf3Input.getParameter().setMode(protocol); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Parameter.MODE, protocol.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(Iperf3Parameter.MODE, protocol.toString()).apply(); } private void updateProtocolState(MaterialButton activeButton, MaterialButton inactiveButton, Iperf3Parameter.Iperf3Protocol protocol) { activeButton.setBackgroundColor(getResources().getColor(R.color.purple_500, null)); inactiveButton.setBackgroundColor(Color.TRANSPARENT); iperf3Input.getParameter().setProtocol(protocol); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Parameter.PROTOCOL, protocol.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(Iperf3Parameter.PROTOCOL, protocol.toString()).apply(); } private void updateDirectionState(MaterialButton activeButton, MaterialButton inactiveButton1, MaterialButton inactiveButton2, Iperf3Parameter.Iperf3Direction direction) { @@ -510,6 +510,6 @@ private void updateDirectionState(MaterialButton activeButton, MaterialButton in inactiveButton1.setBackgroundColor(Color.TRANSPARENT); inactiveButton2.setBackgroundColor(Color.TRANSPARENT); iperf3Input.getParameter().setDirection(direction); - spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Parameter.DIRECTION, direction.toString()).apply(); + spg.getSharedPreference(SPType.IPERF3).edit().putString(Iperf3Parameter.DIRECTION, direction.toString()).apply(); } } \ No newline at end of file diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java index 9caaf6e..4ba77e2 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java @@ -11,7 +11,6 @@ import android.annotation.SuppressLint; import android.content.Context; -import androidx.work.Constraints; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkContinuation; import androidx.work.WorkManager; @@ -19,9 +18,7 @@ import androidx.work.multiprocess.RemoteWorkManager; -import java.util.ArrayList; import java.util.Arrays; -import java.util.concurrent.TimeUnit; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.Worker.InfluxDB2xUploadWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.Iperf3Input; @@ -73,7 +70,7 @@ public Iperf3Executor(Iperf3Input iperf3Input, Context context){ this.remoteWorkContinuation = this.remoteWorkManager.beginWith(Arrays.asList(iperf3ExecutorWorker, iperf3MonitorWorker)).then(iPerf3ToLineProtocolWorker); - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)){ + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)){ this.remoteWorkContinuation = remoteWorkContinuation.then(influxDB2xUploadWorker); } } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecutorWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecutorWorker.java index f1af402..79d9962 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecutorWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecutorWorker.java @@ -77,8 +77,8 @@ public Iperf3ExecutorWorker(@NonNull Context context, @NonNull WorkerParameters public ListenableFuture startRemoteWork() { return CallbackToFutureAdapter.getFuture(completer -> { Log.d(TAG, "startRemoteWork: tags: "+this.getTags()); - File logFile = new File(iperf3Input.getParameter().getLogfile()); - File rawPath = new File(Iperf3Parameter.rawDirPath); + File logFile = new File(iperf3Input.getParameter().getRawLogFilePath()); + File rawPath = new File(iperf3Input.getParameter().getRawDirPath()); if(!rawPath.exists()) { rawPath.mkdirs(); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3MonitorWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3MonitorWorker.java index 7a0210a..cf72312 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3MonitorWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3MonitorWorker.java @@ -111,7 +111,7 @@ public Iperf3MonitorWorker(@NonNull Context context, @NonNull WorkerParameters w notificationLayout.setViewVisibility(R.id.notification_direction, GONE); setForegroundAsync(createForegroundInfo(notificationLayout)); - this.pathToFile = iperf3Input.getParameter().getLogfile(); + this.pathToFile = iperf3Input.getParameter().getRawLogFilePath(); Log.d(TAG, "Iperf3MonitorWorker: pathToFile: "+this.pathToFile); this.file = new File(this.pathToFile); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java index 4ab5490..8346e2e 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java @@ -186,11 +186,11 @@ public Result doWork() { } } - File path = new File(Iperf3Parameter.lineProtocolDirPath); + File path = new File(iperf3Input.getParameter().getRawDirPath()); if(!path.exists()){ path.mkdirs(); } - File iperf3File = new File(iperf3Input.getParameter().getLineProtocolFile()); + File iperf3File = new File(iperf3Input.getParameter().getLineProtocolDirPath()); if (!iperf3File.exists()) { try { iperf3File.createNewFile(); @@ -201,7 +201,7 @@ public Result doWork() { FileOutputStream iperf3Stream = null; try { - iperf3Stream = new FileOutputStream(iperf3Input.getParameter().getLineProtocolFile(), true); + iperf3Stream = new FileOutputStream(iperf3Input.getParameter().getLineProtocolDirPath(), true); } catch (FileNotFoundException e) { Toast.makeText(getApplicationContext(), "logfile not created", Toast.LENGTH_SHORT).show(); Log.d(TAG,e.toString()); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java index 54e9cbc..aae6066 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java @@ -65,17 +65,17 @@ public Result doWork() { } BufferedReader br; try { - br = new BufferedReader(new FileReader(iperf3Input.getParameter().getLineProtocolFile())); + br = new BufferedReader(new FileReader(iperf3Input.getParameter().getLineProtocolFilePath())); } catch (FileNotFoundException | NullPointerException e) { Log.d(TAG,e.toString()); return Result.failure(output); } List points = br.lines().collect(Collectors.toList()); try { - Log.d(TAG, String.format("doWork: uploading %s", iperf3Input.getParameter().getLineProtocolFile())); + Log.d(TAG, String.format("doWork: uploading %s", iperf3Input.getParameter().getLineProtocolFilePath())); influx.writeRecords(points); } catch (IOException e) { - Log.d(TAG, String.format("doWork: upload of %s failed!", iperf3Input.getParameter().getLineProtocolFile())); + Log.d(TAG, String.format("doWork: upload of %s failed!", iperf3Input.getParameter().getLineProtocolFilePath())); return Result.failure(output); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java index c3e0b2f..95f027d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java @@ -159,7 +159,7 @@ private StringBuilder getStringBuilder() { s.append(getText(R.string.loggin_notifaction)).append("\n"); s.append("Logging to...\n"); - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_file_log", false)) + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_file_log", false)) s.append("File\n"); if(ic == null) { @@ -262,7 +262,7 @@ private void getInfluxDBConnectionStatus() { } private void handleWriteApiEvent(InfluxdbWriteApiStatus status, String message) { - if (!spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) return; + if (!spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) return; // Check if status has changed if (currentInfluxdbWriteApiStatus == status && @@ -288,7 +288,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { dp = gv.get_dp(); nm = getSystemService(NotificationManager.class); spg = SharedPreferencesGrouper.getInstance(this); - interval = Integer.parseInt(spg.getSharedPreference(SPType.logging_sp).getString("logging_interval", "1000")); + interval = Integer.parseInt(spg.getSharedPreference(SPType.LOGGING).getString("logging_interval", "1000")); @@ -298,11 +298,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { if(Objects.equals(key, "enable_logging")) { if (prefs.getBoolean(key, false)) { Log.d(TAG, "onSharedPreferenceChanged: " + prefs.getBoolean(key, false)); - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) { + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) { // enable influx when enable_logging is enabled setupRemoteInfluxDB(); } - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_file_log", false)){ + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_file_log", false)){ // enable local file log when enable_logging is enabled setupLocalFile(); updateNotification(); @@ -321,7 +321,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(getApplicationContext(), "Please fill all Influx Settings", Toast.LENGTH_LONG).show(); prefs.edit().putBoolean("enable_influx", false).apply(); } else { - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { // only enable influx log, when enable_logging is also enabled setupRemoteInfluxDB(); updateNotification(); @@ -329,7 +329,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { } } else { - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { // only stop influx log, when enable_logging is also enabled stopRemoteInfluxDB(); updateNotification(); @@ -338,13 +338,13 @@ public int onStartCommand(Intent intent, int flags, int startId) { } } else if (Objects.equals(key, "enable_local_file_log")) { if (prefs.getBoolean(key, false)) { - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { // only enable file log, when enable_logging is also enabled setupLocalFile(); updateNotification(); } } else { - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { // only stop file log, when enable_logging is also enabled stopLocalFile(); updateNotification(); @@ -357,19 +357,19 @@ public int onStartCommand(Intent intent, int flags, int startId) { stopLocalInfluxDB(); } } else if (Objects.equals(key, "logging_interval")) { - interval = Integer.parseInt(spg.getSharedPreference(SPType.logging_sp).getString("logging_interval", "1000")); + interval = Integer.parseInt(spg.getSharedPreference(SPType.LOGGING).getString("logging_interval", "1000")); } - }, SPType.logging_sp); + }, SPType.LOGGING); - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) { setupRemoteInfluxDB(); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_file_log", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_file_log", false)) { setupLocalFile(); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_influx_log", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_influx_log", false)) { //TODO } @@ -385,14 +385,14 @@ public int onStartCommand(Intent intent, int flags, int startId) { public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: Stop logging service"); - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)) { stopRemoteInfluxDB(); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_file_log", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_file_log", false)) { stopLocalFile(); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_influx_log", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_local_influx_log", false)) { stopLocalInfluxDB(); } @@ -410,7 +410,7 @@ private ArrayList getPoints() { if (dp != null) { Map tags_map = dp.getTagsMap(); - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("influx_network_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("influx_network_data", false)) { Point p = dp.getNetworkInformationPoint(); if (p.hasFields()) { p.time(time, WritePrecision.MS); @@ -421,7 +421,7 @@ private ArrayList getPoints() { } } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("influx_throughput_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("influx_throughput_data", false)) { Point p = dp.getNetworkCapabilitiesPoint(); if (p.hasFields()) { p.time(time, WritePrecision.MS); @@ -432,7 +432,7 @@ private ArrayList getPoints() { } } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("log_signal_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("log_signal_data", false)) { Point p = dp.getSignalStrengthPoint(); if (p.hasFields()) { p.time(time, WritePrecision.MS); @@ -443,7 +443,7 @@ private ArrayList getPoints() { } } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("log_wifi_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("log_wifi_data", false)) { WifiInformation wifiInformation = dp.getWifiInformation(); if (wifiInformation != null) { Point p = wifiInformation.getWifiInformationPoint(); @@ -457,7 +457,7 @@ private ArrayList getPoints() { } } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("influx_cell_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("influx_cell_data", false)) { List ps = dp.getCellInformationPoint(); for (Point p : ps) { if (p.hasFields()) { @@ -470,7 +470,7 @@ private ArrayList getPoints() { logPoints.addAll(ps); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("influx_ip_address_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("influx_ip_address_data", false)) { List ps = dp.getNetworkInterfaceInformationPoints(); for (Point p : ps) { if (p.hasFields()) { @@ -483,7 +483,7 @@ private ArrayList getPoints() { logPoints.addAll(ps); } - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("influx_battery_data", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("influx_battery_data", false)) { Point bp = dp.getBatteryInformationPoint(); bp.time(time, WritePrecision.MS); bp.addTags(tags_map); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingServiceOnBootReceiver.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingServiceOnBootReceiver.java index 3ab38cf..dce0460 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingServiceOnBootReceiver.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingServiceOnBootReceiver.java @@ -22,8 +22,8 @@ public class LoggingServiceOnBootReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { spg = SharedPreferencesGrouper.getInstance(context); - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("start_logging_on_boot", false) && - spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("start_logging_on_boot", false) && + spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { Intent serviceIntent = new Intent(context, LoggingService.class); context.startService(serviceIntent); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/Iperf3Handler.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/Iperf3Handler.java index c1af87f..fd817f1 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/Iperf3Handler.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/Iperf3Handler.java @@ -63,7 +63,7 @@ public void parsePayload(String payload) throws JSONException { Iperf3RunResult iperf3RunResult = new Iperf3RunResult(iperf3Input.getTestUUID(), -100, false, iperf3Input, new java.sql.Timestamp(System.currentTimeMillis())); iperf3RunResultDao.insert(iperf3RunResult); - File logFile = new File(iperf3Input.getParameter().getLogfile()); + File logFile = new File(iperf3Input.getParameter().getRawLogFilePath()); if(logFile.exists()) { logFile.delete(); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/PingHandler.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/PingHandler.java index bb65c70..15c20f5 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/PingHandler.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/Handler/PingHandler.java @@ -48,7 +48,7 @@ public void parsePayload(String payload) throws JSONException { PingParameter pingParameter = new PingParameter(params, testUUID); if(pingParameter == null) continue; PingInput pingInput = new PingInput(pingParameter, testUUID, sequenceUUID, measurementUUUID,campaignUUID); - File logFile = new File(pingInput.getParameter().getLogfile()); + File logFile = new File(pingInput.getParameter().getLineProtocolFilePath()); if(logFile.exists()) { logFile.delete(); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/MQTTService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/MQTTService.java index 671fb57..5cf1880 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/MQTTService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MQTT/MQTTService.java @@ -9,6 +9,7 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.MQTT; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; @@ -20,32 +21,37 @@ import android.os.Handler; import android.os.IBinder; import android.util.Log; +import android.widget.Toast; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.work.Data; -import androidx.work.ExistingWorkPolicy; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkInfo; import androidx.work.multiprocess.RemoteWorkManager; +import com.hivemq.client.mqtt.MqttClientState; import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.lifecycle.MqttClientConnectedContext; +import com.hivemq.client.mqtt.lifecycle.MqttClientDisconnectedContext; import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; import com.hivemq.client.mqtt.mqtt5.message.connect.connack.Mqtt5ConnAck; import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PayloadFormatIndicator; -import com.influxdb.client.domain.Run; -import org.json.JSONObject; +import org.jetbrains.annotations.NotNull; import java.net.InetSocketAddress; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.EnumSet; import java.util.HashMap; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.CustomEventListener; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.MQTT.Handler.Iperf3Handler; @@ -78,34 +84,107 @@ public IBinder onBind(Intent intent) { private void setupSharedPreferences(){ spg = SharedPreferencesGrouper.getInstance(context); - mqttSP = spg.getSharedPreference(SPType.mqtt_sp); + mqttSP = spg.getSharedPreference(SPType.MQTT); mqttSP.registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> { if(key == null) return; - if (key.equals("mqtt_host")) { - Log.d(TAG, "MQTT Host update: " + sharedPreferences.getString("mqtt_host", "")); - client.disconnect(); - createClient(); - createNotification(); + isEnabled = sharedPreferences.getBoolean("enable_mqtt", false); + switch (key){ + case "mqtt_host": + if(!isEnabled) return; + Log.d(TAG, "mqtt_host: " + sharedPreferences.getString("mqtt_host", "")); + disconnectClient(); + createClient(); + createNotification(); + break; + case "enable_mqtt": + Log.d(TAG, "enable_mqtt: " + isEnabled); + if(!isEnabled && client != null){ + this.onDestroy(); + } + break; } + }); } - - public void createClient(){ - String addressString = mqttSP.getString("mqtt_host", "localhost:1883"); - String host = null; - int port = -1; + private boolean isValidUrl(String addressString) { try { - host = addressString.split(":")[0]; - port = Integer.parseInt(addressString.split(":")[1]); + new java.net.URL(addressString); + return true; } catch (Exception e) { - Log.e(TAG, "createClient: Invalid address string: " + addressString); + return false; + } + } + + private boolean isProtocolIpPort(String addressString) { + // Example: mqtt://192.168.1.1:1883 + String regex = "^[\\d.]+:\\d+$"; + return addressString.matches(regex); + } + + + public String mQTTClientStateToString(MqttClientState state) { + switch (state) { + case CONNECTED: + return "Connected"; + case CONNECTING: + return "Connecting"; + case DISCONNECTED: + return "Disconnected"; + case DISCONNECTED_RECONNECT: + return "Disconnected_Reconnecting"; + case CONNECTING_RECONNECT: + return "Connecting_Reconnecting"; + default: + return "Unknown"; + } + } + + + public void createClient() { + String addressString = mqttSP.getString("mqtt_host", ""); + Log.d(TAG, "createClient: creating client..."); + if (addressString.isBlank()) { + Log.e(TAG, "createClient: MQTT Host is empty"); + spg.getSharedPreference(SPType.MQTT).edit().putBoolean("enable_mqtt", false).apply(); + client = null; return; } - if(host == null || port == -1){ - Log.e(TAG, "createClient: Invalid address string: " + addressString); + + if (!isValidUrl(addressString) && !isProtocolIpPort(addressString)) { + Log.e(TAG, "createClient: MQTT Host is not a valid URL or IP:Port"); + Toast.makeText(context, "MQTT Host is not a valid URL or IP:Port", Toast.LENGTH_SHORT).show(); + spg.getSharedPreference(SPType.MQTT).edit().putBoolean("enable_mqtt", false).apply(); + client = null; return; } - InetSocketAddress address = new InetSocketAddress(host, port); + + String host; + int port; + + try { + if (isProtocolIpPort(addressString)) { + // Case: raw host:port + String[] hostPort = addressString.split(":"); + host = hostPort[0]; + port = Integer.parseInt(hostPort[1]); + } else { + // Case: URL with scheme + URI uri = new URI(addressString); + host = uri.getHost(); + port = uri.getPort() == -1 ? 1883 : uri.getPort(); // default MQTT port + } + } catch (Exception e) { + Log.e(TAG, "createClient: Invalid MQTT address", e); + spg.getSharedPreference(SPType.MQTT).edit().putBoolean("enable_mqtt", false).apply(); + client = null; + return; + } + + InetSocketAddress address = InetSocketAddress.createUnresolved(host, port); + if(client != null){ + disconnectClient(); + client = null; + } client = Mqtt5Client.builder() .identifier(deviceName) .serverAddress(address) @@ -113,37 +192,47 @@ public void createClient(){ .initialDelay(5, TimeUnit.SECONDS) .maxDelay(30, TimeUnit.SECONDS) .applyAutomaticReconnect() - .addConnectedListener(context -> { - Log.i(TAG, "createClient: Connected to MQTT server"); - createNotification(); + .addConnectedListener(ctx -> { + Log.i(TAG, "addConnectedListener: Connected to MQTT server"); + createNotification(null, ctx); publishToTopic(String.format("device/%s/status", deviceName), "1", false); + Log.d(TAG, "addConnectedListener: "+mQTTClientStateToString(client.getState())); }) - .addDisconnectedListener(context -> { - Log.i(TAG, "createClient: Disconnected from MQTT server"); - createNotification(); + .addDisconnectedListener(ctx -> { + Log.i(TAG, "addDisconnectedListener: Disconnected from MQTT server"); + createNotification(ctx, null); + }) .willPublish() - .topic(String.format("device/%s/status", deviceName)) - .qos(MqttQos.EXACTLY_ONCE) - .payload("0".getBytes()) - .retain(true) - .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) - .contentType("text/plain") - .noMessageExpiry() - .applyWillPublish() + .topic(String.format("device/%s/status", deviceName)) + .qos(MqttQos.EXACTLY_ONCE) + .payload("0".getBytes()) + .retain(true) + .payloadFormatIndicator(Mqtt5PayloadFormatIndicator.UTF_8) + .contentType("text/plain") + .noMessageExpiry() + .applyWillPublish() .buildAsync(); - - Log.i(TAG, "createClient: Client created with address: " + addressString); + Log.i(TAG, "createClient: Client created with address: " + host + ":" + port); } - private void createNotification(){ + private void createNotification() { + createNotification(null, null); + } + private void createNotification(MqttClientDisconnectedContext mqttClientDisconnectedContext, + MqttClientConnectedContext mqttClientConnectedContext) { StringBuilder s = new StringBuilder(); - String address = spg.getSharedPreference(SPType.mqtt_sp).getString("mqtt_host", "None"); + String address = spg.getSharedPreference(SPType.MQTT).getString("mqtt_host", "None"); if(address.equals("None")){ s.append("MQTT Host: None\n"); } else { s.append("Host: ").append(address).append("\n"); s.append("State: ").append(client.getState().toString()).append("\n"); + if(mqttClientDisconnectedContext != null){ + if(mqttClientDisconnectedContext.getCause() != null){ + s.append("Cause: ").append(mqttClientDisconnectedContext.getCause().getMessage()).append("\n"); + } + } } builder.setStyle(new NotificationCompat.BigTextStyle() .bigText(s)); @@ -153,9 +242,21 @@ private void createNotification(){ @Override public void onCreate() { super.onCreate(); + Log.d(TAG, "onCreate: Creating MQTTService"); nm = getSystemService(NotificationManager.class); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel( + "OMNT_notification_channel", + "OMNT MQTT Service", + NotificationManager.IMPORTANCE_MAX + ); + nm.createNotificationChannel(channel); + } + setupSharedPreferences(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // create notification builder = new NotificationCompat.Builder(this, "OMNT_notification_channel") @@ -188,19 +289,33 @@ public void publishToTopic(String topic, String message, boolean retain){ .retain(retain) .send(); } - + private boolean isConnected(){ + if(client == null){ + Log.e(TAG, "isConnected: Client is null"); + return false; + } + return client.getState().isConnected(); + } public void disconnectClient(){ - CompletableFuture disconnect = client.disconnect(); - disconnect.whenComplete((aVoid, throwable) -> { - if(throwable != null){ - Log.e(TAG, "disconnectClient: Error disconnecting from MQTT server: " + throwable.getMessage()); - } else { - Log.i(TAG, "disconnectClient: Disconnected from MQTT server"); - } - }); + Log.d(TAG, "disconnectClient: starting to disconnect client...."); + if(isConnected()){ + + CompletableFuture disconnect = client.disconnect(); + disconnect.whenComplete((aVoid, throwable) -> { + if(throwable != null){ + Log.e(TAG, "disconnectClient: Error disconnecting from MQTT server: " + throwable.getMessage()); + } else { + Log.i(TAG, "disconnectClient: Disconnected from MQTT server"); + } + + }); + } + client = null; + nm.cancel(3); } public void connectClient(){ + Log.d(TAG, "connectClient: Connecting to MQTT server..."); CompletableFuture connAck = client.connectWith() .keepAlive(1) @@ -243,50 +358,50 @@ private void handleConfigMessage(String topic, String payload){ // config logging service if(topic.contains("/logging/enable")){ Log.d(TAG, "handleConfigMessage: Enable Logging: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("enable_logging", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("enable_logging", parseBoolean(payload)).apply(); return; } if(topic.contains("/logging/start_on_boot")){ Log.d(TAG, "handleConfigMessage: Start on Boot: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("start_logging_on_boot", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("start_logging_on_boot", parseBoolean(payload)).apply(); return; } if(topic.contains("/logging/notification_update_enabled")){ Log.d(TAG, "handleConfigMessage: Notification Update: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("enable_notification_update", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("enable_notification_update", parseBoolean(payload)).apply(); return; } if(topic.contains("/logging/interval_ms")){ Log.d(TAG, "handleConfigMessage: Logging Interval: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putString("logging_interval", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("logging_interval", payload).apply(); return; } // config influxdv_v2 parameter if(topic.contains("/influxv2/enabled")){ Log.d(TAG, "handleConfigMessage: Enable Influx: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("enable_influx", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("enable_influx", parseBoolean(payload)).apply(); return; } if(topic.contains("/influxv2/address")){ Log.d(TAG, "handleConfigMessage: Influx Address: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putString("influx_URL", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("influx_URL", payload).apply(); return; } if(topic.contains("/influxv2/token")){ Log.d(TAG, "handleConfigMessage: Influx Token received!"); - spg.getSharedPreference(SPType.logging_sp).edit().putString("influx_token", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("influx_token", payload).apply(); return; } if(topic.contains("/influxv2/bucket")){ Log.d(TAG, "handleConfigMessage: Influx Bucket: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putString("influx_bucket", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("influx_bucket", payload).apply(); return; } if(topic.contains("/influxv2/org")){ Log.d(TAG, "handleConfigMessage: Influx Org: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putString("influx_org", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("influx_org", payload).apply(); return; } if(topic.contains("/influxv2/tags")){ @@ -300,54 +415,54 @@ private void handleConfigMessage(String topic, String payload){ // config log file if(topic.contains("/file/enabled")){ Log.d(TAG, "handleConfigMessage: Enable Local File Log: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("enable_local_file_log", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("enable_local_file_log", parseBoolean(payload)).apply(); return; } // config logging content if(topic.contains("/content/measurement_name")){ Log.d(TAG, "handleConfigMessage: Measurement Name: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putString("measurement_name", payload).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putString("measurement_name", payload).apply(); return; } if(topic.contains("/content/network_information")){ Log.d(TAG, "handleConfigMessage: Network Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("influx_network_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("influx_network_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/signal_information")){ Log.d(TAG, "handleConfigMessage: Signal Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("log_signal_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("log_signal_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/cell_information")){ Log.d(TAG, "handleConfigMessage: Cell Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("influx_cell_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("influx_cell_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/neighbour_cells")){ Log.d(TAG, "handleConfigMessage: Neighbour Cells: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("log_neighbour_cells", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("log_neighbour_cells", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/throughput_information")){ Log.d(TAG, "handleConfigMessage: Throughput Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("influx_throughput_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("influx_throughput_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/wifi_information")){ Log.d(TAG, "handleConfigMessage: Wifi Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("log_wifi_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("log_wifi_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/battery_information")){ Log.d(TAG, "handleConfigMessage: Battery Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("influx_battery_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("influx_battery_data", parseBoolean(payload)).apply(); return; } if(topic.contains("/content/ip_information")){ Log.d(TAG, "handleConfigMessage: IP Information: " + payload); - spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("influx_ip_address_data", parseBoolean(payload)).apply(); + spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("influx_ip_address_data", parseBoolean(payload)).apply(); return; } @@ -439,20 +554,25 @@ private void subscribeToAllTopics(){ subsribetoTopic(String.format("device/%s/#", deviceName)); } + public void onDestroy(){ + disconnectClient(); + client = null; + Log.d(TAG, "onDestroy: Destroying MQTTService"); + super.onDestroy(); + + } @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand: Start MQTT service"); + Log.d(TAG, "onStartCommand: Start MQTTservice"); context = getApplicationContext(); - mqttSP = SharedPreferencesGrouper.getInstance(context).getSharedPreference(SPType.mqtt_sp); - deviceName = SharedPreferencesGrouper.getInstance(context).getSharedPreference(SPType.default_sp).getString("device_name", "null").strip(); + deviceName = SharedPreferencesGrouper.getInstance(context).getSharedPreference(SPType.MAIN).getString("device_name", "null").strip(); startForeground(3, builder.build()); - setupSharedPreferences(); createClient(); if(client == null){ Log.e(TAG, "onStartCommand: Client is null"); - spg.getSharedPreference(SPType.mqtt_sp).edit().putBoolean("enable_mqtt", false).apply(); + spg.getSharedPreference(SPType.MQTT).edit().putBoolean("enable_mqtt", false).apply(); return START_NOT_STICKY; } connectClient(); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java index 9b54556..62f31f8 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java @@ -91,7 +91,7 @@ public void onCellInfo(@NonNull List list) { } }); } - requestCellInfoUpdateHandler.postDelayed(this, Integer.parseInt(spg.getSharedPreference(SPType.logging_sp).getString("logging_interval", "1000"))); + requestCellInfoUpdateHandler.postDelayed(this, Integer.parseInt(spg.getSharedPreference(SPType.LOGGING).getString("logging_interval", "1000"))); } }; private Context context; @@ -152,7 +152,7 @@ protected void onCreate(Bundle savedInstanceState) { // make sure the subscription in the app settings exists in the current subscription list. // if it is not in the subscription list change it to the first one of the current list boolean valid_subscription = false; - String pref_subscription_str = spg.getSharedPreference(SPType.default_sp).getString("select_subscription","99999"); + String pref_subscription_str = spg.getSharedPreference(SPType.MAIN).getString("select_subscription","99999"); for (SubscriptionInfo info : dp.getSubscriptions()) { if (Integer.parseInt(pref_subscription_str) == info.getSubscriptionId()) { valid_subscription = true; @@ -160,10 +160,10 @@ protected void onCreate(Bundle savedInstanceState) { } } if (!valid_subscription) { - spg.getSharedPreference(SPType.default_sp).edit().putString("select_subscription", String.valueOf(dp.getSubscriptions().iterator().next().getSubscriptionId())).apply(); + spg.getSharedPreference(SPType.MAIN).edit().putString("select_subscription", String.valueOf(dp.getSubscriptions().iterator().next().getSubscriptionId())).apply(); } // switch the telephony manager to a new one according to the app settings - tm = tm.createForSubscriptionId(Integer.parseInt(spg.getSharedPreference(SPType.default_sp).getString("select_subscription", "0"))); + tm = tm.createForSubscriptionId(Integer.parseInt(spg.getSharedPreference(SPType.MAIN).getString("select_subscription", "0"))); // update reference to tm gv.setTm(tm); @@ -183,7 +183,7 @@ protected void onCreate(Bundle savedInstanceState) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); // if the location API on android is disabled and we don't want a fake location make a popup - if (!lm.isLocationEnabled() && !spg.getSharedPreference(SPType.logging_sp).getBoolean("fake_location", false)) { + if (!lm.isLocationEnabled() && !spg.getSharedPreference(SPType.LOGGING).getBoolean("fake_location", false)) { new AlertDialog.Builder(MainActivity.this) .setTitle(R.string.dialog_no_location_title) .setMessage(R.string.dialog_no_location) @@ -192,7 +192,7 @@ protected void onCreate(Bundle savedInstanceState) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplicationContext().startActivity(intent); }) - .setNegativeButton(R.string.dialog_no_location_fake, (dialog, which) -> spg.getSharedPreference(SPType.logging_sp).edit().putBoolean("fake_location", true).apply()) + .setNegativeButton(R.string.dialog_no_location_fake, (dialog, which) -> spg.getSharedPreference(SPType.LOGGING).edit().putBoolean("fake_location", true).apply()) .setIcon(android.R.drawable.ic_dialog_map) .show(); } @@ -201,7 +201,7 @@ protected void onCreate(Bundle savedInstanceState) { initHandlerAndHandlerThread(); loggingServiceIntent = new Intent(this, LoggingService.class); - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { + if (spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_logging", false)) { Log.d(TAG, "Start logging service"); context.startForegroundService(loggingServiceIntent); } @@ -216,10 +216,10 @@ protected void onCreate(Bundle savedInstanceState) { context.stopService(loggingServiceIntent); } } - }, SPType.logging_sp); + }, SPType.LOGGING); notificationServiceIntent = new Intent(context, NotificationService.class); - if(spg.getSharedPreference(SPType.default_sp).getBoolean("enable_radio_notification", false)){ + if(spg.getSharedPreference(SPType.MAIN).getBoolean("enable_radio_notification", false)){ context.startService(notificationServiceIntent); } spg.setListener((prefs, key) -> { @@ -230,10 +230,10 @@ protected void onCreate(Bundle savedInstanceState) { context.stopService(notificationServiceIntent); } } - }, SPType.default_sp); + }, SPType.MAIN); mqttServiceIntent = new Intent(this, MQTTService.class); - if (spg.getSharedPreference(SPType.mqtt_sp).getBoolean("enable_mqtt", false)) { + if (spg.getSharedPreference(SPType.MQTT).getBoolean("enable_mqtt", false)) { Log.d(TAG, "Start MQTT service"); context.startService(mqttServiceIntent); } @@ -248,19 +248,19 @@ protected void onCreate(Bundle savedInstanceState) { context.stopService(mqttServiceIntent); } } - }, SPType.mqtt_sp); + }, SPType.MQTT); Intent intent = getIntent(); if (Intent.ACTION_VIEW.equals(intent.getAction())) { String mqtt_broker_address = intent.getStringExtra("mqtt_broker_address"); String device_name = intent.getStringExtra("device_name"); if(device_name != null){ - spg.getSharedPreference(SPType.default_sp).edit() + spg.getSharedPreference(SPType.MAIN).edit() .putString("device_name", device_name) .apply(); } if(mqtt_broker_address != null){ - spg.getSharedPreference(SPType.mqtt_sp).edit() + spg.getSharedPreference(SPType.MQTT).edit() .putBoolean("enable_mqtt", true) .putString("mqtt_host", mqtt_broker_address) .apply(); @@ -269,7 +269,10 @@ protected void onCreate(Bundle savedInstanceState) { } - + String target = getIntent().getStringExtra("navigateToFragment"); + if (target != null && target.equals("PingFragment")) { + navController.navigate(R.id.ping_fragment); + } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/NotificationService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/NotificationService.java index ca2a5ee..2fb218d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/NotificationService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/NotificationService.java @@ -19,13 +19,10 @@ import android.os.HandlerThread; import android.os.IBinder; import android.util.Log; -import android.widget.Toast; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; -import com.influxdb.client.domain.Run; - import java.util.Objects; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.DataProvider.DataProvider; @@ -91,7 +88,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { stopNotificationUpdate(); } - }, SPType.default_sp); + }, SPType.MAIN); setupNotification(); startForeground(4, builder.build()); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/OpenMobileNetworkToolkit.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/OpenMobileNetworkToolkit.java index f054487..4d17f1e 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/OpenMobileNetworkToolkit.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/OpenMobileNetworkToolkit.java @@ -50,41 +50,41 @@ public PersistableBundle applyCarrierSettings() { Log.d(TAG, "applying carrier config"); // API 27 if (sdk_version >= Build.VERSION_CODES.O_MR1) { - configForSubId.putBoolean(CarrierConfigManager.KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL",false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL",false)); } // API 30 if (sdk_version >= Build.VERSION_CODES.R) { - configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_WORLD_MODE_ENABLED_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_EDITABLE_WFC_MODE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_EDITABLE_WFC_ROAMING_MODE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); - configForSubId.putStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, new String[] {spg.getSharedPreference(SPType.carrier_sp).getString("edit_text_KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY", "")}); - configForSubId.putStringArray(CarrierConfigManager.KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, new String[] {spg.getSharedPreference(SPType.carrier_sp).getString("edit_text_KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY", "")}); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_WORLD_MODE_ENABLED_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_EDITABLE_WFC_MODE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_EDITABLE_WFC_ROAMING_MODE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", false)); + configForSubId.putStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, new String[] {spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("edit_text_KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY", "")}); + configForSubId.putStringArray(CarrierConfigManager.KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, new String[] {spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("edit_text_KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY", "")}); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL", true)); } // API 31 if (sdk_version >= Build.VERSION_CODES.S) { int[] nr_av = new int[2]; int i = 0; - for (String value: spg.getSharedPreference(SPType.carrier_sp).getStringSet("multi_select_KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY", new HashSet<>(Arrays.asList("1", "2")))){ + for (String value: spg.getSharedPreference(SPType.MOBILE_NETWORK).getStringSet("multi_select_KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY", new HashSet<>(Arrays.asList("1", "2")))){ nr_av[i] = Integer.parseInt(value); } configForSubId.putIntArray(CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, nr_av); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL", false)); - //configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_ENABLE_2G, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_ENABLE_2G", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL", false)); + //configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_ENABLE_2G, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_ENABLE_2G", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL", true)); // VoLTE // check if a VoLTE / VoNR EPDG address is configured and apply it. - String epdg = spg.getSharedPreference(SPType.carrier_sp).getString("edit_text_EPDG_STATIC_ADDRESS", ""); + String epdg = spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("edit_text_EPDG_STATIC_ADDRESS", ""); if (!epdg.isEmpty()) { configForSubId.putString(CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, epdg); configForSubId.putString(CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_ROAMING_STRING, epdg); @@ -93,41 +93,41 @@ public PersistableBundle applyCarrierSettings() { } // API <= 29 - configForSubId.putBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_FORCE_HOME_NETWORK_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_PREFER_2G_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_SETTINGS_ENABLE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_EDITABLE_ENHANCED_4G_LTE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_VOLTE_AVAILABLE_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_VOLTE_PROVISIONED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_VT_AVAILABLE_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_ENHANCED_4G_LTE_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_IMS_APN_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_PRESET_APN_DETAILS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_PRESET_APN_DETAILS_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_HIDE_SIM_LOCK_SETTINGS_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_ALLOW_ADDING_APNS_BOOL", true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_APN_EXPAND_BOOL",true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_IMS_GBA_REQUIRED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL", false)); - configForSubId.putInt(CarrierConfigManager.KEY_VOLTE_REPLACEMENT_RAT_INT, Integer.parseInt(spg.getSharedPreference(SPType.carrier_sp).getString("list_KEY_VOLTE_REPLACEMENT_RAT_INT9","18"))); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL",false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_AUTO_RETRY_ENABLED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_AUTO_RETRY_ENABLED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_WORLD_PHONE_BOOL",true)); - configForSubId.putBoolean(CarrierConfigManager.KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL", false)); - configForSubId.putBoolean(CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", false)); - configForSubId.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, Integer.parseInt(spg.getSharedPreference(SPType.carrier_sp).getString("list_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", "1"))); - configForSubId.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT, Integer.parseInt(spg.getSharedPreference(SPType.carrier_sp).getString("list_KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT","1"))); - configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, spg.getSharedPreference(SPType.carrier_sp).getBoolean("switch_KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL",false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_FORCE_HOME_NETWORK_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_PREFER_2G_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_SETTINGS_ENABLE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_EDITABLE_ENHANCED_4G_LTE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_VOLTE_AVAILABLE_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_VOLTE_PROVISIONED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_VT_AVAILABLE_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_ENHANCED_4G_LTE_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_IMS_APN_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_PRESET_APN_DETAILS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_PRESET_APN_DETAILS_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_HIDE_SIM_LOCK_SETTINGS_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_ALLOW_ADDING_APNS_BOOL", true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_APN_EXPAND_BOOL",true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_IMS_GBA_REQUIRED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL", false)); + configForSubId.putInt(CarrierConfigManager.KEY_VOLTE_REPLACEMENT_RAT_INT, Integer.parseInt(spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("list_KEY_VOLTE_REPLACEMENT_RAT_INT9","18"))); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL",false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_AUTO_RETRY_ENABLED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_AUTO_RETRY_ENABLED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_WORLD_PHONE_BOOL",true)); + configForSubId.putBoolean(CarrierConfigManager.KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL", false)); + configForSubId.putBoolean(CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", false)); + configForSubId.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, Integer.parseInt(spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("list_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", "1"))); + configForSubId.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT, Integer.parseInt(spg.getSharedPreference(SPType.MOBILE_NETWORK).getString("list_KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT","1"))); + configForSubId.putBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, spg.getSharedPreference(SPType.MOBILE_NETWORK).getBoolean("switch_KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL",false)); Log.d(TAG, "Carrier settings applied"); return configForSubId; } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Iperf3Parameter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Iperf3Parameter.java index 55f1655..28f7413 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Iperf3Parameter.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Iperf3Parameter.java @@ -8,9 +8,7 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter; -import android.os.Environment; import android.os.Parcel; -import android.os.Parcelable; import android.util.Log; import androidx.annotation.NonNull; @@ -24,9 +22,7 @@ import java.util.ArrayList; public class Iperf3Parameter extends Parameter { - public static final String rootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath(); - public static final String rawDirPath = rootPath+"/omnt/iperf3/raw/"; - public static final String lineProtocolDirPath = rootPath+"/omnt/iperf3/lineprotocol/"; + public static final String HOST = "host"; public static final String PORT = "port"; public static final String BITRATE = "bitrate"; @@ -67,7 +63,6 @@ public class Iperf3Parameter extends Parameter { public static final String RSAPRIVATEKEYPATH = "rsaPrivateKeyPath"; public static final String IDLETIMEOUT = "idleTimeout"; public static final String SERVERBITRATELIMIT = "serverBitrateLimit"; - public static final String SERVER = "server"; public static final String CLIENT = "client"; public static final String DAEMON = "daemon"; @@ -89,335 +84,41 @@ public class Iperf3Parameter extends Parameter { public static final String MODE = "mode"; public static final String PROTOCOL = "protocol"; public static final String IPERF3UUID = "iperf3UUID"; + public static final String LENGTH ="length"; - private static final String TAG = "Iperf3Parameter"; - protected Iperf3Parameter(Parcel in) { - super(in); - host = in.readString(); - iPerf3UUID = in.readString(); - port = in.readInt(); - interval = in.readDouble(); - bitrate = in.readString(); - length = in.readInt(); - pidfile = in.readString(); - file = in.readString(); - affinity = in.readString(); - bind = in.readString(); - bindDev = in.readString(); - byte tmpVerbose = in.readByte(); - verbose = tmpVerbose == 0 ? null : tmpVerbose == 1; - byte tmpJson = in.readByte(); - json = tmpJson == 0 ? null : tmpJson == 1; - byte tmpJsonStream = in.readByte(); - jsonStream = tmpJsonStream == 0 ? null : tmpJsonStream == 1; - byte tmpForceflush = in.readByte(); - forceflush = tmpForceflush == 0 ? null : tmpForceflush == 1; - timestamps = in.readString(); - if (in.readByte() == 0) { - rcvTimeout = null; - } else { - rcvTimeout = in.readInt(); - } - if (in.readByte() == 0) { - sndTimeout = null; - } else { - sndTimeout = in.readInt(); - } - if (in.readByte() == 0) { - debug = null; - } else { - debug = in.readInt(); - } - byte tmpVersion = in.readByte(); - version = tmpVersion == 0 ? null : tmpVersion == 1; - byte tmpHelp = in.readByte(); - help = tmpHelp == 0 ? null : tmpHelp == 1; - byte tmpDaemon = in.readByte(); - daemon = tmpDaemon == 0 ? null : tmpDaemon == 1; - byte tmpOneOff = in.readByte(); - oneOff = tmpOneOff == 0 ? null : tmpOneOff == 1; - serverBitrateLimit = in.readString(); - if (in.readByte() == 0) { - idleTimeout = null; - } else { - idleTimeout = in.readInt(); - } - rsaPrivateKeyPath = in.readString(); - authorizedUsersPath = in.readString(); - if (in.readByte() == 0) { - timeSkewThreshold = null; - } else { - timeSkewThreshold = in.readInt(); - } - byte tmpUsePkcs1Padding = in.readByte(); - usePkcs1Padding = tmpUsePkcs1Padding == 0 ? null : tmpUsePkcs1Padding == 1; - byte tmpSctp = in.readByte(); - sctp = tmpSctp == 0 ? null : tmpSctp == 1; - xbind = in.readString(); - if (in.readByte() == 0) { - nstreams = null; - } else { - nstreams = in.readInt(); - } - if (in.readByte() == 0) { - connectTimeout = null; - } else { - connectTimeout = in.readInt(); - } - pacingTimer = in.readString(); - fqRate = in.readString(); - if (in.readByte() == 0) { - time = null; - } else { - time = in.readInt(); - } - bytes = in.readString(); - blockcount = in.readString(); - if (in.readByte() == 0) { - cport = null; - } else { - cport = in.readInt(); - } - if (in.readByte() == 0) { - parallel = null; - } else { - parallel = in.readInt(); - } - byte tmpReverse = in.readByte(); - reverse = tmpReverse == 0 ? null : tmpReverse == 1; - byte tmpBidir = in.readByte(); - bidir = tmpBidir == 0 ? null : tmpBidir == 1; - window = in.readString(); - congestion = in.readString(); - if (in.readByte() == 0) { - setMss = null; - } else { - setMss = in.readInt(); - } - byte tmpNoDelay = in.readByte(); - noDelay = tmpNoDelay == 0 ? null : tmpNoDelay == 1; - byte tmpVersion4 = in.readByte(); - version4 = tmpVersion4 == 0 ? null : tmpVersion4 == 1; - byte tmpVersion6 = in.readByte(); - version6 = tmpVersion6 == 0 ? null : tmpVersion6 == 1; - if (in.readByte() == 0) { - tos = null; - } else { - tos = in.readInt(); - } - dscp = in.readString(); - if (in.readByte() == 0) { - flowlabel = null; - } else { - flowlabel = in.readInt(); - } - byte tmpZerocopy = in.readByte(); - zerocopy = tmpZerocopy == 0 ? null : tmpZerocopy == 1; - if (in.readByte() == 0) { - omit = null; - } else { - omit = in.readInt(); - } - title = in.readString(); - extraData = in.readString(); - byte tmpGetServerOutput = in.readByte(); - getServerOutput = tmpGetServerOutput == 0 ? null : tmpGetServerOutput == 1; - byte tmpUdpCounters64bit = in.readByte(); - udpCounters64bit = tmpUdpCounters64bit == 0 ? null : tmpUdpCounters64bit == 1; - byte tmpRepeatingPayload = in.readByte(); - repeatingPayload = tmpRepeatingPayload == 0 ? null : tmpRepeatingPayload == 1; - byte tmpDontFragment = in.readByte(); - dontFragment = tmpDontFragment == 0 ? null : tmpDontFragment == 1; - username = in.readString(); - rsaPublicKeyPath = in.readString(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Iperf3Parameter createFromParcel(Parcel in) { - return new Iperf3Parameter(in); - } - - @Override - public Iperf3Parameter[] newArray(int size) { - return new Iperf3Parameter[size]; - } - }; - - public Iperf3Parameter(String ip, - int port, - String bitrate, - int duration, - double interval, - String bytes, - int streams, - int cport, - String testUUID, - Iperf3Mode mode, - Iperf3Protocol protocol, - Iperf3Direction direction - ) { - - super(rawDirPath+testUUID+".txt", lineProtocolDirPath+testUUID+".txt"); - this.testUUID = testUUID; - this.host = ip; - this.port = port; - this.bitrate = bitrate; - this.time = duration; - this.interval = interval; - this.bytes = bytes; - this.nstreams = streams; - this.cport = cport; - this.mode = mode; - this.direction = direction; - this.protocol = protocol; - - } - - public Iperf3Parameter(String iPerf3UUID){ - super(rawDirPath+iPerf3UUID+".txt", lineProtocolDirPath+iPerf3UUID+".txt"); - } - public Iperf3Parameter(String ip, - String iPerf3UUID, - Iperf3Protocol protocol, - int port, - double interval, - String bitrate, - int length, - Iperf3Mode mode, - Iperf3Direction direction, - String pidfile, - String file, - String affinity, - String bind, - String bindDev, - Boolean verbose, - Boolean json, - Boolean jsonStream, - String logfile, - Boolean forceflush, - String timestamps, - Integer rcvTimeout, - Integer sndTimeout, - Integer debug, - Boolean version, - Boolean help, - Boolean daemon, - Boolean oneOff, - String serverBitrateLimit, - Integer idleTimeout, - String rsaPrivateKeyPath, - String authorizedUsersPath, - Integer timeSkewThreshold, - Boolean usePkcs1Padding, - Boolean sctp, - String xbind, - Integer nstreams, - Integer connectTimeout, - String pacingTimer, - String fqRate, - Integer time, - String bytes, - String blockcount, - Integer cport, - Integer parallel, - Boolean reverse, - Boolean bidir, - String window, - String congestion, - Integer setMss, - Boolean noDelay, - Boolean version4, - Boolean version6, - Integer tos, - String dscp, - Integer flowlabel, - Boolean zerocopy, - Integer omit, - String title, - String extraData, - Boolean getServerOutput, - Boolean udpCounters64bit, - Boolean repeatingPayload, - Boolean dontFragment, - String username, - String rsaPublicKeyPath) { - super(rawDirPath+iPerf3UUID+".txt", lineProtocolDirPath+iPerf3UUID+".txt"); - this.host = ip; - this.iPerf3UUID = iPerf3UUID; - this.protocol = protocol; - this.port = port; - this.interval = interval; - this.bitrate = bitrate; - this.length = length; - this.mode = mode; - this.direction = direction; - this.pidfile = pidfile; - this.file = file; - this.affinity = affinity; - this.bind = bind; - this.bindDev = bindDev; - this.verbose = verbose; - this.json = json; - this.jsonStream = jsonStream; - this.forceflush = forceflush; - this.timestamps = timestamps; - this.rcvTimeout = rcvTimeout; - this.sndTimeout = sndTimeout; - this.debug = debug; - this.version = version; - this.help = help; - this.daemon = daemon; - this.oneOff = oneOff; - this.serverBitrateLimit = serverBitrateLimit; - this.idleTimeout = idleTimeout; - this.rsaPrivateKeyPath = rsaPrivateKeyPath; - this.authorizedUsersPath = authorizedUsersPath; - this.timeSkewThreshold = timeSkewThreshold; - this.usePkcs1Padding = usePkcs1Padding; - this.sctp = sctp; - this.xbind = xbind; - this.nstreams = nstreams; - this.connectTimeout = connectTimeout; - this.pacingTimer = pacingTimer; - this.fqRate = fqRate; - this.time = time; - this.bytes = bytes; - this.blockcount = blockcount; - this.cport = cport; - this.parallel = parallel; - this.reverse = reverse; - this.bidir = bidir; - this.window = window; - this.congestion = congestion; - this.setMss = setMss; - this.noDelay = noDelay; - this.version4 = version4; - this.version6 = version6; - this.tos = tos; - this.dscp = dscp; - this.flowlabel = flowlabel; - this.zerocopy = zerocopy; - this.omit = omit; - this.title = title; - this.extraData = extraData; - this.getServerOutput = getServerOutput; - this.udpCounters64bit = udpCounters64bit; - this.repeatingPayload = repeatingPayload; - this.dontFragment = dontFragment; - this.username = username; - this.rsaPublicKeyPath = rsaPublicKeyPath; - } + private static final String TAG = "Iperf3Parameter"; public void updatePaths(){ - super.setLogfile(rawDirPath+testUUID+".txt"); - super.setLineProtocolFile(lineProtocolDirPath+testUUID+".txt"); + super.setRawLogFilePath(super.getRawDirPath()+"/"+testUUID+".json"); + super.setLineProtocolFilePath(super.getLineProtocolDirPath()+"/"+testUUID+".lp"); } + public Iperf3Parameter(String testUUID){ + this(new JSONObject(), testUUID); + } + + public void setDirectionFlags() { + switch (this.direction) { + case UP: + this.reverse = false; + this.bidir = false; + break; + case DOWN: + this.reverse = true; + this.bidir = false; + break; + case BIDIR: + this.bidir = true; + this.reverse = false; + break; + } + } + public Iperf3Parameter(JSONObject jsonObject, String testUUID) { - super(rawDirPath+testUUID+".txt", lineProtocolDirPath+testUUID+".txt"); + super(ParameterType.IPERF3, + testUUID); this.testUUID = testUUID; this.jsonStream = true; @@ -454,7 +155,7 @@ public Iperf3Parameter(JSONObject jsonObject, String testUUID) { Log.d(TAG, "interval is not set. Defaulting to iPerf3 default interval."); } try { - this.length = jsonObject.getInt(BYTES); + this.length = jsonObject.getInt(LENGTH); } catch (JSONException e) { Log.d(TAG, "Length not set."); } @@ -467,6 +168,8 @@ public Iperf3Parameter(JSONObject jsonObject, String testUUID) { String direction = jsonObject.getString(DIRECTION); Log.d(TAG, "Iperf3Parameter: direction: "+direction); this.direction = Iperf3Direction.valueOf(direction.toUpperCase().trim()); + setDirectionFlags(); + } catch (JSONException e) { this.direction = Iperf3Direction.UP; Log.d(TAG, "direction not set."); @@ -753,85 +456,13 @@ public Iperf3Parameter(JSONObject jsonObject, String testUUID) { Log.d(TAG, "title not set."); } try { - Files.createDirectories(Paths.get(rawDirPath)); - Files.createDirectories(Paths.get(lineProtocolDirPath)); + Files.createDirectories(Paths.get(super.getRawDirPath())); + Files.createDirectories(Paths.get(super.getLineProtocolDirPath())); } catch (IOException e) { Log.d(TAG, "Could not create directories."); } } - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeString(host); - dest.writeString(iPerf3UUID); - dest.writeInt(port); - dest.writeDouble(interval); - dest.writeString(bitrate); - dest.writeInt(length); - dest.writeString(mode.name()); - dest.writeString(direction.name()); - dest.writeString(pidfile); - dest.writeString(file); - dest.writeString(affinity); - dest.writeString(bind); - dest.writeString(bindDev); - dest.writeBoolean(verbose); - dest.writeBoolean(json); - dest.writeBoolean(jsonStream); - dest.writeBoolean(forceflush); - dest.writeString(timestamps); - dest.writeInt(rcvTimeout); - dest.writeInt(sndTimeout); - dest.writeInt(debug); - dest.writeBoolean(version); - dest.writeBoolean(help); - dest.writeBoolean(daemon); - dest.writeBoolean(oneOff); - dest.writeString(serverBitrateLimit); - dest.writeInt(idleTimeout); - dest.writeString(rsaPrivateKeyPath); - dest.writeString(authorizedUsersPath); - dest.writeInt(timeSkewThreshold); - dest.writeBoolean(usePkcs1Padding); - dest.writeBoolean(sctp); - dest.writeString(xbind); - dest.writeInt(nstreams); - dest.writeInt(connectTimeout); - dest.writeString(pacingTimer); - dest.writeString(fqRate); - dest.writeInt(time); - dest.writeString(bytes); - dest.writeString(blockcount); - dest.writeInt(cport); - dest.writeInt(parallel); - dest.writeBoolean(reverse); - dest.writeBoolean(bidir); - dest.writeString(window); - dest.writeString(congestion); - dest.writeInt(setMss); - dest.writeBoolean(noDelay); - dest.writeBoolean(version4); - dest.writeBoolean(version6); - dest.writeInt(tos); - dest.writeString(dscp); - dest.writeInt(flowlabel); - dest.writeBoolean(zerocopy); - dest.writeInt(omit); - dest.writeString(title); - dest.writeString(extraData); - dest.writeBoolean(getServerOutput); - dest.writeBoolean(udpCounters64bit); - dest.writeBoolean(repeatingPayload); - dest.writeBoolean(dontFragment); - dest.writeString(username); - dest.writeString(rsaPublicKeyPath); - } - public String getHost() { return host; } @@ -1808,7 +1439,7 @@ public String[] getInputAsCommand() { command.add("--json-stream"); command.add("--forceflush"); command.add("--logfile"); - command.add(super.getLogfile()); + command.add(super.getRawLogFilePath()); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Parameter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Parameter.java index ccf116e..a259bbf 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Parameter.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/Parameter.java @@ -12,53 +12,64 @@ import android.os.Parcel; import android.os.Parcelable; -public class Parameter implements Parcelable { - public static final String rootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath(); - private String lineProtocolFile; - private String logfile; +public class Parameter { + private ParameterType parameterType; + public static final String rootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath()+"/omnt"; + private String rawDirPath; + private String lineProtocolDirPath; + private String lineProtocolFilePath; + private String rawLogFilePath; protected Parameter(Parcel in) { - lineProtocolFile = in.readString(); - logfile = in.readString(); + lineProtocolFilePath = in.readString(); + rawLogFilePath = in.readString(); } - public Parameter(String logfile, String lineProtocolFile) { - this.logfile = logfile; - this.lineProtocolFile = lineProtocolFile; + public Parameter(ParameterType type, + String testUUID) { + this.parameterType = type; + this.rawDirPath = rootPath + "/" + this.parameterType.toString().toLowerCase() + "/raw"; + this.lineProtocolDirPath = rootPath + "/" + this.parameterType.toString().toLowerCase() + "/lineprotocol"; + this.rawLogFilePath = this.rawDirPath + "/" + testUUID + ".log"; + this.lineProtocolFilePath = this.lineProtocolDirPath + "/" + testUUID + ".lp"; } - public static final Creator CREATOR = new Creator() { - @Override - public Parameter createFromParcel(Parcel in) { - return new Parameter(in); - } + public ParameterType getParameterType() { + return parameterType; + } + + public String getRootPath() { + return rootPath; + } - @Override - public Parameter[] newArray(int size) { - return new Parameter[size]; - } - }; + public String getRawDirPath() { + return rawDirPath; + } - public String getLineProtocolFile() { - return lineProtocolFile; + public void setRawDirPath(String rawDirPath) { + this.rawDirPath = rawDirPath; } - public String getLogfile() { - return logfile; + public String getLineProtocolDirPath() { + return lineProtocolDirPath; } - public int describeContents() { - return 0; + public void setLineProtocolDirPath(String lineProtocolDirPath) { + this.lineProtocolDirPath = lineProtocolDirPath; } - public void writeToParcel(android.os.Parcel dest, int flags) { - dest.writeString(lineProtocolFile); - dest.writeString(logfile); + public String getLineProtocolFilePath() { + return lineProtocolFilePath; } - public void setLineProtocolFile(String lineProtocolFile) { - this.lineProtocolFile = lineProtocolFile; + + public void setLineProtocolFilePath(String lineProtocolFilePath) { + this.lineProtocolFilePath = lineProtocolFilePath; + } + + public String getRawLogFilePath() { + return rawLogFilePath; } - public void setLogfile(String logfile) { - this.logfile = logfile; + public void setRawLogFilePath(String rawLogFilePath) { + this.rawLogFilePath = rawLogFilePath; } } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/ParameterType.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/ParameterType.java new file mode 100644 index 0000000..9914621 --- /dev/null +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/ParameterType.java @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2025 Peter Hasse + * SPDX-FileCopyrightText: 2025 Johann Hackler + * SPDX-FileCopyrightText: 2025 Fraunhofer FOKUS + * + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter; + +public enum ParameterType { + PING, + IPERF3 +} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/PingParameter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/PingParameter.java index ac38c82..0d25d67 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/PingParameter.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Parameter/PingParameter.java @@ -23,11 +23,8 @@ import java.util.ArrayList; public class PingParameter extends Parameter { - public static final String rawDirPath = rootPath+"/omnt/ping/raw/"; - public static final String lineProtocolDirPath = rootPath+"/omnt/ping/lineprotocol/"; private static final String TAG = "PingParameter"; - public static final String PING = "ping"; public static final String DESTINATION = "destination"; public static final String COUNT = "count"; @@ -43,7 +40,7 @@ public int getCount() { return count; } - public int getTimeoutMillis() { + public double getTimeoutMillis() { return timeoutMillis; } @@ -51,7 +48,7 @@ public int getPacketSize() { return packetSize; } - public long getIntervalMillis() { + public double getIntervalMillis() { return intervalMillis; } @@ -62,9 +59,9 @@ public Network getNetwork() { private String destination; private int count; - private int timeoutMillis; + private double timeoutMillis; private int packetSize; - private long intervalMillis; + private double intervalMillis; private Network network; private int deadline; private String testUUID; @@ -101,15 +98,16 @@ public String[] getInputAsCommand() { private void setupDirs(){ try { - Files.createDirectories(Paths.get(rawDirPath)); - Files.createDirectories(Paths.get(lineProtocolDirPath)); + Files.createDirectories(Paths.get(super.getRawDirPath())); + Files.createDirectories(Paths.get(super.getLineProtocolFilePath())); } catch (IOException e) { Log.d(TAG, "Could not create directories."); } } public PingParameter(String stringParameter, String testUUID) { - super(rawDirPath + testUUID + ".txt", lineProtocolDirPath + testUUID + ".txt"); + super(ParameterType.PING, + testUUID); this.testUUID = testUUID; String[] parts = stringParameter.split(" "); for (int i = 0; i < parts.length; i++) { @@ -118,13 +116,13 @@ public PingParameter(String stringParameter, String testUUID) { count = Integer.parseInt(parts[i + 1]); break; case "-W": - timeoutMillis = Integer.parseInt(parts[i + 1]); + timeoutMillis = Double.parseDouble(parts[i + 1]); break; case "-s": packetSize = Integer.parseInt(parts[i + 1]); break; case "-i": - intervalMillis = Long.parseLong(parts[i + 1]); + intervalMillis = Double.parseDouble(parts[i + 1]); break; case "-w": deadline = Integer.parseInt(parts[i + 1]); @@ -136,7 +134,8 @@ public PingParameter(String stringParameter, String testUUID) { } public PingParameter(JSONObject parameter, String testUUID) { - super(rawDirPath + testUUID + ".txt", lineProtocolDirPath + testUUID + ".txt"); + super(ParameterType.PING, + testUUID); this.testUUID = testUUID; try { destination = parameter.getString(DESTINATION); @@ -164,7 +163,7 @@ public PingParameter(JSONObject parameter, String testUUID) { Log.i(TAG, "no packet size set."); } try { - intervalMillis = parameter.getLong(INTERVAL); + intervalMillis = parameter.getDouble(INTERVAL); } catch (JSONException e) { Log.d(TAG, e.toString()); Log.i(TAG, "no interval set."); @@ -182,38 +181,11 @@ protected PingParameter(Parcel in) { super(in); destination = in.readString(); count = in.readInt(); - timeoutMillis = in.readInt(); + timeoutMillis = in.readDouble(); packetSize = in.readInt(); - intervalMillis = in.readLong(); + intervalMillis = in.readDouble(); network = in.readParcelable(Network.class.getClassLoader()); } - public static final Creator CREATOR = new Creator() { - @Override - public PingParameter createFromParcel(Parcel in) { - return new PingParameter(in); - } - - @Override - public PingParameter[] newArray(int size) { - return new PingParameter[size]; - } - }; - - @Override - public int describeContents() { - return super.describeContents(); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(destination); - dest.writeInt(count); - dest.writeInt(timeoutMillis); - dest.writeInt(packetSize); - dest.writeLong(intervalMillis); - dest.writeParcelable(network, flags); - } } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java index 04e918a..513a15d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java @@ -8,7 +8,8 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping; -import static android.view.View.INVISIBLE; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; import android.annotation.SuppressLint; import android.content.Context; @@ -42,6 +43,8 @@ import com.google.android.material.button.MaterialButtonToggleGroup; import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textview.MaterialTextView; +import com.google.gson.Gson; import java.io.FileOutputStream; import java.util.UUID; @@ -49,6 +52,8 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.METRIC_TYPE; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.MetricCalculator; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.MetricView; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PacketLossLine; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.RTTLine; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; @@ -74,6 +79,9 @@ public class PingFragment extends Fragment { private Observer observer; private LiveData workInfoLiveData; + private MaterialTextView pingTextView; + private int counter = 0; + public PingFragment() { } @@ -103,7 +111,7 @@ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { - spg.getSharedPreference(SPType.ping_sp).edit().putString(name, field.getText().toString()).apply(); + spg.getSharedPreference(SPType.PING).edit().putString(name, field.getText().toString()).apply(); } @Override @@ -132,26 +140,51 @@ private void checkLastUUID(String uuidStr) { if (workInfo == null) return; Data progress = workInfo.getProgress(); Log.d(TAG, "registerObserver: workInfo-State: " + workInfo.getState()); - double rtt = progress.getDouble(PingWorker.RTT, -1.0); - if(rtt != -1.0) { - rttMetric.update(rtt); + String rtt = progress.getString(PingWorker.RTT); + if(rtt != null) { + Log.d(TAG, "checkLastUUID: got RTT line"); + RTTLine rttLine = new Gson().fromJson(rtt, RTTLine.class); + Log.d(TAG, "checkLastUUID: got ICMP-SEQ: "+rttLine.getIcmpSeq()); + rttMetric.update(rttLine.getRtt()); + StringBuilder sb = new StringBuilder(); + sb.append("Host: ").append(rttLine.getHost()).append(" "); + sb.append("Seq: ").append(rttLine.getIcmpSeq()).append(" "); + sb.append("TTL: ").append(rttLine.getTtl()).append(" "); + sb.append("RTT: ").append(rttLine.getRtt()).append(" ms"); + pingTextView.setText(sb.toString()+"\n"+pingTextView.getText()); + counter++; + if(counter > 1e4){ + pingTextView.setText(""); + rttMetric.getMetricCalculator().resetMetric(); + packetLossMetric.getMetricCalculator().resetMetric(); + counter = 0; + } } - double packetLoss = progress.getDouble(PingWorker.PACKET_LOSS, -1.0); - - if(packetLoss != -1.0) { - packetLossMetric.setVisibility(View.VISIBLE); - Log.d(TAG, "onChanged: Packet Loss: " + packetLoss); - packetLossMetric.update(packetLoss); + String packetLoss = progress.getString(PingWorker.PACKET_LOSS); + if(packetLoss != null){ + Log.d(TAG, "checkLastUUID: got PACKETLOSS line"); + PacketLossLine packetLossLine = new Gson().fromJson(packetLoss,PacketLossLine.class); + packetLossMetric.update(packetLossLine.getPacketLoss()); + packetLossMetric.setVisibility(VISIBLE); } + switch (workInfo.getState()) { case RUNNING: case SUCCEEDED: break; case FAILED: + Log.e(TAG, "checkLastUUID: Work failed: " + workInfo.getOutputData().getString(PingWorker.REASON)); + pingTextView.setText(workInfo.getOutputData().getString(PingWorker.REASON)); + rttMetric.getMetricCalculator().resetMetric(); + packetLossMetric.getMetricCalculator().resetMetric(); + packetLossMetric.setVisibility(GONE); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); + toggleGroup.check(R.id.ping_stop); + break; case CANCELLED: - workInfoLiveData.removeObserver(observer); // Optionally clean up +// workInfoLiveData.removeObserver(observer); // Optionally clean up break; default: break; @@ -161,7 +194,7 @@ private void checkLastUUID(String uuidStr) { } private void setupRepeatButton(){ - boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); + boolean isRepeat = spg.getSharedPreference(SPType.PING).getBoolean("repeat_ping", false); int color = ContextCompat.getColor(ct, isRepeat ? R.color.design_default_color_primary : R.color.material_dynamic_secondary40); repeatButton.setColorFilter(color); @@ -171,8 +204,8 @@ private void setupRepeatButton(){ public void onResume() { super.onResume(); Log.d(TAG, "onResume: PingFragment resumed"); - spg.getSharedPreference(SPType.ping_sp).registerOnSharedPreferenceChangeListener(listener); - checkLastUUID(spg.getSharedPreference(SPType.ping_sp).getString(PingService.PING_LAST_UUID, null)); + spg.getSharedPreference(SPType.PING).registerOnSharedPreferenceChangeListener(listener); + checkLastUUID(spg.getSharedPreference(SPType.PING).getString(PingService.PING_LAST_UUID, null)); } @@ -180,7 +213,7 @@ public void onResume() { public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: PingFragment destroyed"); - spg.getSharedPreference(SPType.ping_sp).unregisterOnSharedPreferenceChangeListener(listener); + spg.getSharedPreference(SPType.PING).unregisterOnSharedPreferenceChangeListener(listener); workInfoLiveData.removeObserver(observer); } @@ -198,9 +231,9 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { } }; - spg.getSharedPreference(SPType.ping_sp).registerOnSharedPreferenceChangeListener(listener); + spg.getSharedPreference(SPType.PING).registerOnSharedPreferenceChangeListener(listener); - checkLastUUID(spg.getSharedPreference(SPType.ping_sp).getString(PingService.PING_LAST_UUID, null)); + checkLastUUID(spg.getSharedPreference(SPType.PING).getString(PingService.PING_LAST_UUID, null)); } @SuppressLint("UnspecifiedRegisterReceiverFlag") @@ -213,21 +246,21 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, workManager = WorkManager.getInstance(ct); verticalLL = v.findViewById(R.id.ping_vertical_ll); horizontalLL1 = verticalLL.findViewById(R.id.ping_horizontal1_ll); - + pingTextView = v.findViewById(R.id.ping_output); toggleGroup = verticalLL.findViewById(R.id.ping_toggle_group); input = verticalLL.findViewById(R.id.ping_input); - input.setText(spg.getSharedPreference(SPType.ping_sp).getString("ping_input", "-w 5 8.8.8.8")); + input.setText(spg.getSharedPreference(SPType.PING).getString("ping_input", "-w 5 8.8.8.8")); repeatButton = v.findViewById(R.id.ping_repeat_button); setupRepeatButton(); repeatButton.setOnClickListener(view -> { Log.d(TAG, "onCreateView: Repeat button clicked"); - boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("repeat_ping", !isRepeat).apply(); + boolean isRepeat = spg.getSharedPreference(SPType.PING).getBoolean("repeat_ping", false); + spg.getSharedPreference(SPType.PING).edit().putBoolean("repeat_ping", !isRepeat).apply(); setupRepeatButton(); }); saveTextInputToSharedPreferences(input, "ping_input"); - boolean pingRunning = spg.getSharedPreference(SPType.ping_sp).getBoolean("ping_running", false); + boolean pingRunning = spg.getSharedPreference(SPType.PING).getBoolean("ping_running", false); if (pingRunning) { v.findViewById(R.id.ping_start).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); } else { @@ -240,14 +273,15 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, if (isRunning) { v.findViewById(R.id.ping_start).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); v.findViewById(R.id.ping_stop).setBackgroundColor(Color.TRANSPARENT); + pingTextView.setText(""); } else { v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); v.findViewById(R.id.ping_stop).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); toggleGroup.check(R.id.ping_stop); } } - }, SPType.ping_sp); + }, SPType.PING); input.setEnabled(!pingRunning); toggleGroup.addOnButtonCheckedListener((group, checkedId, isChecked) -> { Log.d(TAG, "onButtonChecked: " + checkedId); @@ -256,7 +290,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, case R.id.ping_start: v.findViewById(R.id.ping_start).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); v.findViewById(R.id.ping_stop).setBackgroundColor(Color.TRANSPARENT); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", true).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", true).apply(); Intent startIntent = new Intent(ct, PingService.class); startIntent.putExtra(PingService.PING_INTENT_COMMAND, input.getText().toString()); startIntent.putExtra(PingService.PING_INTENT_ENABLE, true); @@ -267,7 +301,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); v.findViewById(R.id.ping_stop).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); Intent stopIntent = new Intent(ct, PingService.class); stopIntent.putExtra(PingService.PING_INTENT_ENABLE, false); ct.startService(stopIntent); @@ -289,8 +323,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, metricsLL.setLayoutParams(foo1); metricsLL.addView(rttMetric); metricsLL.addView(packetLossMetric); - packetLossMetric.setVisibility(INVISIBLE); - horizontalLL1.addView(metricsLL); + packetLossMetric.setVisibility(GONE); + LinearLayout foobar= v.findViewById(R.id.ping_metric); + foobar.addView(metricsLL); + + +// horizontalLL1.addView(metricsLL); return v; } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PacketLossLine.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PacketLossLine.java index b8cae2e..0dac9f5 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PacketLossLine.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PacketLossLine.java @@ -51,4 +51,11 @@ public Point getPoint(){ .time(System.currentTimeMillis(), WritePrecision.MS); //ping does not provide timestamp for packet loss line } + @Override + public String toString() { + return "PacketLossLine{" + + "packetLoss=" + packetLoss + + ", packetsTransmitted=" + packetsTransmitted + + ", packetsReceived=" + packetsReceived + '}'; + } } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java index 2ac9b35..cd773cb 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java @@ -49,7 +49,7 @@ public IBinder onBind(Intent intent) { @Override public void onDestroy() { Log.d(TAG, "onDestroy: Stop logging service"); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); stopWorker(); } @@ -74,10 +74,10 @@ private void startWorker(String command) { .addTag(PingToLineProtocolWorker.TAG) .build(); - spg.getSharedPreference(SPType.ping_sp).edit().putString(PING_LAST_UUID, pingWR.getId().toString()).apply(); + spg.getSharedPreference(SPType.PING).edit().putString(PING_LAST_UUID, pingWR.getId().toString()).apply(); registerObserver(command); WorkContinuation workContinuation = workManager.beginWith(pingWR).then(pingToLineProtocolWR); - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)){ + if(spg.getSharedPreference(SPType.LOGGING).getBoolean("enable_influx", false)){ OneTimeWorkRequest influxDB2xUploadWorker = new OneTimeWorkRequest.Builder(InfluxDB2xUploadWorker.class) .setInputData(data) .addTag(uuid) @@ -89,17 +89,18 @@ private void startWorker(String command) { } private void stopWorker(){ - String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, ""); + String lastUUID = spg.getSharedPreference(SPType.PING).getString(PING_LAST_UUID, ""); if(lastUUID.equals("")) { Log.d(TAG, "stopWorker: no worker to stop!"); return; } workManager.cancelWorkById(UUID.fromString(lastUUID)); + workManager.cancelAllWorkByTag(PingWorker.TAG); } private void registerObserver(String command){ - String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, null); + String lastUUID = spg.getSharedPreference(SPType.PING).getString(PING_LAST_UUID, null); if(lastUUID != null) { UUID lastUUIDUUID = UUID.fromString(lastUUID); LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); @@ -109,7 +110,7 @@ private void registerObserver(String command){ switch (workInfo.getState()){ case SUCCEEDED: case FAILED: - if(spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false)){ + if(spg.getSharedPreference(SPType.PING).getBoolean("repeat_ping", false)){ Log.d(TAG, "registerObserver: Repeat ping"); startWorker(command); } else { @@ -145,7 +146,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: Intent is null, stopping service"); workManager.cancelAllWorkByTag(PingWorker.TAG); stopSelf(); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); return START_NOT_STICKY; } String command = intent.getStringExtra(PING_INTENT_COMMAND); @@ -153,10 +154,10 @@ public int onStartCommand(Intent intent, int flags, int startId) { if(!isEnabled){ stopWorker(); stopSelf(); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + spg.getSharedPreference(SPType.PING).edit().putBoolean("ping_running", false).apply(); return START_NOT_STICKY; } - String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, ""); + String lastUUID = spg.getSharedPreference(SPType.PING).getString(PING_LAST_UUID, ""); if(!lastUUID.isEmpty()){ stopWorker(); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingToLineProtocolWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingToLineProtocolWorker.java index 51d45ad..ec1ab58 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingToLineProtocolWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingToLineProtocolWorker.java @@ -54,10 +54,10 @@ public PingToLineProtocolWorker(@NonNull Context context, @NonNull WorkerParamet pingInput = gson.fromJson(iperf3InputString, PingInput.class); spg = SharedPreferencesGrouper.getInstance(getApplicationContext()); - File lineProtocolDirPath = new File(PingParameter.lineProtocolDirPath); + File lineProtocolDirPath = new File(pingInput.getParameter().getLineProtocolDirPath()); if(!lineProtocolDirPath.exists()){ if(!lineProtocolDirPath.mkdirs()){ - Log.e(TAG, "Error creating lineProtocolDirPath directory: " + PingParameter.lineProtocolDirPath); + Log.e(TAG, "Error creating lineProtocolDirPath directory: " + pingInput.getParameter().getLineProtocolDirPath()); } } } @@ -81,7 +81,7 @@ private LINEType getLineType(String line){ @Override public Result doWork() { Data.Builder output = new Data.Builder().putBoolean("pingUpload", false); - File myObj = new File(pingInput.getPingParameter().getLogfile()); + File myObj = new File(pingInput.getPingParameter().getLineProtocolFilePath()); Scanner scanner = null; try { scanner = new Scanner(myObj); @@ -112,7 +112,7 @@ public Result doWork() { pingInformations.add(pi); } scanner.close(); - File lineprotocolfile = new File(pingInput.getPingParameter().getLineProtocolFile()); + File lineprotocolfile = new File(pingInput.getPingParameter().getLineProtocolFilePath()); if(lineprotocolfile.exists()){ lineprotocolfile.delete(); try { @@ -124,7 +124,7 @@ public Result doWork() { } FileOutputStream pingStream = null; try { - pingStream = new FileOutputStream(pingInput.getPingParameter().getLineProtocolFile(), true); + pingStream = new FileOutputStream(pingInput.getPingParameter().getLineProtocolFilePath(), true); } catch (FileNotFoundException e) { Log.d(TAG, "doWork: " + e.toString()); Log.e(TAG, "doWork: Could not create FileOutputStream"); @@ -136,6 +136,11 @@ public Result doWork() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { point.addTags(GlobalVars.getInstance().get_dp().getTagsMap()); } + if(!pingInput.getSequenceUUID().isEmpty()) point.addTag("sequenceUUID", pingInput.getSequenceUUID()); + if(!pingInput.getTestUUID().isEmpty()) point.addTag("testUUID", pingInput.getTestUUID()); + if(!pingInput.getMeasurementUUID().isEmpty())point.addTag("measurementUUID", pingInput.getMeasurementUUID()); + if(!pingInput.getCampaignUUID().isEmpty()) point.addTag("campaignUUID", pingInput.getCampaignUUID()); + pingStream.write((point.toLineProtocol() + "\n").getBytes()); } catch (IOException e) { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingWorker.java index 4e21b6d..cbb286d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/Worker/PingWorker.java @@ -12,7 +12,9 @@ import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.graphics.Color; import android.util.Log; @@ -32,13 +34,16 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.MainActivity; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.PingParameter; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PacketLossLine; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PingInformation; @@ -80,10 +85,10 @@ public PingWorker(@NonNull Context context, @NonNull WorkerParameters workerPara notificationManager = (NotificationManager) ct.getSystemService(Context.NOTIFICATION_SERVICE); notificationBuilder = new NotificationCompat.Builder(ct, channelId); - File rawPath = new File(PingParameter.rawDirPath); + File rawPath = new File(pingInput.getParameter().getRawDirPath()); if(!rawPath.exists()){ if(!rawPath.mkdirs()){ - Log.e(TAG, "Error creating rawDirPath directory: " + PingParameter.rawDirPath); + Log.e(TAG, "Error creating rawDirPath directory: " + pingInput.getParameter().getRawDirPath()); } } @@ -93,7 +98,18 @@ public PingWorker(@NonNull Context context, @NonNull WorkerParameters workerPara } private ForegroundInfo createForegroundInfo(String progress) { - notification = notificationBuilder + Intent intent = new Intent(this.ct, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.putExtra("navigateToFragment", "PingFragment"); // Identifier for your fragment + + PendingIntent pendingIntent = PendingIntent.getActivity( + this.ct, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE + ); + + Notification notification = notificationBuilder .setContentTitle("Ping") .setContentText(progress) .setOngoing(true) @@ -101,11 +117,14 @@ private ForegroundInfo createForegroundInfo(String progress) { .setColor(Color.WHITE) .setSmallIcon(R.mipmap.ic_launcher_foreground) .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_DEFAULT) + .setContentIntent(pendingIntent) // 👈 attach pending intent here .build(); + return new ForegroundInfo(notificationID, notification, FOREGROUND_SERVICE_TYPE); } + @NonNull @Override public Result doWork() { @@ -128,15 +147,17 @@ public Result doWork() { Log.d(TAG, "doWork: executing " + String.join(" ", command)); int result = -1; + String error = ""; try { ProcessBuilder processBuilder = new ProcessBuilder(command); Process process = processBuilder.start(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - FileOutputStream pingStream = new FileOutputStream(pingInput.getPingParameter().getLogfile(), true); + FileOutputStream pingStream = new FileOutputStream(pingInput.getPingParameter().getRawLogFilePath(), true); PingParser pingParser = new PingParser(); String line; + while ((line = reader.readLine()) != null) { Log.d(TAG, "doWork: "+line); pingStream.write((line + "\n").getBytes()); @@ -147,12 +168,12 @@ public Result doWork() { Log.w(TAG, "doWork: Line or PingInformation is null, skipping line"); continue; } + switch (pingInformation.getLineType()){ case RTT: rtt = ((RTTLine)pingInformation).getRtt(); - progressOutput.putDouble(RTT, rtt); - - setProgressAsync(progressOutput.build()); + progressOutput.putString(RTT, new Gson().toJson((RTTLine)pingInformation)); +// setProgressAsync(progressOutput.build()); setForegroundAsync(createForegroundInfo(((RTTLine) pingInformation).getHost()+": " + rtt + " ms")); Log.d(TAG, "doWork: RTT: " + rtt); break; @@ -164,25 +185,36 @@ public Result doWork() { progressOutput.putString(REASON, "Request timeout"); break; case PACKET_LOSS: - double packetLoss = ((PacketLossLine)pingInformation).getPacketLoss(); - setProgressAsync(new Data.Builder().putDouble(PACKET_LOSS, packetLoss).build()); - Log.d(TAG, "doWork: Packet Loss: " + packetLoss); + PacketLossLine packetLoss = ((PacketLossLine)pingInformation); + progressOutput.putString(PACKET_LOSS, new Gson().toJson(packetLoss)); +// setProgressAsync(progressOutput.build()); + Log.d(TAG, "doWork: Packet Loss: " + packetLoss.toString()); break; case UNKNOWN: Log.w(TAG, "doWork: Unknown line type"); break; } + setProgressAsync(progressOutput.build()); if(this.isStopped()){ break; } + } + error = new BufferedReader( + new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); process.destroy(); pingStream.close(); reader.close(); result = process.waitFor(); + + + + Thread.sleep(200); // Sleep so that the Observer can process the last lines } catch (IOException e) { Log.e(TAG, "Error while executing ping command: " + e.toString()); return Result.failure(output.putString(REASON, "Error while executing ping command.").build()); @@ -191,9 +223,10 @@ public Result doWork() { return Result.failure(output.putString(REASON, "Error while waiting for ping command.").build()); } - if (result != 0) { + if (result != 0) {; Log.e(TAG, "Ping command failed with result: " + result); - return Result.failure(output.putString(REASON, "Ping command failed with result: " + result).build()); + Log.e(TAG, "Ping command failed because: "+error); + return Result.failure(output.putString(REASON, "Ping command failed: " + error).build()); } return Result.success(output.putBoolean(PING, true).build()); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SPType.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SPType.java index 9cefa5a..13064af 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SPType.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SPType.java @@ -9,55 +9,35 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences; public enum SPType { - logging_sp, - iperf3_sp, - ping_sp, - carrier_sp, - mobile_network_sp, - default_sp, - mqtt_sp; + LOGGING, + IPERF3, + PING, + CARRIER, + MOBILE_NETWORK, + MAIN, + MQTT; public String toString() { switch(this){ - case default_sp: - return "preferences"; - case logging_sp: - case ping_sp: - case carrier_sp: - case mqtt_sp: - case mobile_network_sp: - return super.toString(); + case LOGGING: + return "logging"; + case MQTT: + return "mqtt"; + case MOBILE_NETWORK: + return "mobile_network"; + case PING: + return "ping"; + case IPERF3: + return "iperf3"; + case CARRIER: + return "carrier"; + case MAIN: default: - return ""; + return "main"; } } - public static SPType fromString(String text) { - for (SPType b : SPType.values()) { - if (b.toString().equalsIgnoreCase(text)) { - return b; - } - } - return null; - } - public String toReadable(){ - String name = this.name().split("_")[0]; - switch(this){ - case logging_sp: - case ping_sp: - case carrier_sp: - case default_sp: - return name.substring(0,1).toUpperCase() + name.substring(1); - case mobile_network_sp: - return "Mobile Network"; - case iperf3_sp: - return "iPerf3"; - case mqtt_sp: - return "MQTT"; - default: - return null; - } - } + } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesGrouper.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesGrouper.java index 845c424..0215ff7 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesGrouper.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesGrouper.java @@ -30,8 +30,8 @@ public class SharedPreferencesGrouper { private final SharedPreferences iperf3SP; private final SharedPreferences mobileNetworkSP; private final SharedPreferences mqttSP; - private final SharedPreferences defaultSP; private final SharedPreferences pingSP; + private final SharedPreferences mainSP; private final Context ct; private ConcurrentHashMap > spMap = new ConcurrentHashMap<>(); public String getSharedPreferenceIdentifier(SPType key) { @@ -47,13 +47,13 @@ public void clearConfig(){ private SharedPreferencesGrouper( Context ct) { this.ct = ct; - loggingSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.logging_sp), Context.MODE_PRIVATE); - carrierSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.carrier_sp), Context.MODE_PRIVATE); - iperf3SP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.iperf3_sp), Context.MODE_PRIVATE); - pingSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.ping_sp), Context.MODE_PRIVATE); - mqttSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.mqtt_sp), Context.MODE_PRIVATE); - mobileNetworkSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.mobile_network_sp), Context.MODE_PRIVATE); - defaultSP = PreferenceManager.getDefaultSharedPreferences(ct); + loggingSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.LOGGING), Context.MODE_PRIVATE); + carrierSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.CARRIER), Context.MODE_PRIVATE); + iperf3SP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.IPERF3), Context.MODE_PRIVATE); + pingSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.PING), Context.MODE_PRIVATE); + mqttSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.MQTT), Context.MODE_PRIVATE); + mobileNetworkSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.MOBILE_NETWORK), Context.MODE_PRIVATE); + mainSP = ct.getSharedPreferences(getSharedPreferenceIdentifier(SPType.MAIN), Context.MODE_PRIVATE); } public static SharedPreferencesGrouper getInstance(Context ct) { @@ -66,26 +66,27 @@ public static SharedPreferencesGrouper getInstance(Context ct) { public SharedPreferences getSharedPreference(SPType key){ SharedPreferences sp; switch (key) { - case logging_sp: + case LOGGING: sp = loggingSP; break; - case carrier_sp: + case CARRIER: sp = carrierSP; break; - case iperf3_sp: + case IPERF3: sp = iperf3SP; break; - case ping_sp: + case PING: sp = pingSP; break; - case mobile_network_sp: + case MOBILE_NETWORK: sp = mobileNetworkSP; break; - case mqtt_sp: + case MQTT: sp = mqttSP; break; + case MAIN: default: - sp = defaultSP; + sp = mainSP; break; } return sp; diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIO.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIO.java index e5fecd0..ee018c9 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIO.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIO.java @@ -10,86 +10,155 @@ import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Resources; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; + +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.DataProvider.BuildInformation; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; public class SharedPreferencesIO { private static final String TAG = "SharedPreferencesIO"; public static String exportPreferences(Context context) { - HashMap sharedPreferences = SharedPreferencesGrouper.getInstance(context).getAllSharedPreferences(); - JSONObject preferencesJson = new JSONObject(); - for(SPType key : sharedPreferences.keySet()) { - SharedPreferences prefs = sharedPreferences.get(key); - JSONObject spJSON = new JSONObject(prefs.getAll()); - try { - preferencesJson.put(key.toString(), spJSON); - } catch (JSONException e) { - Log.e(TAG, "Failed to export preference "+key, e); - } + JSONArray jsonArray = null; + try (InputStream is = context.getResources().openRawResource(R.raw.config); + BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { + String json = reader.lines().collect(Collectors.joining()); + jsonArray = new JSONArray(json); + + } catch (Exception e) { + Log.e(TAG, "Failed to read or parse JSON array from config file", e); + return ""; } + + SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(context); try { - preferencesJson.put("BuildInformation", new BuildInformation().toJSON()); - return preferencesJson.toString(4); - } catch (JSONException e) { - Log.e(TAG, "Failed to Preference JSON to String", e); - return "{}"; + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject settingObject = jsonArray.getJSONObject(i); + if(settingObject.has("metadata")) continue; + String settingName = settingObject.getString("setting"); + JSONArray categoriesArray = settingObject.getJSONArray("categories"); + SPType spType = SPType.valueOf(settingName.toUpperCase()); + if(spType == null) { + Log.w(TAG, "Unknown SPType: " + settingName); + continue; + } + for (int j = 0; j < categoriesArray.length(); j++) { + JSONObject categorieObject = categoriesArray.getJSONObject(j); + JSONArray preferenceArray = categorieObject.getJSONArray("preferences"); + for (int k = 0; k < preferenceArray.length(); k++) { + JSONObject preferenceObject = preferenceArray.getJSONObject(k); + getValue(preferenceObject, spg.getSharedPreference(spType)); + } + } + } + } catch (Exception e) { + Log.e(TAG, "Failed to import preferences", e); + Toast.makeText(context, "Failed to import preferences", Toast.LENGTH_SHORT).show(); } + + return jsonArray.toString(); + } + private static void getValue(JSONObject jsonObject, SharedPreferences sp){ + try{ + String type = jsonObject.getString("type"); + String key = jsonObject.getString("key"); + switch (type){ + case "string": + jsonObject.put("value", sp.getString(key, "")); + break; + case "boolean": + jsonObject.put("value", sp.getBoolean(key, false)); + break; + case "set": + JSONArray jsonArray = new JSONArray(); + Set stringSet = sp.getStringSet(key, new HashSet<>()); + for (String string: stringSet) { + jsonArray.put(string); + } + jsonObject.put("value", jsonArray); + default: + Log.e(TAG, "getValue: could not get value of type: "+type); + break; + } + } catch (JSONException e) { + Log.e(TAG, "getValue: could not get data from JSON object");; + } + } + private static void putValue(JSONObject jsonObject, SharedPreferences sp){ + try{ + String type = jsonObject.getString("type"); + String key = jsonObject.getString("key"); + switch (type){ + case "string": + sp.edit().putString(key, jsonObject.getString("value")).apply(); + break; + case "boolean": + sp.edit().putBoolean(key, jsonObject.getBoolean("value")).apply(); + break; + case "set": + Set stringSet = new HashSet<>(); + JSONArray jsonArray = jsonObject.getJSONArray("value"); + if(jsonArray == null || jsonArray.length() == 0){ + break; + } + for (int i = 0; i < jsonArray.length(); i++) { + stringSet.add(jsonArray.getString(i)); + } + sp.edit().putStringSet(key, stringSet); + default: + Log.e(TAG, "putValue: could not put value of type: "+type); + break; + } + } catch (JSONException e) { + Log.e(TAG, "putValue: could not get data from JSON object");; + } + } public static void importPreferences(Context context, String jsonString) { + SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(context); try { - JSONObject spJSON = new JSONObject(jsonString); - - spJSON.keys().forEachRemaining(key -> { - SPType spType = SPType.fromString(key); - if (spType == null) { - Log.e(TAG, "Unknown preference type: " + key); - return; - } - SharedPreferences prefs = SharedPreferencesGrouper.getInstance(context).getSharedPreference(spType); - SharedPreferences.Editor editor = prefs.edit(); - @NonNull JSONObject preferences; - try { - preferences = spJSON.getJSONObject(key); - } catch (JSONException e) { - Log.e(TAG, "Failed to get preferences for: " + key, e); - return; + JSONArray spJSON = new JSONArray(jsonString); + for (int i = 0; i < spJSON.length(); i++) { + JSONObject settingObject = spJSON.getJSONObject(i); + if(settingObject.has("metadata")) continue; + String settingName = settingObject.getString("setting"); + JSONArray categoriesArray = settingObject.getJSONArray("categories"); + SPType spType = SPType.valueOf(settingName.toUpperCase()); + if(spType == null) { + Log.w(TAG, "Unknown SPType: " + settingName); + continue; } - preferences.keys().forEachRemaining(preferenceKey -> { - @NonNull Object value; - try { - value = preferences.get(preferenceKey); - } catch (JSONException e) { - Log.e(TAG, "Failed to get value for: " + preferenceKey, e); - return; + for (int j = 0; j < categoriesArray.length(); j++) { + JSONObject categorieObject = categoriesArray.getJSONObject(j); + JSONArray preferenceArray = categorieObject.getJSONArray("preferences"); + for (int k = 0; k < preferenceArray.length(); k++) { + JSONObject preferenceObject = preferenceArray.getJSONObject(k); + putValue(preferenceObject, spg.getSharedPreference(spType)); } - if (value instanceof Boolean) { - editor.putBoolean(preferenceKey, (Boolean) value); - } else if (value instanceof Float) { - editor.putFloat(preferenceKey, (Float) value); - } else if (value instanceof Integer) { - editor.putInt(preferenceKey, (Integer) value); - } else if (value instanceof Long) { - editor.putLong(preferenceKey, (Long) value); - } else if (value instanceof String) { - editor.putString(preferenceKey, (String) value); - } - }); - editor.apply(); - Log.d(TAG, "Imported: " + key); - }); + } + } } catch (Exception e) { Log.e(TAG, "Failed to import preferences", e); Toast.makeText(context, "Failed to import preferences", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIOFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIOFragment.java index 0928739..464dedd 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIOFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Preferences/SharedPreferencesIOFragment.java @@ -41,7 +41,6 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -50,6 +49,7 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.SettingPreferences.ClearPreferencesListener; +import org.json.JSONArray; import org.json.JSONObject; public class SharedPreferencesIOFragment extends Fragment implements ClearPreferencesListener { @@ -154,6 +154,8 @@ private void addSharedPreferencesViews() { LinearLayout preferencesLayout = new LinearLayout(context); preferencesLayout.setOrientation(LinearLayout.VERTICAL); for (Map.Entry spEntry : SharedPreferencesGrouper.getInstance(context).getAllSharedPreferences().entrySet()) { + SPType spType = spEntry.getKey(); + if(spType.equals(SPType.IPERF3) || spType.equals(SPType.PING) || spType.equals(SPType.CARRIER)) continue; preferencesLayout.addView(generateSharedPreferencesView(spEntry.getKey(), spEntry.getValue())); } @@ -194,13 +196,12 @@ private void exportPreferencesToFile(Uri uri) { private List getKeysFromJson(String jsonString) { List keys = new ArrayList<>(); try { - JSONObject jsonObject = new JSONObject(jsonString); - Iterator iter = jsonObject.keys(); - while (iter.hasNext()) { - String current = iter.next(); - if (SPType.fromString(current) != null) { - keys.add(current); - } + JSONArray jsonArray = new JSONArray(jsonString); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject setting = jsonArray.getJSONObject(i); + if(setting.has("metadata")) continue; + String settingString = setting.getString("setting"); + keys.add(settingString); } } catch (Exception e) { @@ -231,12 +232,17 @@ private void importPreferencesFromFile(Uri uri) { private @NonNull MultiSelectDialogFragment getMultiSelectDialogFragment(String jsonString, List keys) { MultiSelectDialogFragment.OnMultiSelectListener listener = selectedItems -> { try { - JSONObject jsonObject = new JSONObject(jsonString); - JSONObject filteredJsonObject = new JSONObject(); - for (String key : selectedItems) { - filteredJsonObject.put(key, jsonObject.get(key)); + JSONArray jsonArray = new JSONArray(jsonString); + JSONArray filteredjsonArray = new JSONArray(); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if(jsonObject.has("metadata")) continue; + String setting = jsonObject.getString("setting"); + if(!selectedItems.contains(setting)) continue; + filteredjsonArray.put(jsonObject); + } - SharedPreferencesIO.importPreferences(context, filteredJsonObject.toString()); + SharedPreferencesIO.importPreferences(context, filteredjsonArray.toString()); onPreferenceChanged(); showToast("Config imported"); } catch (Exception e) { @@ -264,7 +270,7 @@ private LinearLayout generateSharedPreferencesView(SPType type, SharedPreference headerLayout.setPadding(16, 16, 16, 16); // Add padding TextView typeTextView = new TextView(context); - typeTextView.setText(type.toReadable()); + typeTextView.setText(type.toString().replace("_", " ")); typeTextView.setTextSize(18); typeTextView.setTypeface(typeTextView.getTypeface(), Typeface.BOLD); typeTextView.setTextColor(context.getColor(R.color.design_default_color_primary)); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java index 103b9b6..53f2bbf 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java @@ -375,7 +375,7 @@ public void run() { } else { cellInformationList.forEach(cellInformation -> addCellInformationToView(cellInformation)); } - if (spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false)) { + if (spg.getSharedPreference(SPType.MAIN).getBoolean("show_neighbour_cells", false)) { if(!neighborCells.isEmpty()){ neighborCells.forEach(cellInformation -> addCellInformationToView(cellInformation)); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/FileConfigReceiver.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/FileConfigReceiver.java new file mode 100644 index 0000000..0034c4e --- /dev/null +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/FileConfigReceiver.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2025 Peter Hasse + * SPDX-FileCopyrightText: 2025 Johann Hackler + * SPDX-FileCopyrightText: 2025 Fraunhofer FOKUS + * + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesIO; + +public class FileConfigReceiver extends BroadcastReceiver { + private static final String TAG = "FileConfigReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + String filePath = intent.getStringExtra("filePath"); + Log.e(TAG, "onReceive: got following path"+ filePath); + if (filePath == null) { + Log.e(TAG, "onReceive: filePath is null"); + return; + } + try { + String jsonString = new String(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(filePath))); + if (jsonString.isEmpty()) { + Log.e(TAG, "onReceive: JSON string is empty"); + return; + } + Log.i(TAG, "onReceive: Successfully read JSON from file: " + filePath); + SharedPreferencesIO.importPreferences(context, jsonString); + } catch (java.io.IOException e) { + Log.e(TAG, "Failed to read JSON from file: " + filePath, e); + } + + } +} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/JsonConfigReceiver.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/JsonConfigReceiver.java new file mode 100644 index 0000000..8b6c621 --- /dev/null +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Receiver/JsonConfigReceiver.java @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2025 Peter Hasse + * SPDX-FileCopyrightText: 2025 Johann Hackler + * SPDX-FileCopyrightText: 2025 Fraunhofer FOKUS + * + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesIO; + +public class JsonConfigReceiver extends BroadcastReceiver { + private final String TAG = "JsonConfigReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + String jsonString = intent.getStringExtra("jsonData"); + Log.e(TAG, "onReceive: got jsonString:"+jsonString ); + if (jsonString == null) { + return; + } + SharedPreferencesIO.importPreferences(context, jsonString); + } +} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/LoggingSettingsFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/LoggingSettingsFragment.java index ba05905..4af5b07 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/LoggingSettingsFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/LoggingSettingsFragment.java @@ -26,12 +26,12 @@ public class LoggingSettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { - public static final String TAG = "PreferenceSettings"; + public static final String TAG = "LoggingSettingsFragment"; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(requireContext()); - getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.logging_sp)); + getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.LOGGING)); setPreferencesFromResource(R.xml.preference_logging, rootKey); Objects.requireNonNull(getPreferenceScreen().getSharedPreferences()) .registerOnSharedPreferenceChangeListener(this); diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MQTTSettingsFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MQTTSettingsFragment.java index c896675..86f468d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MQTTSettingsFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MQTTSettingsFragment.java @@ -10,7 +10,6 @@ import android.content.SharedPreferences; import android.os.Bundle; -import android.text.InputType; import android.util.Log; import androidx.annotation.Nullable; @@ -29,7 +28,7 @@ public class MQTTSettingsFragment extends PreferenceFragmentCompat implements Sh @Override public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(requireContext()); - getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.mqtt_sp)); + getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.MQTT)); setPreferencesFromResource(R.xml.preference_mqtt, rootKey); Objects.requireNonNull(getPreferenceScreen().getSharedPreferences()) .registerOnSharedPreferenceChangeListener(this); @@ -44,6 +43,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Null if (key.equals("enable_mqtt")) { boolean logger = sharedPreferences.getBoolean("enable_mqtt", false); Log.d(TAG, "Logger update: " + logger); + _switch.setChecked(logger); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java index cbaae36..3b989c9 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java @@ -97,7 +97,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { ct = requireContext(); plmnId = ct.getString(R.string.select_plmn); accessNetworkType = ct.getString(R.string.access_networktype); - preferences = SharedPreferencesGrouper.getInstance(ct).getSharedPreference(SPType.mobile_network_sp); + preferences = SharedPreferencesGrouper.getInstance(ct).getSharedPreference(SPType.MOBILE_NETWORK); tm = gv.getTm(); pm = gv.getPm(); int sdk_version = Build.VERSION.SDK_INT; @@ -186,7 +186,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { gv = GlobalVars.getInstance(); - getPreferenceManager().setSharedPreferencesName(SharedPreferencesGrouper.getInstance(requireContext()).getSharedPreferenceIdentifier(SPType.carrier_sp)); + getPreferenceManager().setSharedPreferencesName(SharedPreferencesGrouper.getInstance(requireContext()).getSharedPreferenceIdentifier(SPType.MOBILE_NETWORK)); setPreferencesFromResource(R.xml.preference_mobile_network, rootKey); Preference button = getPreferenceManager().findPreference("apply_cs_settings"); if (button != null) { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/SettingsFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/SettingsFragment.java index 1d56dc2..0e49edc 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/SettingsFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/SettingsFragment.java @@ -12,6 +12,7 @@ import android.os.Build; import android.os.Bundle; import android.telephony.SubscriptionInfo; +import android.util.Log; import android.widget.Toast; import androidx.activity.OnBackPressedCallback; @@ -33,14 +34,16 @@ public class SettingsFragment extends PreferenceFragmentCompat { + private static final String TAG = "SettingsFragment"; + @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(requireContext()); PreferenceManager pfm = getPreferenceManager(); - getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.default_sp)); - pfm.setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.default_sp)); + getPreferenceManager().setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.MAIN)); + pfm.setSharedPreferencesName(spg.getSharedPreferenceIdentifier(SPType.MAIN)); pfm.setSharedPreferencesMode(Context.MODE_PRIVATE); - setPreferencesFromResource(R.xml.preference, rootKey); + setPreferencesFromResource(R.xml.preference_main, rootKey); ListPreference sub_select = pfm.findPreference("select_subscription"); if (sub_select != null) { @@ -64,6 +67,15 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { } } + for (String key : pfm.getSharedPreferences().getAll().keySet()) { + Preference pref = pfm.findPreference(key); + if (pref != null) { + pref.setOnPreferenceChangeListener((preference, newValue) -> { + Log.d(TAG, "Preference changed: " + preference.getKey() + " -> " + newValue); + return true; + }); + } + } Preference button = pfm.findPreference("reset_modem"); if (button != null) { if (GlobalVars.getInstance().isCarrier_permissions()) { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeController.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeController.java deleted file mode 100644 index 7777140..0000000 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeController.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Peter Hasse - * SPDX-FileCopyrightText: 2023 Johann Hackler - * SPDX-FileCopyrightText: 2023 Fraunhofer FOKUS - * - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -//from https://codeburst.io/android-swipe-menu-with-recyclerview-8f28a235ff28 - -package de.fraunhofer.fokus.OpenMobileNetworkToolkit; - -import static androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_SWIPE; -import static androidx.recyclerview.widget.ItemTouchHelper.Callback; - -import android.annotation.SuppressLint; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.RectF; -import android.view.MotionEvent; -import android.view.View; - -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.RecyclerView; - -enum ButtonsState { - GONE, - LEFT_VISIBLE, - RIGHT_VISIBLE -} - -public class SwipeController extends Callback { - - private static final float buttonWidth = 300; - private boolean swipeBack = false; - private ButtonsState buttonShowedState = ButtonsState.GONE; - private RectF buttonInstance = null; - private RecyclerView.ViewHolder currentItemViewHolder = null; - private SwipeControllerActions buttonsActions = null; - - public SwipeController(SwipeControllerActions buttonsActions) { - this.buttonsActions = buttonsActions; - } - - @Override - public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { - return makeMovementFlags(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT); - } - - @Override - public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, - RecyclerView.ViewHolder target) { - return false; - } - - @Override - public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { - - } - - @Override - public int convertToAbsoluteDirection(int flags, int layoutDirection) { - if (swipeBack) { - swipeBack = buttonShowedState != ButtonsState.GONE; - return 0; - } - return super.convertToAbsoluteDirection(flags, layoutDirection); - } - - @Override - public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, - float dX, float dY, int actionState, boolean isCurrentlyActive) { - if (actionState == ACTION_STATE_SWIPE) { - if (buttonShowedState != ButtonsState.GONE) { - if (buttonShowedState == ButtonsState.LEFT_VISIBLE) { - dX = Math.max(dX, buttonWidth); - } - if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) { - dX = Math.min(dX, -buttonWidth); - } - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, - isCurrentlyActive); - } else { - setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, - isCurrentlyActive); - } - } - - if (buttonShowedState == ButtonsState.GONE) { - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); - } - currentItemViewHolder = viewHolder; - } - - @SuppressLint("ClickableViewAccessibility") - private void setTouchListener(final Canvas c, final RecyclerView recyclerView, - final RecyclerView.ViewHolder viewHolder, final float dX, - final float dY, final int actionState, - final boolean isCurrentlyActive) { - recyclerView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - swipeBack = event.getAction() == MotionEvent.ACTION_CANCEL || - event.getAction() == MotionEvent.ACTION_UP; - if (swipeBack) { - if (dX < -buttonWidth) { - buttonShowedState = ButtonsState.RIGHT_VISIBLE; - } else if (dX > buttonWidth) { - buttonShowedState = ButtonsState.LEFT_VISIBLE; - } - - if (buttonShowedState != ButtonsState.GONE) { - setTouchDownListener(c, recyclerView, viewHolder, dX, dY, actionState, - isCurrentlyActive); - setItemsClickable(recyclerView, false); - } - } - return false; - } - }); - } - - @SuppressLint("ClickableViewAccessibility") - private void setTouchDownListener(final Canvas c, final RecyclerView recyclerView, - final RecyclerView.ViewHolder viewHolder, final float dX, - final float dY, final int actionState, - final boolean isCurrentlyActive) { - recyclerView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - setTouchUpListener(c, recyclerView, viewHolder, dX, dY, actionState, - isCurrentlyActive); - } - return false; - } - }); - } - - @SuppressLint("ClickableViewAccessibility") - private void setTouchUpListener(final Canvas c, final RecyclerView recyclerView, - final RecyclerView.ViewHolder viewHolder, final float dX, - final float dY, final int actionState, - final boolean isCurrentlyActive) { - recyclerView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP) { - SwipeController.super.onChildDraw(c, recyclerView, viewHolder, 0F, dY, - actionState, isCurrentlyActive); - recyclerView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return false; - } - }); - setItemsClickable(recyclerView, true); - swipeBack = false; - - if (buttonsActions != null && buttonInstance != null && - buttonInstance.contains(event.getX(), event.getY())) { - if (buttonShowedState == ButtonsState.LEFT_VISIBLE) { - buttonsActions.onLeftClicked(viewHolder.getAdapterPosition()); - } else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) { - buttonsActions.onRightClicked(viewHolder.getAdapterPosition()); - } - } - buttonShowedState = ButtonsState.GONE; - currentItemViewHolder = null; - } - return false; - } - }); - } - - private void setItemsClickable(RecyclerView recyclerView, boolean isClickable) { - for (int i = 0; i < recyclerView.getChildCount(); ++i) { - recyclerView.getChildAt(i).setClickable(isClickable); - } - } - - private void drawButtons(Canvas c, RecyclerView.ViewHolder viewHolder) { - float buttonWidthWithoutPadding = buttonWidth - 20; - float corners = 16; - - View itemView = viewHolder.itemView; - Paint p = new Paint(); - - RectF leftButton = new RectF(itemView.getLeft(), itemView.getTop(), - itemView.getLeft() + buttonWidthWithoutPadding, itemView.getBottom()); - p.setColor(Color.BLUE); - c.drawRoundRect(leftButton, corners, corners, p); - drawText("EDIT", c, leftButton, p); - - RectF rightButton = - new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop(), - itemView.getRight(), itemView.getBottom()); - p.setColor(Color.CYAN); - c.drawRoundRect(rightButton, corners, corners, p); - drawText("STOP", c, rightButton, p); - - buttonInstance = null; - if (buttonShowedState == ButtonsState.LEFT_VISIBLE) { - buttonInstance = leftButton; - } else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) { - buttonInstance = rightButton; - } - } - - private void drawText(String text, Canvas c, RectF button, Paint p) { - float textSize = 60; - p.setColor(Color.WHITE); - p.setAntiAlias(true); - p.setTextSize(textSize); - - float textWidth = p.measureText(text); - c.drawText(text, button.centerX() - (textWidth / 2), button.centerY() + (textSize / 2), p); - } - - public void onDraw(Canvas c) { - if (currentItemViewHolder != null) { - drawButtons(c, currentItemViewHolder); - } - } -} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeControllerActions.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeControllerActions.java deleted file mode 100644 index 4e7ab37..0000000 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SwipeControllerActions.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Peter Hasse - * SPDX-FileCopyrightText: 2023 Johann Hackler - * SPDX-FileCopyrightText: 2023 Fraunhofer FOKUS - * - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -//from https://codeburst.io/android-swipe-menu-with-recyclerview-8f28a235ff28 - -package de.fraunhofer.fokus.OpenMobileNetworkToolkit; - -public abstract class SwipeControllerActions { - - public void onLeftClicked(int position) { - } - - public void onRightClicked(int position) { - } - -} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_iperf3_input.xml b/app/src/main/res/layout/fragment_iperf3_input.xml index 0e7f743..6bdf0db 100644 --- a/app/src/main/res/layout/fragment_iperf3_input.xml +++ b/app/src/main/res/layout/fragment_iperf3_input.xml @@ -101,7 +101,7 @@ diff --git a/app/src/main/res/layout/fragment_ping.xml b/app/src/main/res/layout/fragment_ping.xml index ccc4af1..62fefab 100644 --- a/app/src/main/res/layout/fragment_ping.xml +++ b/app/src/main/res/layout/fragment_ping.xml @@ -109,11 +109,41 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" - android:orientation="horizontal" + android:orientation="vertical" android:baselineAligned="false"> + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 246b554..1dd1095 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -133,7 +133,7 @@ android:id="@+id/settingsFragment" android:name="de.fraunhofer.fokus.OpenMobileNetworkToolkit.SettingPreferences.SettingsFragment" android:label="SettingsFragment" - tools:layout="@xml/preference"> + tools:layout="@xml/preference_main"> diff --git a/app/src/main/res/raw/config.json b/app/src/main/res/raw/config.json new file mode 100644 index 0000000..1763930 --- /dev/null +++ b/app/src/main/res/raw/config.json @@ -0,0 +1,519 @@ +[ + { + "setting": "logging", + "categories": [ + { + "name": "logging_service", + "preferences": [ + { + "key": "enable_logging", + "value": null, + "type": "boolean" + }, + { + "key": "start_logging_on_boot", + "value": null, + "type": "boolean" + }, + { + "key": "logging_interval", + "value": null, + "type": "string" + } + ] + }, + { + "name": "local_logging", + "preferences": [ + { + "key": "enable_local_influx_log", + "value": null, + "type": "boolean" + }, + { + "key": "enable_local_file_log", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "remote_logging", + "preferences": [ + { + "key": "enable_influx", + "value": null, + "type": "boolean" + }, + { + "key": "influx_URL", + "value": null, + "type": "string" + }, + { + "key": "influx_org", + "value": null, + "type": "string" + }, + { + "key": "influx_token", + "value": null, + "type": "string" + }, + { + "key": "influx_bucket", + "value": null, + "type": "string" + } + ] + }, + { + "name": "logging_content", + "preferences": [ + { + "key": "fake_location", + "value": null, + "type": "boolean" + }, + { + "key": "measurement_name", + "value": null, + "type": "string" + }, + { + "key": "tags", + "value": null, + "type": "string" + }, + { + "key": "influx_network_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_signal_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_cell_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_neighbour_cells", + "value": null, + "type": "boolean" + }, + { + "key": "influx_throughput_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_wifi_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_battery_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_ip_address_data", + "value": null, + "type": "boolean" + } + ] + } + ] + }, + { + "setting": "main", + "categories": [ + { + "name": "home_screen_settings", + "preferences": [ + { + "key": "show_neighbour_cells", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "notification_settings", + "preferences": [ + { + "key": "enable_radio_notification", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "app_settings", + "preferences": [ + { + "key": "device_name", + "value": null, + "type": "string" + }, + { + "key": "select_subscription", + "value": null, + "type": "string" + } + ] + } + ] + }, + { + "setting": "mqtt", + "categories": [ + { + "name": "mqtt_service", + "preferences": [ + { + "key": "enable_mqtt", + "value": null, + "type": "boolean" + }, + { + "key": "enable_mqtt_on_boot", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "mqtt_credentials", + "preferences": [ + { + "key": "mqtt_host", + "value": null, + "type": "string" + }, + { + "key": "mqtt_client_username", + "value": null, + "type": "string" + }, + { + "key": "mqtt_client_password", + "value": null, + "type": "string" + } + ] + } + ] + }, + { + "setting": "mobile_network", + "categories": [ + { + "name": "radio_settings", + "preferences": [ + { + "key": "select_network_type", + "value": null, + "type": "string" + }, + { + "key": "add_plmn", + "value": null, + "type": "string" + }, + { + "key": "persist_boot", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_12_api_31_(s)", + "preferences": [ + { + "key": "edit_text_EPDG_STATIC_ADDRESS", + "value": null, + "type": "string" + }, + { + "key": "multi_select_KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY", + "value": null, + "type": "set" + }, + { + "key": "switch_KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_ENABLE_2G", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_11_api_30_(r)", + "preferences": [ + { + "key": "switch_KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_WORLD_MODE_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_WFC_MODE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_WFC_ROAMING_MODE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "edit_text_KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY", + "value": null, + "type": "string" + }, + { + "key": "edit_text_KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_10_api_29_(q)", + "preferences": [ + { + "key": "switch_KEY_FORCE_HOME_NETWORK_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_PREFER_2G_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_SETTINGS_ENABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_ENHANCED_4G_LTE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_PROVISIONED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VT_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_ENHANCED_4G_LTE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_IMS_APN_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_PRESET_APN_DETAILS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_SIM_LOCK_SETTINGS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_ALLOW_ADDING_APNS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_APN_EXPAND_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_IMS_GBA_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "list_KEY_VOLTE_REPLACEMENT_RAT_INT9", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_AUTO_RETRY_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_WORLD_PHONE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "list_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", + "value": null, + "type": "string" + }, + { + "key": "list_KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_8_api_27_(0_mr1)", + "preferences": [ + { + "key": "switch_KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL", + "value": null, + "type": "boolean" + } + ] + } + ] + }, + { + "metadata": { + "version": "0.7", + "code": 7, + "gitHash": "377044e" + } + } +] \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6770bd6..51d8c75 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,14 +7,14 @@ --> - OpenMobileNetworkToolkit + OpenMobileNetworkToolkit Android Testing - Samsung IMS - Sony Service - Nokia enable SA - Huawei Project - Mediatek IMS - iPerf3 + Samsung IMS + Sony Service + Nokia enable SA + Huawei Project + Mediatek IMS + iPerf3 Send Logging Service This app is provided by NGNI a department of Fraunhofer FOKUS. \n\nhttps://www.fokus.fraunhofer.de/go/ngni \n\nThis software is licensed under BSD 3-Clause Clear License https://spdx.org/licenses/BSD-3-Clause-Clear.html \n\nAuthors: \n\nPeter Hasse \nMohsin Nisar \nJohann Hackler @@ -104,7 +104,7 @@ Exit\n xiaomi Applied on SIM / network change - Show neighbour cells\n + Show neighbour cells Home screen settings App settings Android IMS> @@ -121,7 +121,7 @@ MQTT Client Password MQTT-Broker Address, including Port MQTT-Broker Address - tcp://192.168.213.89:1883 + 192.168.213.89:1883 MQTT Service @@ -249,6 +249,35 @@ Enterprise 2 Enterprise 3 filter string + This will log NetworkInformation to InfluxDB. Like NetworkOperatorName, SimOperatorName, DataNetworkType. + This will log SignalStrength to InfluxDB. Like RSRP, RSRQ from the SignalStrength API. + This will log CellInformation to InfluxDB. Like CellId, MCC, MNC, PCI, but also RSRP, RSRQ from the CellInformation API. + This will log neighbour CellInformation data to InfluxDB. Like CellId, MCC, MNC, PCI, but also RSRP, RSRQ from the CellInformation API. + This will log InterfaceThroughput data to InfluxDB. Like download and upload throughput, what the phone thinks what is currently possible. + This will log WifiInformation data to InfluxDB. Like SSID, BSSID, RSSI, Frequency, LinkSpeed, and WifiStandard. + This will log BatteryInformation data to InfluxDB. Like BatteryLevel and Charging Status. + This will log IPAddressInformation data to InfluxDB. Like IPv4 and IPv6 addresses, and the interface name. + Click here for Android Doc + This configures a remote InfluxDB instance to log data to. + This configures a local InfluxDB instance, running on the Device, to log data to. EXPERIMENTAL + This configures the logging Service of OMNT. + Influx URL, it can either be http://IP:8086, https://IP:8086, or any hostname. + Influx ORG Name, or ID. + Influx TOKEN + Influx Bucket Name or ID. + Enables MQTT Services for OMNT. + Section to set Credentials for MQTT. + MQTT Broker Address + MQTT Client Password. + Opens Link to Android Doc. + Select Network Type + Shows neighbour cells only when connected to a network and is announced by the network. + Set unique device name. + Configure the Logging Parameter. + Configure Mobile Network Settings, only if the App has Carrier Permissions. + Reboots the modem, only possible when OMNT has Carrier Permissions. + Configure MQTT for OMNT. + Import/Export Config of OMNT. \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 730352f..6f80172 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -27,10 +27,12 @@ bold center 2dp + @color/material_dynamic_secondary60 + + + \ No newline at end of file diff --git a/app/src/main/res/xml/preference_logging.xml b/app/src/main/res/xml/preference_logging.xml index 494d3ba..73631bf 100644 --- a/app/src/main/res/xml/preference_logging.xml +++ b/app/src/main/res/xml/preference_logging.xml @@ -13,16 +13,19 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:title="Logging Service" + android:summary="@string/logging_service_summary" app:iconSpaceReserved="false"> @@ -56,11 +62,13 @@ @@ -69,6 +77,8 @@ app:iconSpaceReserved="false" app:key="influx_URL" app:title="@string/influx_url" + android:defaultValue="http://IP:8086" + app:summary="@string/influx_url_summary" app:useSimpleSummaryProvider="true" /> @@ -101,6 +117,7 @@ @@ -108,6 +125,7 @@ @@ -116,52 +134,67 @@ app:key="tags" app:summary="@string/tags_summary" app:title="@string/tags" + android:defaultValue="" app:useSimpleSummaryProvider="true" /> - diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference_main.xml similarity index 86% rename from app/src/main/res/xml/preference.xml rename to app/src/main/res/xml/preference_main.xml index f0b603b..79aae8c 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference_main.xml @@ -18,6 +18,7 @@ @@ -41,6 +43,8 @@ @@ -48,12 +52,14 @@ android:icon="@drawable/ic_baseline_code_24" app:fragment="de.fraunhofer.fokus.OpenMobileNetworkToolkit.SettingPreferences.LoggingSettingsFragment" app:key="log_settings" + android:summary="@string/log_settings_summary" app:dependency="device_name" app:title="Logging" /> diff --git a/app/src/main/res/xml/preference_mobile_network.xml b/app/src/main/res/xml/preference_mobile_network.xml index 7f60f20..025b673 100644 --- a/app/src/main/res/xml/preference_mobile_network.xml +++ b/app/src/main/res/xml/preference_mobile_network.xml @@ -14,9 +14,23 @@ + + + + + + @@ -32,15 +35,16 @@ @@ -56,7 +61,9 @@ app:dependency="enable_mqtt" app:iconSpaceReserved="false" app:key="mqtt_client_password" + android:defaultValue="PASSWORD" app:title="@string/mqtt_client_password" + android:summary="@string/mqtt_client_password_summary" app:useSimpleSummaryProvider="true" /> diff --git a/build.gradle b/build.gradle index df35d7a..75db35a 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.10.1' + classpath 'com.android.tools.build:gradle:8.13.1' def nav_version = "2.5.3" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21' diff --git a/docs/OpenMobileNetworkToolkit.md b/docs/OpenMobileNetworkToolkit.md index c903689..f0b599b 100644 --- a/docs/OpenMobileNetworkToolkit.md +++ b/docs/OpenMobileNetworkToolkit.md @@ -22,4 +22,5 @@ * [Mobile Network](settings/mobile_network.md) * [Set subscription](settings/set_subscrption.md) * [Reboot Modem](settings/reboot_modem.md) - \ No newline at end of file + +* Auto generated [Preferences](./preferences.md) \ No newline at end of file diff --git a/docs/config.json b/docs/config.json new file mode 100644 index 0000000..1763930 --- /dev/null +++ b/docs/config.json @@ -0,0 +1,519 @@ +[ + { + "setting": "logging", + "categories": [ + { + "name": "logging_service", + "preferences": [ + { + "key": "enable_logging", + "value": null, + "type": "boolean" + }, + { + "key": "start_logging_on_boot", + "value": null, + "type": "boolean" + }, + { + "key": "logging_interval", + "value": null, + "type": "string" + } + ] + }, + { + "name": "local_logging", + "preferences": [ + { + "key": "enable_local_influx_log", + "value": null, + "type": "boolean" + }, + { + "key": "enable_local_file_log", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "remote_logging", + "preferences": [ + { + "key": "enable_influx", + "value": null, + "type": "boolean" + }, + { + "key": "influx_URL", + "value": null, + "type": "string" + }, + { + "key": "influx_org", + "value": null, + "type": "string" + }, + { + "key": "influx_token", + "value": null, + "type": "string" + }, + { + "key": "influx_bucket", + "value": null, + "type": "string" + } + ] + }, + { + "name": "logging_content", + "preferences": [ + { + "key": "fake_location", + "value": null, + "type": "boolean" + }, + { + "key": "measurement_name", + "value": null, + "type": "string" + }, + { + "key": "tags", + "value": null, + "type": "string" + }, + { + "key": "influx_network_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_signal_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_cell_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_neighbour_cells", + "value": null, + "type": "boolean" + }, + { + "key": "influx_throughput_data", + "value": null, + "type": "boolean" + }, + { + "key": "log_wifi_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_battery_data", + "value": null, + "type": "boolean" + }, + { + "key": "influx_ip_address_data", + "value": null, + "type": "boolean" + } + ] + } + ] + }, + { + "setting": "main", + "categories": [ + { + "name": "home_screen_settings", + "preferences": [ + { + "key": "show_neighbour_cells", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "notification_settings", + "preferences": [ + { + "key": "enable_radio_notification", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "app_settings", + "preferences": [ + { + "key": "device_name", + "value": null, + "type": "string" + }, + { + "key": "select_subscription", + "value": null, + "type": "string" + } + ] + } + ] + }, + { + "setting": "mqtt", + "categories": [ + { + "name": "mqtt_service", + "preferences": [ + { + "key": "enable_mqtt", + "value": null, + "type": "boolean" + }, + { + "key": "enable_mqtt_on_boot", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "mqtt_credentials", + "preferences": [ + { + "key": "mqtt_host", + "value": null, + "type": "string" + }, + { + "key": "mqtt_client_username", + "value": null, + "type": "string" + }, + { + "key": "mqtt_client_password", + "value": null, + "type": "string" + } + ] + } + ] + }, + { + "setting": "mobile_network", + "categories": [ + { + "name": "radio_settings", + "preferences": [ + { + "key": "select_network_type", + "value": null, + "type": "string" + }, + { + "key": "add_plmn", + "value": null, + "type": "string" + }, + { + "key": "persist_boot", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_12_api_31_(s)", + "preferences": [ + { + "key": "edit_text_EPDG_STATIC_ADDRESS", + "value": null, + "type": "string" + }, + { + "key": "multi_select_KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY", + "value": null, + "type": "set" + }, + { + "key": "switch_KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_ENABLE_2G", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_11_api_30_(r)", + "preferences": [ + { + "key": "switch_KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_WORLD_MODE_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_WFC_MODE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_WFC_ROAMING_MODE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "edit_text_KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY", + "value": null, + "type": "string" + }, + { + "key": "edit_text_KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_10_api_29_(q)", + "preferences": [ + { + "key": "switch_KEY_FORCE_HOME_NETWORK_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_PREFER_2G_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_SETTINGS_ENABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_EDITABLE_ENHANCED_4G_LTE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_PROVISIONED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VT_AVAILABLE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_ENHANCED_4G_LTE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_IMS_APN_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_PRESET_APN_DETAILS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_HIDE_SIM_LOCK_SETTINGS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_ALLOW_ADDING_APNS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_APN_EXPAND_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_IMS_GBA_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "list_KEY_VOLTE_REPLACEMENT_RAT_INT9", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_AUTO_RETRY_ENABLED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_WORLD_PHONE_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "switch_KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL", + "value": null, + "type": "boolean" + }, + { + "key": "list_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT", + "value": null, + "type": "string" + }, + { + "key": "list_KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT", + "value": null, + "type": "string" + }, + { + "key": "switch_KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL", + "value": null, + "type": "boolean" + } + ] + }, + { + "name": "android_8_api_27_(0_mr1)", + "preferences": [ + { + "key": "switch_KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL", + "value": null, + "type": "boolean" + } + ] + } + ] + }, + { + "metadata": { + "version": "0.7", + "code": 7, + "gitHash": "377044e" + } + } +] \ No newline at end of file diff --git a/docs/config.md b/docs/config.md index 118717f..831c7b8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -124,4 +124,26 @@ An example of a config file is shown below: "Debug": true } } +``` + +## Config File via Intent + +You can also pass the config file via an Intent to the App. +Either via JSON directly or as a path to the config file. + + +### Config via JSON +```bash +adb shell am broadcast \ + -a de.fraunhofer.fokus.OpenMobileNetworkToolkit.CONFIG_JSON \ + -n de.fraunhofer.fokus.OpenMobileNetworkToolkit/.Receiver.JsonConfigReceiver \ + -e jsonData '{}' +``` + +### Config via File Path +```bash +adb shell am broadcast \ + -a de.fraunhofer.fokus.OpenMobileNetworkToolkit.CONFIG_FILE \ + -n de.fraunhofer.fokus.OpenMobileNetworkToolkit/.Receiver.FileConfigReceiver + -e filePath 'PATH_TO_YOUR_CONFIG_FILE' ``` \ No newline at end of file diff --git a/docs/preferences.md b/docs/preferences.md new file mode 100644 index 0000000..2b83a78 --- /dev/null +++ b/docs/preferences.md @@ -0,0 +1,188 @@ +# Preferences Documentation + +## Logging + +### Logging Service + +_This configures the logging Service of OMNT._ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **enable_logging** | Enable | Start / stop the logging service | `false` | +| **start_logging_on_boot** | Start on boot | Start the logging service on device boot | `false` | +| **logging_interval** | Interval | Logging interval in milliseconds | `1000` | + +### Local logging + +_This configures a local InfluxDB instance, running on the Device, to log data to. EXPERIMENTAL_ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **enable_local_influx_log** | InfluxDB log | Log to a local Influx 2.x database | `fals` | +| **enable_local_file_log** | Log file | Log to a local file | `false` | + +### Remote logging + +_This configures a remote InfluxDB instance to log data to._ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **enable_influx** | InfluxDB log | Log to a remote Influx 2.x database | `false` | +| **influx_URL** | InfluxDB instance URL / IP | Influx URL, it can either be http://IP:8086, https://IP:8086, or any hostname. | `http://IP:8086` | +| **influx_org** | InfluxDB Organization | Influx ORG Name, or ID. | `ORG` | +| **influx_token** | Influx Token | Influx TOKEN | `TOKEN` | +| **influx_bucket** | InfluxDB bucket | Influx Bucket Name or ID. | `BUCKET_NAME` | + +### Logging content + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **fake_location** | Use fake location | Use a fake location for all measurements for testing / privacy reasons | `false` | +| **measurement_name** | Measurement name | | `omnt` | +| **tags** | Tags | Comma separated list of tags | | +| **influx_network_data** | Log network information | This will log NetworkInformation to InfluxDB. Like NetworkOperatorName, SimOperatorName, DataNetworkType. | `false` | +| **log_signal_data** | Log signal data | This will log SignalStrength to InfluxDB. Like RSRP, RSRQ from the SignalStrength API. | `false` | +| **influx_cell_data** | Log cell information | This will log CellInformation to InfluxDB. Like CellId, MCC, MNC, PCI, but also RSRP, RSRQ from the CellInformation API. | `true` | +| **log_neighbour_cells** | Log neighbour cells | This will log neighbour CellInformation data to InfluxDB. Like CellId, MCC, MNC, PCI, but also RSRP, RSRQ from the CellInformation API. | `false` | +| **influx_throughput_data** | Log throughput information | This will log InterfaceThroughput data to InfluxDB. Like download and upload throughput, what the phone thinks what is currently possible. | `false` | +| **log_wifi_data** | Log WiFi information | This will log WifiInformation data to InfluxDB. Like SSID, BSSID, RSSI, Frequency, LinkSpeed, and WifiStandard. | `false` | +| **influx_battery_data** | Log battery information | This will log BatteryInformation data to InfluxDB. Like BatteryLevel and Charging Status. | `false` | +| **influx_ip_address_data** | Log IP addresses | This will log IPAddressInformation data to InfluxDB. Like IPv4 and IPv6 addresses, and the interface name. | `false` | + +## Main + +### Home screen settings + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **show_neighbour_cells** | Show neighbour cells | Shows neighbour cells only when connected to a network and is announced by the network. | `false` | + +### Notification settings + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **enable_radio_notification** | Enable Cell Notification | Serving Cell Parameter: PCI, RSRP... | `false` | + +### App settings + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **device_name** | Unique Device Name | Set unique device name. | `OMNT0001` | +| **log_settings** | Logging | Configure the Logging Parameter. | | +| **mobile_network_settings** | Mobile Network | Configure Mobile Network Settings, only if the App has Carrier Permissions. | | +| **select_subscription** | Set subscription (SIM) | | `1` | +| **reset_modem** | Reboot Modem | Reboots the modem, only possible when OMNT has Carrier Permissions. | | +| **mqtt_settings** | MQTT Settings | Configure MQTT for OMNT. | | +| **shared_preferences_io** | Config | Import/Export Config of OMNT. | | + +## Mqtt + +### MQTT Service + +_Enables MQTT Services for OMNT._ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **enable_mqtt** | Enable | Enable MQTT | `false` | +| **enable_mqtt_on_boot** | Start on boot | Enable MQTT on boot | `false` | + +### MQTT Credentials + +_Section to set Credentials for MQTT._ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **mqtt_host** | MQTT-Broker Address | MQTT Broker Address | `192.168.213.89:1883` | +| **mqtt_client_username** | MQTT Client Username | MQTT Username | `USERNAME` | +| **mqtt_client_password** | MQTT Client Password | MQTT Client Password. | `PASSWORD` | + +## Mobile network + +### Radio Settings + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **doc** | Click here for Android Doc | Opens Link to Android Doc. | | +| **select_network_type** | Select Access Network Type | | | +| **add_plmn** | Set PLMN | | | +| **persist_boot** | Persist until reboot | | | + +### Carrier Settings + +_Applied on SIM / network change_ + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **apply_cs_settings** | Apply carrier settings now | | | + +### Android 12 API 31 (S) + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **edit_text_EPDG_STATIC_ADDRESS** | EPDG_STATIC_ADDRESS | | | +| **multi_select_KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY** | CARRIER_NR_AVAILABILITIES_INT_ARRAY | | | +| **switch_KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL** | HIDE_TTY_HCO_VCO_WITH_RTT_BOOL | | `false` | +| **switch_KEY_HIDE_ENABLE_2G** | HIDE_ENABLE_2G | | `false` | +| **switch_KEY_RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL** | RTT_UPGRADE_SUPPORTED_FOR_DOWNGRADED_VT_CALL_BOOL | | `true` | + +### Android 11 API 30 (R) + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **switch_KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL** | ALLOW_VIDEO_CALLING_FALLBACK_BOOL | | `true` | +| **switch_KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL** | CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL | | `false` | +| **switch_KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL** | HIDE_LTE_PLUS_DATA_ICON_BOOL | | `false` | +| **switch_KEY_WORLD_MODE_ENABLED_BOOL** | WORLD_MODE_ENABLED_BOOL | | `true` | +| **switch_KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL** | CARRIER_RCS_PROVISIONING_REQUIRED_BOOL | | `false` | +| **switch_KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL** | SHOW_IMS_REGISTRATION_STATUS_BOOL | | `true` | +| **switch_KEY_EDITABLE_WFC_MODE_BOOL** | EDITABLE_WFC_MODE_BOOL | | `true` | +| **switch_KEY_EDITABLE_WFC_ROAMING_MODE_BOOL** | EDITABLE_WFC_ROAMING_MODE_BOOL | | `true` | +| **edit_text_KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY** | READ_ONLY_APN_FIELDS_STRING_ARRAY | | | +| **edit_text_KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY** | APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY | | | +| **switch_KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL** | CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL | | `true` | + +### Android 10 API 29 (Q) + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **switch_KEY_FORCE_HOME_NETWORK_BOOL** | FORCE_HOME_NETWORK_BOOL | | `false` | +| **switch_KEY_PREFER_2G_BOOL** | PREFER_2G_BOOL | | `false` | +| **switch_KEY_CARRIER_SETTINGS_ENABLE_BOOL** | CARRIER_SETTINGS_ENABLE_BOOL | | `true` | +| **switch_KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL** | CARRIER_ALLOW_TURNOFF_IMS_BOOL | | `true` | +| **switch_KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL** | CARRIER_WFC_IMS_AVAILABLE_BOOL | | `true` | +| **switch_KEY_EDITABLE_ENHANCED_4G_LTE_BOOL** | EDITABLE_ENHANCED_4G_LTE_BOOL | | `true` | +| **switch_KEY_CARRIER_VOLTE_AVAILABLE_BOOL** | CARRIER_VOLTE_AVAILABLE_BOOL | | `true` | +| **switch_KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL** | CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL | | `false` | +| **switch_KEY_CARRIER_VOLTE_PROVISIONED_BOOL** | CARRIER_VOLTE_PROVISIONED_BOOL | | `false` | +| **switch_KEY_CARRIER_VT_AVAILABLE_BOOL** | CARRIER_VT_AVAILABLE_BOOL | | `false` | +| **switch_KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL** | CARRIER_VOLTE_TTY_SUPPORTED_BOOL | | `false` | +| **switch_KEY_HIDE_ENHANCED_4G_LTE_BOOL** | HIDE_ENHANCED_4G_LTE_BOOL | | `false` | +| **switch_KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL** | HIDE_CARRIER_NETWORK_SETTINGS_BOOL | | `false` | +| **switch_KEY_HIDE_IMS_APN_BOOL** | HIDE_IMS_APN_BOOL | | `false` | +| **switch_KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL** | HIDE_PREFERRED_NETWORK_TYPE_BOOL | | `false` | +| **switch_KEY_HIDE_PRESET_APN_DETAILS_BOOL** | HIDE_PRESET_APN_DETAILS_BOOL | | `false` | +| **switch_KEY_HIDE_SIM_LOCK_SETTINGS_BOOL** | HIDE_SIM_LOCK_SETTINGS_BOOL | | `false` | +| **switch_KEY_ALLOW_ADDING_APNS_BOOL** | ALLOW_ADDING_APNS_BOOL | | `true` | +| **switch_KEY_APN_EXPAND_BOOL** | APN_EXPAND_BOOL | | `true` | +| **switch_KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL** | CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL | | `false` | +| **switch_KEY_CARRIER_IMS_GBA_REQUIRED_BOOL** | CARRIER_IMS_GBA_REQUIRED_BOOL | | `false` | +| **switch_KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL** | REQUIRE_ENTITLEMENT_CHECKS_BOOL | | `false` | +| **list_KEY_VOLTE_REPLACEMENT_RAT_INT9** | VOLTE_REPLACEMENT_RAT_INT | | `18` | +| **switch_KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL** | CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL | | `false` | +| **switch_KEY_AUTO_RETRY_ENABLED_BOOL** | AUTO_RETRY_ENABLED_BOOL | | `false` | +| **switch_KEY_WORLD_PHONE_BOOL** | WORLD_PHONE_BOOL | | `true` | +| **switch_KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL** | SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL | | `false` | +| **switch_KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL** | CARRIER_UT_PROVISIONING_REQUIRED_BOOL | | `false` | +| **switch_KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL** | CARRIER_SUPPORTS_SS_OVER_UT_BOOL | | `false` | +| **switch_KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL** | ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL | | `false` | +| **switch_KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL** | SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL | | `false` | +| **list_KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT** | CARRIER_DEFAULT_WFC_IMS_MODE_INT | | `1` | +| **list_KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT** | CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT | | `1` | +| **switch_KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL** | ALLOW_EMERGENCY_VIDEO_CALLS_BOOL | | `false` | + +### Android 8 API 27 (0_MR1) + +| Key | Title | Summary | Default Value | +| --- | ----- | ------- | ------------- | +| **switch_KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL** | DISPLAY_HD_AUDIO_PROPERTY_BOOL | | `false` | +