From 9d5302c9b8bdde82b4299da8d60f9314ff9e4ea6 Mon Sep 17 00:00:00 2001 From: hajoha Date: Wed, 30 Apr 2025 15:19:35 +0200 Subject: [PATCH 01/10] update ping --- .../OpenMobileNetworkToolkit/Application.java | 12 ++- .../Inputs/PingInput.java | 4 + .../Parameter/PingParameter.java | 47 ++++++++-- .../Ping/PingFragment.java | 88 +++++++++++++++---- .../Ping/Worker/PingWorker.java | 8 +- 5 files changed, 127 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Application.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Application.java index 36e24d03..13b78051 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Application.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Application.java @@ -15,9 +15,13 @@ public class Application extends android.app.Application implements Configuratio @NonNull @Override public Configuration getWorkManagerConfiguration() { - return new Configuration.Builder() - .setDefaultProcessName(getPackageName()) - .setMinimumLoggingLevel(android.util.Log.DEBUG) - .build(); + Configuration.Builder configurationBuilder = new Configuration.Builder() + .setDefaultProcessName(getPackageName()); + + + if(BuildConfig.DEBUG) { + return configurationBuilder.setMinimumLoggingLevel(android.util.Log.DEBUG).build(); + } + return configurationBuilder.setMinimumLoggingLevel(android.util.Log.ERROR).build(); } } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/PingInput.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/PingInput.java index 4cf787b4..0dc35dc1 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/PingInput.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Inputs/PingInput.java @@ -29,6 +29,10 @@ protected PingInput(Parcel in) { super(in); } + public PingInput(PingParameter pingParameter, String testUUID){ + super(testUUID, "","","", pingParameter); + this.pingParameter = pingParameter; + } public PingInput(PingParameter pingParameter, String testUUID, String sequenceUUID, 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 32c8742c..ac38c820 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 @@ -98,6 +98,43 @@ public String[] getInputAsCommand() { return command.toArray(new String[0]); } + private void setupDirs(){ + + try { + Files.createDirectories(Paths.get(rawDirPath)); + Files.createDirectories(Paths.get(lineProtocolDirPath)); + } catch (IOException e) { + Log.d(TAG, "Could not create directories."); + } + + } + public PingParameter(String stringParameter, String testUUID) { + super(rawDirPath + testUUID + ".txt", lineProtocolDirPath + testUUID + ".txt"); + this.testUUID = testUUID; + String[] parts = stringParameter.split(" "); + for (int i = 0; i < parts.length; i++) { + switch (parts[i]) { + case "-c": + count = Integer.parseInt(parts[i + 1]); + break; + case "-W": + timeoutMillis = Integer.parseInt(parts[i + 1]); + break; + case "-s": + packetSize = Integer.parseInt(parts[i + 1]); + break; + case "-i": + intervalMillis = Long.parseLong(parts[i + 1]); + break; + case "-w": + deadline = Integer.parseInt(parts[i + 1]); + break; + default: + destination = parts[i]; + } + } + } + public PingParameter(JSONObject parameter, String testUUID) { super(rawDirPath + testUUID + ".txt", lineProtocolDirPath + testUUID + ".txt"); this.testUUID = testUUID; @@ -138,15 +175,7 @@ public PingParameter(JSONObject parameter, String testUUID) { Log.d(TAG, e.toString()); Log.i(TAG, "no deadline set."); } - - try { - Files.createDirectories(Paths.get(rawDirPath)); - Files.createDirectories(Paths.get(lineProtocolDirPath)); - } catch (IOException e) { - Log.d(TAG, "Could not create directories."); - } - - + setupDirs(); } protected PingParameter(Parcel in) { 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 7175aeb7..c3e970b0 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 @@ -25,21 +25,36 @@ import android.widget.Switch; import androidx.fragment.app.Fragment; +import androidx.lifecycle.LiveData; +import androidx.work.Data; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkInfo; +import androidx.work.WorkManager; import com.google.android.material.button.MaterialButtonToggleGroup; import com.google.android.material.textfield.TextInputEditText; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.gson.Gson; + +import org.json.JSONObject; import java.io.FileOutputStream; +import java.util.List; +import java.util.UUID; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; 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.Parameter.PingParameter; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; public class PingFragment extends Fragment { private final String TAG = "PingFragment"; + private final String LAST_UUID = "LAST_UUID"; private Switch aSwitch; private MaterialButtonToggleGroup toggleGroup; private LinearLayout verticalLL; @@ -51,6 +66,7 @@ public class PingFragment extends Fragment { private SharedPreferencesGrouper spg; private MetricView rttMetric; private MetricView packetLossMetric; + private WorkManager workManager; public PingFragment() { } @@ -60,21 +76,27 @@ public PingFragment() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } + private void startWorker() { + String uuid = UUID.randomUUID().toString(); + PingParameter pingParameter = new PingParameter(input.getText().toString(), uuid); + PingInput pingInput = new PingInput(pingParameter, uuid); + String gson = new Gson().toJson(pingInput, PingInput.class); + Data data = new Data.Builder() + .putString(PingInput.INPUT, gson) + .build(); + OneTimeWorkRequest pingWR = new OneTimeWorkRequest.Builder(PingWorker.class) + .setInputData(data) + .addTag(uuid) + .build(); + spg.getSharedPreference(SPType.ping_sp).edit().putString(LAST_UUID, pingWR.getId().toString()).apply(); + registerObserver(); + workManager.enqueue(pingWR); - private void startPingService() { - input.setEnabled(false); - Intent pingStart = new Intent(ct, PingService.class); - ct.startService(pingStart); - rttMetric.getMetricCalculator().resetMetric(); - packetLossMetric.getMetricCalculator().resetMetric(); } - private void stopPingService() { - input.setEnabled(true); - Intent pingStart = new Intent(ct, PingService.class); - ct.stopService(pingStart); - } + private void stopWorker(){ + } private void saveTextInputToSharedPreferences(EditText field, String name) { field.addTextChangedListener(new TextWatcher() { @@ -99,6 +121,39 @@ private void handleInput(boolean ping_running) { input.setEnabled(!ping_running); } + private void registerObserver(){ + + String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(LAST_UUID, null); + if(lastUUID != null) { + UUID lastUUIDUUID = UUID.fromString(lastUUID); + LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); + liveData.observe(getViewLifecycleOwner(), workInfo -> { + if(workInfo == null) return; + Log.d(TAG, "registerObserver: workInfo-State: "+workInfo.getState()); + switch (workInfo.getState()){ + case FAILED: + break; + case BLOCKED: + break; + case CANCELLED: + break; + case ENQUEUED: + break; + case RUNNING: + double rtt = workInfo.getOutputData().getDouble(PingWorker.LINE, 0); + Log.d(TAG, "registerObserver: current RTT:"+rtt); + rttMetric.update(rtt); + break; + case SUCCEEDED: + break; + default: + break; + } + }); + } + + } + @SuppressLint("UnspecifiedRegisterReceiverFlag") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -106,7 +161,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, View v = inflater.inflate(R.layout.fragment_ping, container, false); ct = requireContext(); spg = SharedPreferencesGrouper.getInstance(ct); - + workManager = WorkManager.getInstance(ct); verticalLL = v.findViewById(R.id.ping_vertical_ll); horizontalLL1 = verticalLL.findViewById(R.id.ping_horizontal1_ll); @@ -142,17 +197,16 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, if (!isChecked) return; switch (checkedId) { case R.id.ping_start: - startPingService(); v.findViewById(R.id.ping_start).setBackgroundColor(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(); - + startWorker(); break; case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); v.findViewById(R.id.ping_stop).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); - stopPingService(); spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + stopWorker(); break; } @@ -174,6 +228,10 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, horizontalLL1.addView(metricsLL); + registerObserver(); + + + //ToDO /* PingParser pingParser = PingParser; 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 1f9e30de..d58725f4 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 @@ -55,7 +55,7 @@ public class PingWorker extends Worker { private NotificationManager notificationManager; private final String channelId = "OMNT_notification_channel"; private NotificationCompat.Builder notificationBuilder; - private float rtt; // round-trip time + private double rtt; // round-trip time private PingInput pingInput; private Notification notification; public PingWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { @@ -127,7 +127,8 @@ public Result doWork() { Matcher matcher = pattern.matcher(line); if (matcher.find()) { try { - rtt = Float.parseFloat(Objects.requireNonNull(matcher.group(1))); + rtt = Double.parseDouble(Objects.requireNonNull(matcher.group(1))); + setProgressAsync(new Data.Builder().putDouble(LINE, rtt).build()); Log.d(TAG, "Updated RTT: " + rtt); new Runnable() { @Override @@ -139,8 +140,7 @@ public void run() { Log.e(TAG, "Error parsing RTT value: " + e.toString()); } } - // Optionally, report progress with the output line. - setProgressAsync(output.putString(LINE, line).build()); + } pingStream.close(); From f0c8132b43d90e799197ce3508fa95663c16fda4 Mon Sep 17 00:00:00 2001 From: hajoha Date: Fri, 9 May 2025 17:09:54 +0200 Subject: [PATCH 02/10] add repeat button --- .../Ping/PingFragment.java | 10 ++- .../Ping/Worker/PingWorker.java | 7 +- .../main/res/drawable-anydpi/repeat_24px.xml | 10 +++ app/src/main/res/layout/fragment_ping.xml | 74 +++++++++++++------ 4 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 app/src/main/res/drawable-anydpi/repeat_24px.xml 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 c3e970b0..688f162a 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 @@ -87,8 +87,10 @@ private void startWorker() { OneTimeWorkRequest pingWR = new OneTimeWorkRequest.Builder(PingWorker.class) .setInputData(data) .addTag(uuid) + .addTag(PingWorker.TAG) .build(); spg.getSharedPreference(SPType.ping_sp).edit().putString(LAST_UUID, pingWR.getId().toString()).apply(); + rttMetric.getMetricCalculator().resetMetric(); registerObserver(); workManager.enqueue(pingWR); @@ -96,6 +98,12 @@ private void startWorker() { private void stopWorker(){ + String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(LAST_UUID, ""); + if(lastUUID.equals("")) { + Log.d(TAG, "stopWorker: no worker to stop!"); + return; + } + workManager.cancelWorkById(UUID.fromString(lastUUID)); } private void saveTextInputToSharedPreferences(EditText field, String name) { @@ -140,7 +148,7 @@ private void registerObserver(){ case ENQUEUED: break; case RUNNING: - double rtt = workInfo.getOutputData().getDouble(PingWorker.LINE, 0); + double rtt = workInfo.getProgress().getDouble(PingWorker.LINE, 0); Log.d(TAG, "registerObserver: current RTT:"+rtt); rttMetric.update(rtt); break; 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 d58725f4..a711ee20 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 @@ -48,7 +48,6 @@ public class PingWorker extends Worker { public static final String REASON = "reason"; public static final String LINE = "line"; public static final String TAG = "PingWorker"; - private int notificationID = 102; private final int FOREGROUND_SERVICE_TYPE = FOREGROUND_SERVICE_TYPE_SPECIAL_USE; private final Context ct; @@ -129,6 +128,7 @@ public Result doWork() { try { rtt = Double.parseDouble(Objects.requireNonNull(matcher.group(1))); setProgressAsync(new Data.Builder().putDouble(LINE, rtt).build()); + Log.d(TAG, "Updated RTT: " + rtt); new Runnable() { @Override @@ -140,9 +140,12 @@ public void run() { Log.e(TAG, "Error parsing RTT value: " + e.toString()); } } + if(this.isStopped()){ + break; + } } - + process.destroy(); pingStream.close(); reader.close(); diff --git a/app/src/main/res/drawable-anydpi/repeat_24px.xml b/app/src/main/res/drawable-anydpi/repeat_24px.xml new file mode 100644 index 00000000..877737af --- /dev/null +++ b/app/src/main/res/drawable-anydpi/repeat_24px.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_ping.xml b/app/src/main/res/layout/fragment_ping.xml index 435da3d6..c315e623 100644 --- a/app/src/main/res/layout/fragment_ping.xml +++ b/app/src/main/res/layout/fragment_ping.xml @@ -47,37 +47,63 @@ android:hint="Ping Command" tools:ignore="LabelFor,RtlSymmetry" /> - - - - + + android:layout_marginRight="10dp" + android:layout_weight="7"> + + + + + - - + + + + + + + + Date: Tue, 20 May 2025 15:49:27 +0200 Subject: [PATCH 03/10] fix minor bug --- .../Database/RunResult/Iperf3ResultsDataBase.java | 2 +- .../Iperf3/Worker/Iperf3ToLineProtocolWorker.java | 15 ++++++++++++++- .../MQTT/MQTTService.java | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java index 981c2131..4902ce81 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java @@ -22,7 +22,7 @@ @Database( entities = {Iperf3RunResult.class}, - version = 3 + version = 4 ) public abstract class Iperf3ResultsDataBase extends RoomDatabase { 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 adbeeef7..4ab5490e 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 @@ -28,6 +28,7 @@ import com.influxdb.client.domain.WritePrecision; import com.influxdb.client.write.Point; +import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -45,6 +46,7 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.Stream; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP.TCP_UL_STREAM; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.UDP.UDP_DL_STREAM; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.Iperf3Parameter; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; @@ -184,7 +186,18 @@ public Result doWork() { } } - + File path = new File(Iperf3Parameter.lineProtocolDirPath); + if(!path.exists()){ + path.mkdirs(); + } + File iperf3File = new File(iperf3Input.getParameter().getLineProtocolFile()); + if (!iperf3File.exists()) { + try { + iperf3File.createNewFile(); + } catch (IOException e) { + Log.e(TAG, "doWork: ", e); + } + } FileOutputStream iperf3Stream = null; try { 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 f2b66bbc..f58a94ba 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 @@ -450,6 +450,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { 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(); + return START_NOT_STICKY; + } connectClient(); subscribeToAllTopics(); From 283188bbd83febaa1d16ad6b9e7736e2f987a14e Mon Sep 17 00:00:00 2001 From: hajoha Date: Tue, 3 Jun 2025 11:11:52 +0200 Subject: [PATCH 04/10] fix minor bug --- .../RunResult/Iperf3ResultsDataBase.java | 1 + .../MQTT/MQTTService.java | 2 +- .../MainActivity.java | 26 +++++++++++++++++++ .../Ping/Worker/PingToLineProtocolWorker.java | 8 ++++++ .../Ping/Worker/PingWorker.java | 10 +++++++ .../MQTTSettingsFragment.java | 4 +-- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java index 4902ce81..eeb60c11 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java @@ -43,6 +43,7 @@ public static Iperf3ResultsDataBase getDatabase(final Context context) { .addTypeConverter(new Iperf3ErrorConverter()) .allowMainThreadQueries() .enableMultiInstanceInvalidation() + .fallbackToDestructiveMigration(true) .build(); } } 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 f58a94ba..671fb57b 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 @@ -110,7 +110,7 @@ public void createClient(){ .identifier(deviceName) .serverAddress(address) .automaticReconnect() - .initialDelay(200, TimeUnit.MILLISECONDS) + .initialDelay(5, TimeUnit.SECONDS) .maxDelay(30, TimeUnit.SECONDS) .applyAutomaticReconnect() .addConnectedListener(context -> { 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 6fc6a1bb..e3ea6ffb 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java @@ -21,6 +21,7 @@ import android.content.pm.PackageManager; import android.content.pm.Signature; import android.location.LocationManager; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -251,6 +252,31 @@ protected void onCreate(Bundle savedInstanceState) { } }, SPType.mqtt_sp); + 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() + .putString("device_name", device_name) + .apply(); + } + if(mqtt_broker_address != null){ + spg.getSharedPreference(SPType.mqtt_sp).edit() + .putBoolean("enable_mqtt", true) + .putString("mqtt_host", mqtt_broker_address) + .apply(); + context.startForegroundService(mqttServiceIntent); + } + + + } + + + + + + getAppSignature(); gv.setGit_hash(getString(R.string.git_hash)); } 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 faad5762..51d45ade 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 @@ -33,6 +33,7 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.GlobalVars; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.InfluxdbConnection; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.PingParameter; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.LINEType; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PacketLossLine; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PingInformation; @@ -52,6 +53,13 @@ public PingToLineProtocolWorker(@NonNull Context context, @NonNull WorkerParamet String iperf3InputString = getInputData().getString(PingInput.INPUT); pingInput = gson.fromJson(iperf3InputString, PingInput.class); spg = SharedPreferencesGrouper.getInstance(getApplicationContext()); + + File lineProtocolDirPath = new File(PingParameter.lineProtocolDirPath); + if(!lineProtocolDirPath.exists()){ + if(!lineProtocolDirPath.mkdirs()){ + Log.e(TAG, "Error creating lineProtocolDirPath directory: " + PingParameter.lineProtocolDirPath); + } + } } 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 a711ee20..331372a0 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 @@ -70,6 +70,16 @@ 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); + if(!rawPath.exists()){ + if(!rawPath.mkdirs()){ + Log.e(TAG, "Error creating rawDirPath directory: " + PingParameter.rawDirPath); + } + } + + + setForegroundAsync(createForegroundInfo("")); } 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 9139c08c..c896675b 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 @@ -25,7 +25,7 @@ public class MQTTSettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "MQTTSettingsFragment"; - SwitchPreferenceCompat enable_mqtt_switch; + SwitchPreferenceCompat _switch; @Override public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { SharedPreferencesGrouper spg = SharedPreferencesGrouper.getInstance(requireContext()); @@ -33,7 +33,7 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S setPreferencesFromResource(R.xml.preference_mqtt, rootKey); Objects.requireNonNull(getPreferenceScreen().getSharedPreferences()) .registerOnSharedPreferenceChangeListener(this); - enable_mqtt_switch = findPreference("enable_mqtt"); + _switch = findPreference("enable_mqtt"); } From 4887c4c93b2a8168ddf48d775e2717fc30c504c5 Mon Sep 17 00:00:00 2001 From: hajoha Date: Mon, 16 Jun 2025 15:58:15 +0200 Subject: [PATCH 05/10] add repeat button --- .../Ping/PingFragment.java | 33 +++++++++++++++---- app/src/main/res/layout/fragment_ping.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 30 insertions(+), 6 deletions(-) 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 688f162a..53e8db9a 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 @@ -21,9 +21,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; +import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.Switch; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; import androidx.work.Data; @@ -40,6 +42,7 @@ import java.io.FileOutputStream; import java.util.List; +import java.util.Objects; import java.util.UUID; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; @@ -67,6 +70,7 @@ public class PingFragment extends Fragment { private MetricView rttMetric; private MetricView packetLossMetric; private WorkManager workManager; + private ImageButton repeatButton; public PingFragment() { } @@ -162,6 +166,13 @@ private void registerObserver(){ } + private void setupRepeatButton(){ + boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); + int color = ContextCompat.getColor(requireContext(), + isRepeat ? R.color.design_default_color_primary : R.color.design_default_color_on_secondary); + repeatButton.setColorFilter(color); + } + @SuppressLint("UnspecifiedRegisterReceiverFlag") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -177,23 +188,33 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, input = verticalLL.findViewById(R.id.ping_input); input.setText(spg.getSharedPreference(SPType.ping_sp).getString("ping_input", "-w 5 8.8.8.8")); input.setEnabled(!PingService.isRunning()); + 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(); + setupRepeatButton(); + + }); + saveTextInputToSharedPreferences(input, "ping_input"); boolean pingRunning = spg.getSharedPreference(SPType.ping_sp).getBoolean("ping_running", false); if (pingRunning && PingService.isRunning()) { - v.findViewById(R.id.ping_start).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); } else { - v.findViewById(R.id.ping_stop).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); } spg.setListener((sharedPreferences, key) -> { if (key != null && key.equals("ping_running")) { boolean isRunning = sharedPreferences.getBoolean("ping_running", false); handleInput(isRunning); if (isRunning) { - v.findViewById(R.id.ping_start).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); v.findViewById(R.id.ping_stop).setBackgroundColor(Color.TRANSPARENT); } else { v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); - v.findViewById(R.id.ping_stop).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); } } @@ -205,14 +226,14 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, if (!isChecked) return; switch (checkedId) { case R.id.ping_start: - v.findViewById(R.id.ping_start).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().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(); startWorker(); break; case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); - v.findViewById(R.id.ping_stop).setBackgroundColor(getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); stopWorker(); break; diff --git a/app/src/main/res/layout/fragment_ping.xml b/app/src/main/res/layout/fragment_ping.xml index c315e623..0b912a65 100644 --- a/app/src/main/res/layout/fragment_ping.xml +++ b/app/src/main/res/layout/fragment_ping.xml @@ -97,6 +97,8 @@ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 88be6d21..ca4124fc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -284,6 +284,7 @@ X State Parameter + if enabled, ping will repeat, until disabled \ No newline at end of file From b824a9477a8ec39c383229312ec3233ea80c8ca7 Mon Sep 17 00:00:00 2001 From: hajoha Date: Wed, 18 Jun 2025 15:16:24 +0200 Subject: [PATCH 06/10] implement repeat functionality --- .../Ping/PingFragment.java | 120 ++++---- .../Ping/PingService.java | 278 +++++++----------- 2 files changed, 158 insertions(+), 240 deletions(-) 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 53e8db9a..09b76013 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 @@ -11,6 +11,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; @@ -28,8 +29,10 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; +import androidx.lifecycle.Observer; import androidx.work.Data; import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkContinuation; import androidx.work.WorkInfo; import androidx.work.WorkManager; @@ -45,11 +48,13 @@ import java.util.Objects; import java.util.UUID; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.Worker.InfluxDB2xUploadWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; 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.Parameter.PingParameter; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingToLineProtocolWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; @@ -57,7 +62,7 @@ public class PingFragment extends Fragment { private final String TAG = "PingFragment"; - private final String LAST_UUID = "LAST_UUID"; + private Switch aSwitch; private MaterialButtonToggleGroup toggleGroup; private LinearLayout verticalLL; @@ -80,35 +85,8 @@ public PingFragment() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } - private void startWorker() { - String uuid = UUID.randomUUID().toString(); - PingParameter pingParameter = new PingParameter(input.getText().toString(), uuid); - PingInput pingInput = new PingInput(pingParameter, uuid); - String gson = new Gson().toJson(pingInput, PingInput.class); - Data data = new Data.Builder() - .putString(PingInput.INPUT, gson) - .build(); - OneTimeWorkRequest pingWR = new OneTimeWorkRequest.Builder(PingWorker.class) - .setInputData(data) - .addTag(uuid) - .addTag(PingWorker.TAG) - .build(); - spg.getSharedPreference(SPType.ping_sp).edit().putString(LAST_UUID, pingWR.getId().toString()).apply(); - rttMetric.getMetricCalculator().resetMetric(); - registerObserver(); - workManager.enqueue(pingWR); - - } - private void stopWorker(){ - String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(LAST_UUID, ""); - if(lastUUID.equals("")) { - Log.d(TAG, "stopWorker: no worker to stop!"); - return; - } - workManager.cancelWorkById(UUID.fromString(lastUUID)); - } private void saveTextInputToSharedPreferences(EditText field, String name) { field.addTextChangedListener(new TextWatcher() { @@ -133,39 +111,50 @@ private void handleInput(boolean ping_running) { input.setEnabled(!ping_running); } - private void registerObserver(){ - - String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(LAST_UUID, null); - if(lastUUID != null) { - UUID lastUUIDUUID = UUID.fromString(lastUUID); - LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); - liveData.observe(getViewLifecycleOwner(), workInfo -> { - if(workInfo == null) return; - Log.d(TAG, "registerObserver: workInfo-State: "+workInfo.getState()); - switch (workInfo.getState()){ - case FAILED: - break; - case BLOCKED: - break; - case CANCELLED: - break; - case ENQUEUED: - break; - case RUNNING: - double rtt = workInfo.getProgress().getDouble(PingWorker.LINE, 0); - Log.d(TAG, "registerObserver: current RTT:"+rtt); - rttMetric.update(rtt); - break; - case SUCCEEDED: - break; - default: - break; + private void registerObserver() { + SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (PingService.PING_LAST_UUID.equals(key)) { + String uuidStr = sharedPreferences.getString(PingService.PING_LAST_UUID, null); + if (uuidStr == null) return; + + UUID lastUUIDUUID = UUID.fromString(uuidStr); + Log.d(TAG, "registerObserver: lastUUID changed: " + lastUUIDUUID); + + LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); + Observer observer = new Observer() { + @Override + public void onChanged(WorkInfo workInfo) { + if (workInfo == null) return; + + Log.d(TAG, "registerObserver: workInfo-State: " + workInfo.getState()); + switch (workInfo.getState()) { + case RUNNING: + double rtt = workInfo.getProgress().getDouble(PingWorker.LINE, 0); + Log.d(TAG, "registerObserver: current RTT: " + rtt); + rttMetric.update(rtt); + break; + case SUCCEEDED: + case FAILED: + case CANCELLED: + liveData.removeObserver(this); // Optionally clean up + break; + default: + break; + } + } + }; + + liveData.observe(getViewLifecycleOwner(), observer); } - }); - } + } + }; + spg.getSharedPreference(SPType.ping_sp).registerOnSharedPreferenceChangeListener(listener); } + private void setupRepeatButton(){ boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); int color = ContextCompat.getColor(requireContext(), @@ -187,7 +176,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, 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.setEnabled(!PingService.isRunning()); repeatButton = v.findViewById(R.id.ping_repeat_button); setupRepeatButton(); repeatButton.setOnClickListener(view -> { @@ -195,12 +183,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("repeat_ping", !isRepeat).apply(); setupRepeatButton(); - }); saveTextInputToSharedPreferences(input, "ping_input"); boolean pingRunning = spg.getSharedPreference(SPType.ping_sp).getBoolean("ping_running", false); - if (pingRunning && PingService.isRunning()) { + if (pingRunning) { v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); } else { v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); @@ -229,13 +216,21 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().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(); - startWorker(); + Intent startIntent = new Intent(ct, PingService.class); + startIntent.putExtra(PingService.PING_INTENT_COMMAND, input.getText().toString()); + startIntent.putExtra(PingService.PING_INTENT_ENABLE, true); + ct.startService(startIntent); + registerObserver(); + break; case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); - stopWorker(); + Intent stopIntent = new Intent(ct, PingService.class); + stopIntent.setAction(PingService.PING_INTENT_COMMAND); + stopIntent.putExtra(PingService.PING_INTENT_ENABLE, false); + ct.startService(stopIntent); break; } @@ -257,7 +252,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, horizontalLL1.addView(metricsLL); - registerObserver(); 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 aaf8086e..c86e1b56 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 @@ -9,67 +9,38 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping; import android.app.Service; -import android.content.Context; import android.content.Intent; -import android.icu.text.SimpleDateFormat; -import android.os.Environment; -import android.os.Handler; -import android.os.HandlerThread; import android.os.IBinder; -import android.os.Looper; import android.util.Log; -import android.widget.Toast; import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; +import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.work.Data; import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkContinuation; import androidx.work.WorkInfo; import androidx.work.WorkManager; -import com.influxdb.client.write.Point; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -import de.fraunhofer.fokus.OpenMobileNetworkToolkit.DataProvider.DataProvider; -import de.fraunhofer.fokus.OpenMobileNetworkToolkit.GlobalVars; -import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.InfluxdbConnection; -import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.InfluxdbConnections; -import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PingInformation; +import com.google.gson.Gson; + +import java.util.UUID; + +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.Worker.InfluxDB2xUploadWorker; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.PingParameter; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingToLineProtocolWorker; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; public class PingService extends Service { private static final String TAG = "PingService"; - private FileOutputStream ping_stream; - private Handler pingLogging; - private HandlerThread pingLoggingHandleThread; - private WorkManager wm; - private Context context; - private ArrayList pingWRs; + public static final String PING_INTENT_COMMAND = "ping_intent_command"; + public static final String PING_INTENT_ENABLE = "ping_intent_enable"; + public static final String PING_LAST_UUID = "ping_last_uuid"; private SharedPreferencesGrouper spg; - NotificationCompat.Builder builder; - DataProvider dp; - InfluxdbConnection influx; - private static boolean isRunning = false; - private String pingCommand; - private PropertyChangeListener propertyChangeListener; - HashMap parsedCommand = new HashMap<>(); - + private WorkManager workManager; @Nullable @Override public IBinder onBind(Intent intent) { @@ -78,161 +49,114 @@ public IBinder onBind(Intent intent) { @Override public void onDestroy() { Log.d(TAG, "onDestroy: Stop logging service"); - stopPing(); - } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand: Start logging service"); - GlobalVars gv = GlobalVars.getInstance(); - // setup class variables - dp = gv.get_dp(); - context = getApplicationContext(); - spg = SharedPreferencesGrouper.getInstance(context); - if(spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) influx = InfluxdbConnections.getRicInstance(context); - wm = WorkManager.getInstance(context); - wm.cancelAllWorkByTag("Ping"); - if(intent == null) return START_NOT_STICKY; - pingWRs = new ArrayList<>(); - - setupPing(); - isRunning = true; - return START_STICKY; } - private void setupPing(){ - Log.d(TAG, "starting Ping Service..."); + private void startWorker(String command) { + String uuid = UUID.randomUUID().toString(); + PingParameter pingParameter = new PingParameter(command, uuid); + PingInput pingInput = new PingInput(pingParameter, uuid); + String gson = new Gson().toJson(pingInput, PingInput.class); + Data data = new Data.Builder() + .putString(PingInput.INPUT, gson) + .build(); + OneTimeWorkRequest pingWR = new OneTimeWorkRequest.Builder(PingWorker.class) + .setInputData(data) + .addTag(uuid) + .addTag(PingWorker.TAG) + .build(); + OneTimeWorkRequest pingToLineProtocolWR = new OneTimeWorkRequest.Builder(PingToLineProtocolWorker.class) + .setInputData(data) + .addTag(uuid) + .addTag(PingToLineProtocolWorker.TAG) + .build(); - String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/omnt/ping/"; - try { - Files.createDirectories(Paths.get(path)); - } catch (IOException e) { - Toast.makeText(context, "could not create /omnt/ping Dir!", Toast.LENGTH_SHORT).show(); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", false).apply(); - Log.d(TAG, "setupPing: could not create /omnt/ping Dir!"); - return; - } - // create the log file - SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.US); - Date now = new Date(); - String filename = path + formatter.format(now) + ".txt"; - Log.d(TAG, "logfile: " + filename); - File logfile = new File(filename); - try { - logfile.createNewFile(); - } catch (IOException e) { - Toast.makeText(context, "could not create logfile "+filename, Toast.LENGTH_SHORT).show(); - Log.d(TAG, "setupPing: could not create logfile"); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", false).apply(); - return; + spg.getSharedPreference(SPType.ping_sp).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)){ + OneTimeWorkRequest influxDB2xUploadWorker = new OneTimeWorkRequest.Builder(InfluxDB2xUploadWorker.class) + .setInputData(data) + .addTag(uuid) + .addTag(InfluxDB2xUploadWorker.TAG) + .build(); + workContinuation = workContinuation.then(influxDB2xUploadWorker); } + workContinuation.enqueue(); - // get an output stream - try { - ping_stream = new FileOutputStream(logfile); - } catch (FileNotFoundException e) { - Toast.makeText(context, "could not create output stream", Toast.LENGTH_SHORT).show(); - Log.d(TAG, "setupPing: could not create output stream"); - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", false).apply(); + } + private void stopWorker(){ + String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, ""); + if(lastUUID.equals("")) { + Log.d(TAG, "stopWorker: no worker to stop!"); return; } - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", true).apply(); - pingLoggingHandleThread = new HandlerThread("PingLoggingHandlerThread"); - pingLoggingHandleThread.start(); - pingLogging = new Handler(Objects.requireNonNull(pingLoggingHandleThread.getLooper())); - propertyChangeListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - PingInformation pi = (PingInformation) evt.getNewValue(); - - Point point = pi.getPoint(); - point.addTags(dp.getTagsMap()); - Log.d(TAG, "propertyChange: "+point.toLineProtocol()); - try { - ping_stream.write((point.toLineProtocol() + "\n").getBytes()); - } catch (IOException e) { - Log.d(TAG,e.toString()); - } - - if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false) && influx.getWriteApi() != null) { - try { - influx.writePoints(List.of(point)); - } catch (IOException e) { - Log.d(TAG,e.toString()); - } - } + workManager.cancelWorkById(UUID.fromString(lastUUID)); + } - } - }; - pingLogging.post(pingUpdate); - } - public void parsePingCommand() { - - String[] commandParts = pingCommand.split("\\s+"); - - String previousPart = null; - for (String part : commandParts) { - switch (part) { - case "ping": - parsedCommand.put("command", part); - break; - case "-w": - if (previousPart != null) { - parsedCommand.put("timeout", previousPart); - } - break; - default: - parsedCommand.put("target", part); - break; - } - previousPart = part; + private void registerObserver(String command){ + String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, null); + if(lastUUID != null) { + UUID lastUUIDUUID = UUID.fromString(lastUUID); + LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); + Observer observer = workInfo -> { + if(workInfo == null) return; + Log.d(TAG, "registerObserver: workInfo-State: "+workInfo.getState()); + switch (workInfo.getState()){ + case SUCCEEDED: + case FAILED: + if(spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false)){ + Log.d(TAG, "registerObserver: Repeat ping"); + startWorker(command); + } else { + Log.d(TAG, "registerObserver: Stop ping service"); + stopSelf(); + } +// liveData.removeObserver(observer); +// liveData.removeObservers(); + + break; + case CANCELLED: + case ENQUEUED: + case BLOCKED: + case RUNNING: + break; + default: + break; + } + }; + liveData.observeForever(observer); } - } - - private final Runnable pingUpdate = new Runnable() { - @Override - public void run() { - Data data = new Data.Builder() - .putString("input", spg.getSharedPreference(SPType.ping_sp).getString("ping_input", "8.8.8.8")) - .build(); + } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "onStartCommand: Start ping service"); + spg = SharedPreferencesGrouper.getInstance(getApplicationContext()); + workManager = WorkManager.getInstance(getApplicationContext()); + String command = intent.getStringExtra(PING_INTENT_COMMAND); + boolean isEnabled = intent.getBooleanExtra(PING_INTENT_ENABLE, false); + if(!isEnabled){ + stopWorker(); + stopSelf(); + return START_NOT_STICKY; } - }; - - private void stopPing(){ - - if (pingLogging != null )pingLogging.removeCallbacks(pingUpdate); - if (pingLoggingHandleThread != null) { - pingLoggingHandleThread.quitSafely(); - try { - pingLoggingHandleThread.join(); - } catch (InterruptedException e) { - Log.e(TAG, "Exception happened!! "+e, e); - } - pingLoggingHandleThread = null; - } - try { - if (ping_stream != null) ping_stream.close(); - } catch (IOException e) { - throw new RuntimeException(e); + String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, ""); + if(!lastUUID.isEmpty()){ + stopWorker(); } - for (OneTimeWorkRequest wr : pingWRs){ - wm.cancelWorkById(wr.getId()); + startWorker(command); - } - spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", false).apply(); - pingWRs = new ArrayList<>(); - } - public static boolean isRunning() { - return isRunning; + return START_STICKY; } + } From af5ab396f3d26816d7ca601472ea54a0848fb6a9 Mon Sep 17 00:00:00 2001 From: hajoha Date: Wed, 18 Jun 2025 16:49:54 +0200 Subject: [PATCH 07/10] fix fragment view --- .../Ping/PingFragment.java | 51 ++++++------ .../PingInformations/PingInformation.java | 1 - .../Ping/PingInformations/RTTLine.java | 15 ++-- .../Ping/PingParser.java | 79 +++++++------------ .../Ping/Worker/PingWorker.java | 61 +++++++++----- 5 files changed, 105 insertions(+), 102 deletions(-) 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 09b76013..3b4bda5c 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,6 +8,8 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping; +import static android.view.View.INVISIBLE; + import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; @@ -54,6 +56,9 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.MetricCalculator; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.MetricView; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.PingParameter; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PacketLossLine; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PingInformation; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.RTTLine; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingToLineProtocolWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.Worker.PingWorker; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; @@ -127,15 +132,25 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin @Override public void onChanged(WorkInfo workInfo) { 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); + } + + 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); + } + switch (workInfo.getState()) { case RUNNING: - double rtt = workInfo.getProgress().getDouble(PingWorker.LINE, 0); - Log.d(TAG, "registerObserver: current RTT: " + rtt); - rttMetric.update(rtt); - break; case SUCCEEDED: + break; case FAILED: case CANCELLED: liveData.removeObserver(this); // Optionally clean up @@ -221,7 +236,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, startIntent.putExtra(PingService.PING_INTENT_ENABLE, true); ct.startService(startIntent); registerObserver(); - + rttMetric.getMetricCalculator().resetMetric(); + packetLossMetric.getMetricCalculator().resetMetric(); break; case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); @@ -249,29 +265,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, metricsLL.setLayoutParams(foo1); metricsLL.addView(rttMetric); metricsLL.addView(packetLossMetric); - + packetLossMetric.setVisibility(INVISIBLE); horizontalLL1.addView(metricsLL); - - - - - //ToDO - /* - PingParser pingParser = PingParser; - pingParser.addPropertyChangeListener(evt -> { - PingInformation pi = (PingInformation) evt.getNewValue(); - switch (pi.getLineType()) { - case RTT: - rttMetric.update(((RTTLine) pi).getRtt()); - break; - case PACKET_LOSS: - packetLossMetric.update(((PacketLossLine) pi).getPacketLoss()); - //packetLossMetric.setVisibility(View.VISIBLE); - break; - } - }); - */ - //packetLossMetric.setVisibility(View.INVISIBLE); return v; } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PingInformation.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PingInformation.java index 281ab1d5..e0f5ee38 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PingInformation.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/PingInformation.java @@ -18,7 +18,6 @@ public class PingInformation { private final String line; private LINEType lineType; private Double unixTimestamp; - private DataProvider dp; public PingInformation(String line) { this.line = line; } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java index c6645666..fb3f70ba 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java @@ -15,7 +15,8 @@ public class RTTLine extends PingInformation{ public static Pattern pattern = Pattern.compile( - "\\[(\\d+\\.\\d+)\\] (\\d+ bytes from (\\S+|\\d+\\.\\d+\\.\\d+\\.\\d+)): icmp_seq=(\\d+) ttl=(\\d+) time=([\\d.]+) ms"); + "\\[(\\d+\\.\\d+)\\] (\\d+ bytes from ([^(]+)(?: \\(([^)]+)\\))?): icmp_seq=(\\d+) ttl=(\\d+) time=([\\d.]+) ms"); + private int icmpSeq; private int ttl; private double rtt; @@ -30,11 +31,15 @@ public void parse(){ super.parse(); Matcher matcher = pattern.matcher(this.getLine()); if (matcher.find()) { - icmpSeq = Integer.parseInt(matcher.group(4)); - ttl = Integer.parseInt(matcher.group(5)); - host = matcher.group(3); - rtt = Double.parseDouble(matcher.group(6)); + icmpSeq = Integer.parseInt(matcher.group(5)); + ttl = Integer.parseInt(matcher.group(6)); + // Group 3 = hostname, Group 4 = optional IP + String hostname = matcher.group(3).trim(); + String ip = matcher.group(4); + host = ip; + rtt = Double.parseDouble(matcher.group(7)); } + } public double getRtt() { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingParser.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingParser.java index d7e9cf50..ec2eee35 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingParser.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingParser.java @@ -20,16 +20,11 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.RTTLine; public class PingParser { - private static PingParser instance = null; - private BufferedReader br; + private final ArrayList lines; - private final PropertyChangeSupport support; - private PropertyChangeListener listener; - public PingParser(BufferedReader br) { - this.br = br; + public PingParser() { this.lines = new ArrayList<>(); - support = new PropertyChangeSupport(this); } @@ -46,53 +41,39 @@ private LINEType getLineType(String line){ return LINEType.UNKNOWN; } } - public void parse(){ - String line; - try { - while((line = this.br.readLine()) != null){ - PingInformation pi = null; - switch (getLineType(line)){ - case RTT: - pi = new RTTLine(line); - case UNREACHABLE: - //TDODO - break; - case TIMEOUT: - //TODO - break; - case PACKET_LOSS: - pi = new PacketLossLine(line); - break; - case UNKNOWN: - break; - } - if(pi == null) continue; - pi.parse(); - this.lines.add(pi); - support.firePropertyChange("ping", null, pi); - } - } catch (IOException e){ + public void addLine(String line) { + PingInformation pi = null; + LINEType lineType = getLineType(line); + switch (lineType){ + case RTT: + pi = new RTTLine(line); + break; + case UNREACHABLE: + //TODO + break; + case TIMEOUT: + //TODO + break; + case PACKET_LOSS: + pi = new PacketLossLine(line); + break; + case UNKNOWN: + break; + } + if(pi != null){ + pi.parse(); + pi.setLineType(lineType); + lines.add(pi); } } - public void addPropertyChangeListener(PropertyChangeListener listener){ - support.addPropertyChangeListener(listener); - } - public void setListener(PropertyChangeListener listener){ - this.listener = listener; - } - public PropertyChangeListener getListener(){ - return this.listener; - } - public void removePropertyChangeListener(PropertyChangeListener listener){ - support.removePropertyChangeListener(listener); - } - - public void setBr(BufferedReader br){ - this.br = br; + public PingInformation getLastPingInformation() { + if (lines.isEmpty()) { + return null; + } + return lines.get(lines.size() - 1); } - } 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 331372a0..05d7a92a 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 @@ -40,6 +40,10 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Inputs.PingInput; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Parameter.PingParameter; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PacketLossLine; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.PingInformation; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingInformations.RTTLine; +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping.PingParser; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; public class PingWorker extends Worker { @@ -47,6 +51,11 @@ public class PingWorker extends Worker { public static final String PING = "ping"; public static final String REASON = "reason"; public static final String LINE = "line"; + public static final String RTT = "rtt"; + public static final String PACKET_LOSS = "packetLoss"; + public static final String UNREACHABLE = "unreachable"; + public static final String TIMEOUT = "timeout"; + public static final String TAG = "PingWorker"; private int notificationID = 102; private final int FOREGROUND_SERVICE_TYPE = FOREGROUND_SERVICE_TYPE_SPECIAL_USE; @@ -120,36 +129,50 @@ public Result doWork() { Log.d(TAG, "doWork: executing " + String.join(" ", command)); int result = -1; try { - String timeRegex = "time=(\\d+(?:\\.\\d+)?)\\s*ms"; - Pattern pattern = Pattern.compile(timeRegex); 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); - + PingParser pingParser = new PingParser(); String line; while ((line = reader.readLine()) != null) { Log.d(TAG, "doWork: "+line); pingStream.write((line + "\n").getBytes()); - Matcher matcher = pattern.matcher(line); - if (matcher.find()) { - try { - rtt = Double.parseDouble(Objects.requireNonNull(matcher.group(1))); - setProgressAsync(new Data.Builder().putDouble(LINE, rtt).build()); - - Log.d(TAG, "Updated RTT: " + rtt); - new Runnable() { - @Override - public void run() { - setForegroundAsync(createForegroundInfo( rtt + " ms")); - } - }.run(); - } catch (NumberFormatException e) { - Log.e(TAG, "Error parsing RTT value: " + e.toString()); - } + pingParser.addLine(line); + PingInformation pingInformation = pingParser.getLastPingInformation(); + Data.Builder progressOutput = new Data.Builder(); + if(line == null || pingInformation == null){ + 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()); + setForegroundAsync(createForegroundInfo(((RTTLine) pingInformation).getHost()+": " + rtt + " ms")); + Log.d(TAG, "doWork: RTT: " + rtt); + break; + case UNREACHABLE: + Log.e(TAG, "doWork: Unreachable destination"); + return Result.failure(progressOutput.putString(REASON, "Unreachable destination").build()); + case TIMEOUT: + Log.w(TAG, "doWork: Request timeout"); + 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); + break; + case UNKNOWN: + Log.w(TAG, "doWork: Unknown line type"); + break; + } + if(this.isStopped()){ break; } From b15e426b7ddaea1986399cba8bc29d0166465198 Mon Sep 17 00:00:00 2001 From: hajoha Date: Thu, 19 Jun 2025 10:03:43 +0200 Subject: [PATCH 08/10] fix togglebutons --- .../Ping/PingFragment.java | 150 +++++++++++------- .../Ping/PingInformations/RTTLine.java | 2 +- .../Ping/PingService.java | 13 +- .../Ping/Worker/PingWorker.java | 2 +- 4 files changed, 104 insertions(+), 63 deletions(-) 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 3b4bda5c..59d72a8c 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 @@ -10,7 +10,10 @@ import static android.view.View.INVISIBLE; +import static androidx.core.content.ContextCompat.getSystemService; + import android.annotation.SuppressLint; +import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -28,6 +31,7 @@ import android.widget.LinearLayout; import android.widget.Switch; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; @@ -81,6 +85,9 @@ public class PingFragment extends Fragment { private MetricView packetLossMetric; private WorkManager workManager; private ImageButton repeatButton; + private SharedPreferences.OnSharedPreferenceChangeListener listener; + private Observer observer; + private LiveData workInfoLiveData; public PingFragment() { } @@ -116,67 +123,92 @@ private void handleInput(boolean ping_running) { input.setEnabled(!ping_running); } - private void registerObserver() { - SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PingService.PING_LAST_UUID.equals(key)) { - String uuidStr = sharedPreferences.getString(PingService.PING_LAST_UUID, null); - if (uuidStr == null) return; - - UUID lastUUIDUUID = UUID.fromString(uuidStr); - Log.d(TAG, "registerObserver: lastUUID changed: " + lastUUIDUUID); - - LiveData liveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); - Observer observer = new Observer() { - @Override - public void onChanged(WorkInfo workInfo) { - 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); - } - - 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); - } - - switch (workInfo.getState()) { - case RUNNING: - case SUCCEEDED: - break; - case FAILED: - case CANCELLED: - liveData.removeObserver(this); // Optionally clean up - break; - default: - break; - } - } - }; - - liveData.observe(getViewLifecycleOwner(), observer); - } + + private void checkLastUUID(String uuidStr) { + if (uuidStr == null || !isAdded() || getView() == null) return; + + UUID lastUUIDUUID = UUID.fromString(uuidStr); + Log.d(TAG, "registerObserver: lastUUID changed: " + lastUUIDUUID); + if(workInfoLiveData != null){ + workInfoLiveData.removeObserver(observer); + } + + workInfoLiveData = workManager.getWorkInfoByIdLiveData(lastUUIDUUID); + observer = workInfo -> { + 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); } - }; - spg.getSharedPreference(SPType.ping_sp).registerOnSharedPreferenceChangeListener(listener); - } + 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); + } + switch (workInfo.getState()) { + case RUNNING: + case SUCCEEDED: + break; + case FAILED: + case CANCELLED: + workInfoLiveData.removeObserver(observer); // Optionally clean up + break; + default: + break; + } + }; + workInfoLiveData.observe(getViewLifecycleOwner(), observer); + + } private void setupRepeatButton(){ boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); - int color = ContextCompat.getColor(requireContext(), + int color = ContextCompat.getColor(ct, isRepeat ? R.color.design_default_color_primary : R.color.design_default_color_on_secondary); repeatButton.setColorFilter(color); } + @Override + 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)); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG, "onDestroy: PingFragment destroyed"); + spg.getSharedPreference(SPType.ping_sp).unregisterOnSharedPreferenceChangeListener(listener); + workInfoLiveData.removeObserver(observer); + } + + @Override + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Log.d(TAG, "onViewCreated: PingFragment view created"); + listener = (sharedPreferences, key) -> { + Log.d(TAG, "registerObserver: key changed: " + key); + if (PingService.PING_LAST_UUID.equals(key)) { + String uuidStr = sharedPreferences.getString(PingService.PING_LAST_UUID, null); + Log.d(TAG, "registerObserver: lastUUID changed "+uuidStr); + checkLastUUID(uuidStr); + + } + }; + + spg.getSharedPreference(SPType.ping_sp).registerOnSharedPreferenceChangeListener(listener); + + checkLastUUID(spg.getSharedPreference(SPType.ping_sp).getString(PingService.PING_LAST_UUID, null)); + } + @SuppressLint("UnspecifiedRegisterReceiverFlag") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -203,48 +235,45 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, saveTextInputToSharedPreferences(input, "ping_input"); boolean pingRunning = spg.getSharedPreference(SPType.ping_sp).getBoolean("ping_running", false); if (pingRunning) { - v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_start).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); } else { - v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_stop).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); } spg.setListener((sharedPreferences, key) -> { if (key != null && key.equals("ping_running")) { boolean isRunning = sharedPreferences.getBoolean("ping_running", false); handleInput(isRunning); if (isRunning) { - v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_start).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); v.findViewById(R.id.ping_stop).setBackgroundColor(Color.TRANSPARENT); } else { v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); - v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + v.findViewById(R.id.ping_stop).setBackgroundColor(ct.getResources().getColor(R.color.purple_500, null)); } } }, SPType.ping_sp); - input.setEnabled(!pingRunning); toggleGroup.addOnButtonCheckedListener((group, checkedId, isChecked) -> { Log.d(TAG, "onButtonChecked: " + checkedId); if (!isChecked) return; switch (checkedId) { case R.id.ping_start: - v.findViewById(R.id.ping_start).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + 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(); Intent startIntent = new Intent(ct, PingService.class); startIntent.putExtra(PingService.PING_INTENT_COMMAND, input.getText().toString()); startIntent.putExtra(PingService.PING_INTENT_ENABLE, true); ct.startService(startIntent); - registerObserver(); rttMetric.getMetricCalculator().resetMetric(); packetLossMetric.getMetricCalculator().resetMetric(); break; case R.id.ping_stop: v.findViewById(R.id.ping_start).setBackgroundColor(Color.TRANSPARENT); - v.findViewById(R.id.ping_stop).setBackgroundColor(requireContext().getResources().getColor(R.color.purple_500, null)); + 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(); Intent stopIntent = new Intent(ct, PingService.class); - stopIntent.setAction(PingService.PING_INTENT_COMMAND); stopIntent.putExtra(PingService.PING_INTENT_ENABLE, false); ct.startService(stopIntent); break; @@ -267,6 +296,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, metricsLL.addView(packetLossMetric); packetLossMetric.setVisibility(INVISIBLE); horizontalLL1.addView(metricsLL); + return v; } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java index fb3f70ba..b862cc40 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingInformations/RTTLine.java @@ -36,7 +36,7 @@ public void parse(){ // Group 3 = hostname, Group 4 = optional IP String hostname = matcher.group(3).trim(); String ip = matcher.group(4); - host = ip; + host = (ip != null) ? ip : hostname; rtt = Double.parseDouble(matcher.group(7)); } 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 c86e1b56..2ac9b351 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,11 +49,14 @@ 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(); + stopWorker(); } private void startWorker(String command) { String uuid = UUID.randomUUID().toString(); + PingParameter pingParameter = new PingParameter(command, uuid); PingInput pingInput = new PingInput(pingParameter, uuid); String gson = new Gson().toJson(pingInput, PingInput.class); @@ -71,7 +74,6 @@ private void startWorker(String command) { .addTag(PingToLineProtocolWorker.TAG) .build(); - spg.getSharedPreference(SPType.ping_sp).edit().putString(PING_LAST_UUID, pingWR.getId().toString()).apply(); registerObserver(command); WorkContinuation workContinuation = workManager.beginWith(pingWR).then(pingToLineProtocolWR); @@ -133,16 +135,25 @@ private void registerObserver(String command){ } + @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: Start ping service"); spg = SharedPreferencesGrouper.getInstance(getApplicationContext()); workManager = WorkManager.getInstance(getApplicationContext()); + if(intent == null){ + 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(); + return START_NOT_STICKY; + } String command = intent.getStringExtra(PING_INTENT_COMMAND); boolean isEnabled = intent.getBooleanExtra(PING_INTENT_ENABLE, false); if(!isEnabled){ stopWorker(); stopSelf(); + spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); return START_NOT_STICKY; } String lastUUID = spg.getSharedPreference(SPType.ping_sp).getString(PING_LAST_UUID, ""); 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 05d7a92a..4e21b6d3 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 @@ -95,7 +95,7 @@ public PingWorker(@NonNull Context context, @NonNull WorkerParameters workerPara private ForegroundInfo createForegroundInfo(String progress) { notification = notificationBuilder .setContentTitle("Ping") - .setContentText(pingInput.getPingParameter().getDestination()+": "+progress) + .setContentText(progress) .setOngoing(true) .setOnlyAlertOnce(true) .setColor(Color.WHITE) From b8673ccd775cf84182c8e68025c3133df9b9dc62 Mon Sep 17 00:00:00 2001 From: hajoha Date: Thu, 19 Jun 2025 10:19:29 +0200 Subject: [PATCH 09/10] fix togglebutton --- .../fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 59d72a8c..ccbf4a4a 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 @@ -249,8 +249,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, } 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(); + toggleGroup.check(R.id.ping_stop); } - } }, SPType.ping_sp); input.setEnabled(!pingRunning); From 4c433acf9ddbff153c5ee96a63cd80882b05864b Mon Sep 17 00:00:00 2001 From: hajoha Date: Thu, 19 Jun 2025 10:22:25 +0200 Subject: [PATCH 10/10] fix repeat button color --- .../fokus/OpenMobileNetworkToolkit/Ping/PingFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ccbf4a4a..18dc8339 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 @@ -169,7 +169,7 @@ private void checkLastUUID(String uuidStr) { private void setupRepeatButton(){ boolean isRepeat = spg.getSharedPreference(SPType.ping_sp).getBoolean("repeat_ping", false); int color = ContextCompat.getColor(ct, - isRepeat ? R.color.design_default_color_primary : R.color.design_default_color_on_secondary); + isRepeat ? R.color.design_default_color_primary : R.color.material_dynamic_secondary40); repeatButton.setColorFilter(color); }