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/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/RunResult/Iperf3ResultsDataBase.java index 981c2131..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 @@ -22,7 +22,7 @@ @Database( entities = {Iperf3RunResult.class}, - version = 3 + version = 4 ) public abstract class Iperf3ResultsDataBase extends RoomDatabase { @@ -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/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..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 -> { @@ -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(); 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/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..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 @@ -8,9 +8,15 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Ping; +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; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; @@ -21,25 +27,51 @@ 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.annotation.NonNull; +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; 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.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.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; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; public class PingFragment extends Fragment { private final String TAG = "PingFragment"; + private Switch aSwitch; private MaterialButtonToggleGroup toggleGroup; private LinearLayout verticalLL; @@ -51,6 +83,11 @@ public class PingFragment extends Fragment { private SharedPreferencesGrouper spg; private MetricView rttMetric; private MetricView packetLossMetric; + private WorkManager workManager; + private ImageButton repeatButton; + private SharedPreferences.OnSharedPreferenceChangeListener listener; + private Observer observer; + private LiveData workInfoLiveData; public PingFragment() { } @@ -61,19 +98,6 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } - 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 saveTextInputToSharedPreferences(EditText field, String name) { @@ -99,6 +123,92 @@ private void handleInput(boolean ping_running) { input.setEnabled(!ping_running); } + + 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); + } + + 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(ct, + isRepeat ? R.color.design_default_color_primary : R.color.material_dynamic_secondary40); + 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, @@ -106,53 +216,67 @@ 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); 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 -> { + 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)); + if (pingRunning) { + v.findViewById(R.id.ping_start).setBackgroundColor(ct.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(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(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(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(); + toggleGroup.check(R.id.ping_stop); } - } }, 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: - startPingService(); - v.findViewById(R.id.ping_start).setBackgroundColor(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); + 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(getResources().getColor(R.color.purple_500, null)); - stopPingService(); + 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.putExtra(PingService.PING_INTENT_ENABLE, false); + ct.startService(stopIntent); break; } @@ -171,26 +295,9 @@ 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..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 @@ -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 != null) ? ip : hostname; + 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/PingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java index aaf8086e..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 @@ -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,125 @@ 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; + spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping_running", false).apply(); + stopWorker(); } - private void setupPing(){ - Log.d(TAG, "starting Ping Service..."); + private void startWorker(String command) { + String uuid = UUID.randomUUID().toString(); - 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; - } + 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(); - // 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()); + 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; } - }; - - 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; + 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; } - 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; } + } 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 1f9e30de..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 @@ -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,15 +51,19 @@ 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 TAG = "PingWorker"; + 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; private final Context ct; 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) { @@ -71,13 +79,23 @@ 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("")); } private ForegroundInfo createForegroundInfo(String progress) { notification = notificationBuilder .setContentTitle("Ping") - .setContentText(pingInput.getPingParameter().getDestination()+": "+progress) + .setContentText(progress) .setOngoing(true) .setOnlyAlertOnce(true) .setColor(Color.WHITE) @@ -111,38 +129,56 @@ 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 = Float.parseFloat(Objects.requireNonNull(matcher.group(1))); - 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; } - // Optionally, report progress with the output line. - setProgressAsync(output.putString(LINE, line).build()); - } + if(this.isStopped()){ + break; + } + + } + process.destroy(); pingStream.close(); reader.close(); 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"); } 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..0b912a65 100644 --- a/app/src/main/res/layout/fragment_ping.xml +++ b/app/src/main/res/layout/fragment_ping.xml @@ -47,37 +47,65 @@ android:hint="Ping Command" tools:ignore="LabelFor,RtlSymmetry" /> - - - - + + android:layout_marginRight="10dp" + android:layout_weight="7"> + + + + + - - + + + + + + + + X State Parameter + if enabled, ping will repeat, until disabled Level AsuLevel\n "Signal Strength Level: "