From bb171923eeacfa2675491da428fb3288df71beb4 Mon Sep 17 00:00:00 2001 From: Johann Date: Tue, 23 Jul 2024 18:00:26 +0200 Subject: [PATCH 01/21] update gui --- app/build.gradle | 2 +- .../Iperf3/Iperf3CardAdapter.java | 28 + .../Iperf3/Iperf3CardFragment.java | 44 ++ .../Iperf3/Iperf3Fragment.java | 560 +++++++++--------- .../main/res/layout/fragment_iperf3_card.xml | 196 ++++++ .../main/res/layout/fragment_iperf3_input.xml | 407 +++++-------- app/src/main/res/values/strings.xml | 16 +- app/src/main/res/values/styles.xml | 14 + 8 files changed, 723 insertions(+), 544 deletions(-) create mode 100644 app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardAdapter.java create mode 100644 app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardFragment.java create mode 100644 app/src/main/res/layout/fragment_iperf3_card.xml create mode 100644 app/src/main/res/values/styles.xml diff --git a/app/build.gradle b/app/build.gradle index 7cfa5b8e..8c328591 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -132,7 +132,6 @@ dependencies { implementation 'androidx.activity:activity:1.9.0' implementation 'androidx.fragment:fragment:1.8.1' implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.navigation:navigation-fragment:2.7.7' implementation 'androidx.navigation:navigation-ui:2.7.7' @@ -147,6 +146,7 @@ dependencies { implementation 'com.google.android.gms:play-services-location:21.3.0' implementation 'com.github.anastr:speedviewlib:1.6.1' implementation "androidx.viewpager2:viewpager2:1.1.0" + implementation "androidx.compose.material3:material3:1.2.1" } configurations.implementation { diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardAdapter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardAdapter.java new file mode 100644 index 00000000..031d9eb7 --- /dev/null +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardAdapter.java @@ -0,0 +1,28 @@ +package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +public class Iperf3CardAdapter extends FragmentStateAdapter { + + private final int numPages; + + public Iperf3CardAdapter(@NonNull FragmentActivity fragmentActivity, int numPages) { + super(fragmentActivity); + this.numPages = numPages; + } + + @NonNull + @Override + public Fragment createFragment(int position) { + // Return a new instance of the Iperf3CardFragment + return Iperf3CardFragment.newInstance(); + } + + @Override + public int getItemCount() { + return numPages; // Number of pages you want + } +} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardFragment.java new file mode 100644 index 00000000..fba3c882 --- /dev/null +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3CardFragment.java @@ -0,0 +1,44 @@ +package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; + +public class Iperf3CardFragment extends Fragment { + + private static final String ARG_POSITION = "position"; + private int position; + private TextView pageNumberTextView; + + public static Iperf3CardFragment newInstance(int position) { + Iperf3CardFragment fragment = new Iperf3CardFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_POSITION, position); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_iperf3_card, container, false); + + // Initialize the TextView + pageNumberTextView = view.findViewById(R.id.page_number_text_view); + + // Get the position argument and set the text + if (getArguments() != null) { + position = getArguments().getInt(ARG_POSITION, 1); + pageNumberTextView.setText("Page " + position); + } + + return view; + } +} diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java index 4a381bf5..e417e65f 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java @@ -39,13 +39,17 @@ import androidx.lifecycle.Observer; import androidx.navigation.NavController; import androidx.navigation.fragment.NavHostFragment; +import androidx.viewpager2.widget.ViewPager2; import androidx.work.Data; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkInfo; import androidx.work.WorkManager; +import androidx.work.Worker; import com.google.android.material.progressindicator.LinearProgressIndicator; import com.google.common.util.concurrent.ListenableFuture; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.button.MaterialButtonToggleGroup; import java.io.File; import java.io.IOException; @@ -55,9 +59,12 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.function.Consumer; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R; import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType; @@ -80,8 +87,12 @@ public class Iperf3Fragment extends Fragment { private final String IPERF3IDXPROTOCOL = "iperf3IdxProtocol"; private final String IPERF3IDXMODE = "iperf3IdxMode"; private final String IPERF3CPORT = "iperf3cport"; - private CheckBox iperf3BiDir; - private CheckBox iperf3Reverse; + + // Declare the toggle group and buttons + private MaterialButtonToggleGroup iperf3ModeToggleGroup; + private MaterialButton iperf3DownloadButton; + private MaterialButton iperf3UploadButton; + private MaterialButton iperf3BiDirButton; private CheckBox iperf3OneOff; private EditText iperf3EtIp; @@ -169,8 +180,6 @@ public void onChanged(String s) { iperf3EtBytes.setText(iperf3RunResult.input.iperf3Bytes); iperf3Cport.setText(iperf3RunResult.input.iperf3Cport); - iperf3Reverse.setChecked(iperf3RunResult.input.iperf3Reverse); - iperf3BiDir.setChecked(iperf3RunResult.input.iperf3BiDir); iperf3OneOff.setChecked(iperf3RunResult.input.iperf3OneOff); protocolSpinner.setSelection(iperf3RunResult.input.iperf3IdxProtocol); iperf3ModeSpinner.setSelection(iperf3RunResult.input.iperf3IdxMode); @@ -215,25 +224,40 @@ public void onClick(View v) { @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { v = inflater.inflate(R.layout.fragment_iperf3_input, parent, false); + ViewPager2 viewPager2 = v.findViewById(R.id.viewPager2); + int numPages = 3; // Set this to the number of pages you want + Iperf3CardAdapter adapter = new Iperf3CardAdapter(getActivity(), numPages); + viewPager2.setAdapter(adapter); + + //initializeViews(v); + //setupTextWatchers(); + //restoreTextInput(); + //setupProgressIndicator(); + //setupEditTextList(); + //setupButtons(); + //setupFragmentResultListener(); + //restorePreviousInputs(); + //setTemporaryDirectory(); + + return v; + } + + private void initializeViews(View v) { iperf3EtIp = v.findViewById(R.id.iperf3_ip); iperf3EtPort = v.findViewById(R.id.iperf3_port); iperf3EtBandwidth = v.findViewById(R.id.iperf3_bandwidth); iperf3EtDuration = v.findViewById(R.id.iperf3_duration); - - - - iperf3EtInterval = v.findViewById(R.id.iperf3_interval); iperf3EtBytes = v.findViewById(R.id.iperf3_bytes); iperf3EtStreams = v.findViewById(R.id.iperf3_streams); iperf3Cport = v.findViewById(R.id.iperf3_cport); progressIndicator = v.findViewById(R.id.iperf3_progress); + } + private void setupTextWatchers() { iperf3EtDuration.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -241,17 +265,12 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override - public void afterTextChanged(Editable s) { - - } + public void afterTextChanged(Editable s) {} }); - iperf3EtBytes.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -259,11 +278,11 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override - public void afterTextChanged(Editable s) { - - } + public void afterTextChanged(Editable s) {} }); + } + private void restoreTextInput() { saveTextInputToSharedPreferences(iperf3EtIp, IPERF3IP); saveTextInputToSharedPreferences(iperf3EtPort, IPERF3PORT); saveTextInputToSharedPreferences(iperf3EtBandwidth, IPERF3BANDWIDTH); @@ -272,19 +291,19 @@ public void afterTextChanged(Editable s) { saveTextInputToSharedPreferences(iperf3EtBytes, IPERF3BYTES); saveTextInputToSharedPreferences(iperf3EtStreams, IPERF3STREAMS); saveTextInputToSharedPreferences(iperf3Cport, IPERF3CPORT); + } - failedColors = new int[] {getContext().getColor(R.color.crimson), - getContext().getColor(R.color.crimson), getContext().getColor(R.color.crimson)}; - runningColors = new int[] {getContext().getColor(R.color.purple_500), - getContext().getColor(R.color.crimson), getContext().getColor(R.color.forestgreen)}; - succesColors = new int[] {getContext().getColor(R.color.forestgreen), - getContext().getColor(R.color.forestgreen), getContext().getColor(R.color.forestgreen)}; + private void setupProgressIndicator() { + failedColors = new int[]{getContext().getColor(R.color.crimson), getContext().getColor(R.color.crimson), getContext().getColor(R.color.crimson)}; + runningColors = new int[]{getContext().getColor(R.color.purple_500), getContext().getColor(R.color.crimson), getContext().getColor(R.color.forestgreen)}; + succesColors = new int[]{getContext().getColor(R.color.forestgreen), getContext().getColor(R.color.forestgreen), getContext().getColor(R.color.forestgreen)}; progressIndicator.setIndicatorColor(runningColors); - progressIndicator.setIndeterminateAnimationType( - LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS); + progressIndicator.setIndeterminateAnimationType(LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS); progressIndicator.setVisibility(LinearProgressIndicator.INVISIBLE); + } + private void setupEditTextList() { editTexts = new LinkedList<>(); editTexts.add(iperf3EtIp); editTexts.add(iperf3EtPort); @@ -294,105 +313,90 @@ public void afterTextChanged(Editable s) { editTexts.add(iperf3EtBytes); editTexts.add(iperf3EtStreams); editTexts.add(iperf3Cport); + } + + private void setupButtons() { sendBtn = v.findViewById(R.id.iperf3_send); instancesBtn = v.findViewById(R.id.iperf3_instances_button); sendBtn.setOnClickListener(this::executeIperfCommand); instancesBtn.setOnClickListener(this::showInstances); + } - iperf3BiDir = v.findViewById(R.id.iperf_bidir); - iperf3Reverse = v.findViewById(R.id.iperf3_reverse); - iperf3OneOff = v.findViewById(R.id.iperf3_one_off); - - saveCheckboxInputToSharedPreferences(iperf3BiDir, IPERF3BIDIR); - saveCheckboxInputToSharedPreferences(iperf3Reverse, IPERF3REVERSE); - saveCheckboxInputToSharedPreferences(iperf3OneOff, IPERF3ONEOFF); - - protocolSpinner = v.findViewById(R.id.iperf3_protocol_spinner); - ArrayAdapter adapter = - ArrayAdapter.createFromResource(getContext(), R.array.iperf_protocol, - R.layout.support_simple_spinner_dropdown_item); - adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item); - protocolSpinner.setAdapter(adapter); - - iperf3ModeSpinner = v.findViewById(R.id.iperf3_mode_spinner); - ArrayAdapter mode_adapter = - ArrayAdapter.createFromResource(getContext(), R.array.iperf_mode, - R.layout.support_simple_spinner_dropdown_item); - adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item); - iperf3ModeSpinner.setAdapter(mode_adapter); - - - getActivity().getSupportFragmentManager() - .setFragmentResultListener("input", getViewLifecycleOwner(), - new FragmentResultListener() { - @Override - public void onFragmentResult(@NonNull String requestKey, - @NonNull Bundle result) { - - Iperf3RunResult iperf3RunResult = - db.iperf3RunResultDao().getRunResult(result.getString("uid")); - String logFileName = iperf3RunResult.input.iperf3LogFileName.split("_")[0]; - if (logFileName.equals("iperf3")) { - logFileName = ""; - } - - iperf3EtIp.setText(iperf3RunResult.input.iperf3IP); - iperf3EtPort.setText(iperf3RunResult.input.iperf3Port); - iperf3EtBandwidth.setText(iperf3RunResult.input.iperf3Bandwidth); - iperf3EtDuration.setText(iperf3RunResult.input.iperf3Duration); - iperf3EtInterval.setText(iperf3RunResult.input.iperf3Interval); - iperf3EtBytes.setText(iperf3RunResult.input.iperf3Bytes); - iperf3EtStreams.setText(iperf3RunResult.input.streams); - iperf3Cport.setText(iperf3RunResult.input.iperf3Cport); - - iperf3Reverse.setChecked(iperf3RunResult.input.iperf3Reverse); - iperf3BiDir.setChecked(iperf3RunResult.input.iperf3BiDir); - iperf3OneOff.setChecked(iperf3RunResult.input.iperf3OneOff); - protocolSpinner.setSelection(iperf3RunResult.input.iperf3IdxProtocol); - iperf3ModeSpinner.setSelection(iperf3RunResult.input.iperf3IdxMode); - - writeToSP(); - } - }); - iperf3EtIp.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3IP, null)); - iperf3EtPort.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3PORT, null)); - iperf3EtBandwidth.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3BANDWIDTH, null)); - iperf3EtDuration.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3DURATION, null)); - iperf3EtInterval.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3INTERVAL, null)); - iperf3EtBytes.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3BYTES, null)); - iperf3EtStreams.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3STREAMS, null)); - iperf3Cport.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3CPORT, null)); - - iperf3BiDir.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3BIDIR, false)); - iperf3Reverse.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3REVERSE, false)); - iperf3OneOff.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3ONEOFF, false)); - protocolSpinner.setSelection(spg.getSharedPreference(SPType.iperf3_sp).getInt(IPERF3IDXPROTOCOL, 0)); - iperf3ModeSpinner.setSelection(spg.getSharedPreference(SPType.iperf3_sp).getInt(IPERF3IDXMODE, 0)); + private void setupFragmentResultListener() { + getActivity().getSupportFragmentManager().setFragmentResultListener("input", getViewLifecycleOwner(), new FragmentResultListener() { + @Override + public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) { + Iperf3RunResult iperf3RunResult = db.iperf3RunResultDao().getRunResult(result.getString("uid")); + populateFieldsFromRunResult(iperf3RunResult); + writeToSP(); + } + }); + } + + private void populateFieldsFromRunResult(Iperf3RunResult iperf3RunResult) { + String logFileName = iperf3RunResult.input.iperf3LogFileName.split("_")[0]; + if (logFileName.equals("iperf3")) { + logFileName = ""; + } + iperf3EtIp.setText(iperf3RunResult.input.iperf3IP); + iperf3EtPort.setText(iperf3RunResult.input.iperf3Port); + iperf3EtBandwidth.setText(iperf3RunResult.input.iperf3Bandwidth); + iperf3EtDuration.setText(iperf3RunResult.input.iperf3Duration); + iperf3EtInterval.setText(iperf3RunResult.input.iperf3Interval); + iperf3EtBytes.setText(iperf3RunResult.input.iperf3Bytes); + iperf3EtStreams.setText(iperf3RunResult.input.streams); + iperf3Cport.setText(iperf3RunResult.input.iperf3Cport); + } + + private void restorePreviousInputs() { + SharedPreferences sp = spg.getSharedPreference(SPType.iperf3_sp); + + iperf3EtIp.setText(sp.getString(IPERF3IP, null)); + iperf3EtPort.setText(sp.getString(IPERF3PORT, null)); + iperf3EtBandwidth.setText(sp.getString(IPERF3BANDWIDTH, null)); + iperf3EtDuration.setText(sp.getString(IPERF3DURATION, null)); + iperf3EtInterval.setText(sp.getString(IPERF3INTERVAL, null)); + iperf3EtBytes.setText(sp.getString(IPERF3BYTES, null)); + iperf3EtStreams.setText(sp.getString(IPERF3STREAMS, null)); + iperf3Cport.setText(sp.getString(IPERF3CPORT, null)); + } + + private void setTemporaryDirectory() { try { Os.setenv("TMPDIR", String.valueOf(getActivity().getCacheDir()), true); } catch (ErrnoException e) { e.printStackTrace(); } - return v; } + public void showInstances(View view) { + Bundle bundle = createIperf3Bundle(); + NavController navController = getNavController(); + navigateToRunnersList(navController, bundle); + } + + private Bundle createIperf3Bundle() { Bundle bundle = new Bundle(); bundle.putStringArrayList("iperf3List", uids); + return bundle; + } - NavController navController; - - NavHostFragment navHostFragment = - (NavHostFragment) getActivity().getSupportFragmentManager() + private NavController getNavController() { + NavHostFragment navHostFragment = (NavHostFragment) getActivity() + .getSupportFragmentManager() .findFragmentById(R.id.fragmentContainerView); - navController = navHostFragment.getNavController(); + return navHostFragment.getNavController(); + } + private void navigateToRunnersList(NavController navController, Bundle bundle) { navController.navigate(R.id.runners_list, bundle); } + private boolean isModeSpinnerClient() { String status = iperf3ModeSpinner.getSelectedItem().toString(); return status.equals("Client"); @@ -400,245 +404,260 @@ private boolean isModeSpinnerClient() { public void executeIperfCommand(View view) { String[] command = parseInput().split(" "); + String path = getPath(); + + createDirectoryIfNeeded(path); + setLogFileNames(path); + uids.add(0, input.uuid); + + Data iperf3Data = buildIperf3Data(command); + + ListenableFuture> status = iperf3WM.getWorkInfosByTag("iperf3Run"); - String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/omnt/iperf3LP/"; - if(input.iperf3Json){ + OneTimeWorkRequest iperf3WR = createWorkRequest(Iperf3Worker.class, iperf3Data, "iperf3Run", input.uuid); + OneTimeWorkRequest iperf3LP = createWorkRequest(Iperf3ToLineProtocolWorker.class, iperf3Data, null, null); + OneTimeWorkRequest iperf3UP = createWorkRequest(Iperf3UploadWorker.class, iperf3Data, "iperf3", null); + + saveIperf3RunResult(input.uuid); + + enqueueWorkRequests(iperf3WR, iperf3LP, iperf3UP); + observeWorkStatus(iperf3WR, iperf3UP); + } + + private String getPath() { + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/omnt/iperf3LP/"; + } + + private void createDirectoryIfNeeded(String path) { + if (input.iperf3Json) { try { Files.createDirectories(Paths.get(path)); } catch (IOException e) { - Toast.makeText(requireContext(),"Could not create Dir files!", Toast.LENGTH_SHORT).show(); + Toast.makeText(requireContext(), "Could not create Dir files!", Toast.LENGTH_SHORT).show(); } } + } - // create the log file; - + private void setLogFileNames(String path) { String iperf3WorkerID = input.uuid; - input.iperf3LineProtocolFile = path + iperf3WorkerID + ".txt"; - Data.Builder iperf3Data = new Data.Builder(); - iperf3Data.putStringArray("commands", command); - iperf3Data.putString("iperf3WorkerID", iperf3WorkerID); - iperf3Data.putString("rawIperf3file", rawIperf3file); - iperf3Data.putString("iperf3LineProtocolFile", input.iperf3LineProtocolFile); - iperf3Data.putString("measurementName", input.measurementName); - iperf3Data.putString("ip", input.iperf3IP); - iperf3Data.putString("port", input.iperf3Port); - iperf3Data.putString("bandwidth", input.iperf3Bandwidth); - iperf3Data.putString("duration", input.iperf3Duration); - iperf3Data.putString("interval", input.iperf3Interval); - iperf3Data.putString("bytes", input.iperf3Bytes); - iperf3Data.putString("protocol", protocolSpinner.getSelectedItem().toString()); - iperf3Data.putBoolean("rev", input.iperf3Reverse); - iperf3Data.putBoolean("biDir", input.iperf3BiDir); - iperf3Data.putBoolean("oneOff", input.iperf3OneOff); - iperf3Data.putString("client", iperf3ModeSpinner.getSelectedItem().toString()); - iperf3Data.putString("timestamp", input.timestamp.toString()); - iperf3Data.putString("protocol", protocolSpinner.getSelectedItem().toString()); - iperf3Data.putString("cport", input.iperf3Cport); - - ListenableFuture> status = iperf3WM.getWorkInfosByTag("iperf3Run"); - -/* try { - for (WorkInfo workInfo : status.get()) { - if (workInfo.getState().equals(WorkInfo.State.RUNNING)) { - Toast.makeText(getContext(), "iperf3 Test is running!", Toast.LENGTH_SHORT) - .show(); - return; - } - } - } catch (ExecutionException | InterruptedException e) { - e.printStackTrace(); - }*/ - - uids.add(0, iperf3WorkerID); - iperf3Data.putInt("notificationID", uids.size()); - + } - OneTimeWorkRequest iperf3WR = - new OneTimeWorkRequest - .Builder(Iperf3Worker.class) - .setInputData(iperf3Data.build()) - .addTag("iperf3Run") - .addTag(iperf3WorkerID) - .build(); - OneTimeWorkRequest iperf3LP = - new OneTimeWorkRequest - .Builder(Iperf3ToLineProtocolWorker.class) - .setInputData(iperf3Data.build()) - .build(); - OneTimeWorkRequest iperf3UP = - new OneTimeWorkRequest - .Builder(Iperf3UploadWorker.class) - .setInputData(iperf3Data.build()) - .addTag("iperf3") + private Data buildIperf3Data(String[] command) { + return new Data.Builder() + .putStringArray("commands", command) + .putString("iperf3WorkerID", input.uuid) + .putString("rawIperf3file", rawIperf3file) + .putString("iperf3LineProtocolFile", input.iperf3LineProtocolFile) + .putString("measurementName", input.measurementName) + .putString("ip", input.iperf3IP) + .putString("port", input.iperf3Port) + .putString("bandwidth", input.iperf3Bandwidth) + .putString("duration", input.iperf3Duration) + .putString("interval", input.iperf3Interval) + .putString("bytes", input.iperf3Bytes) + .putString("protocol", protocolSpinner.getSelectedItem().toString()) + .putBoolean("rev", input.iperf3Reverse) + .putBoolean("biDir", input.iperf3BiDir) + .putBoolean("oneOff", input.iperf3OneOff) + .putString("client", iperf3ModeSpinner.getSelectedItem().toString()) + .putString("timestamp", input.timestamp.toString()) + .putString("cport", input.iperf3Cport) + .putInt("notificationID", uids.size()) .build(); + } - iperf3RunResultDao.insert( - new Iperf3RunResult(iperf3WorkerID, -100, false, input, input.timestamp)); + private OneTimeWorkRequest createWorkRequest(Class workerClass, Data data, String... tags) { + OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(workerClass).setInputData(data); + if (tags != null) { + for (String tag : tags) { + if (tag != null) { + builder.addTag(tag); + } + } + } + return builder.build(); + } + private void saveIperf3RunResult(String iperf3WorkerID) { + iperf3RunResultDao.insert(new Iperf3RunResult(iperf3WorkerID, -100, false, input, input.timestamp)); + } + private void enqueueWorkRequests(OneTimeWorkRequest iperf3WR, OneTimeWorkRequest iperf3LP, OneTimeWorkRequest iperf3UP) { if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false) && input.iperf3Json) { iperf3WM.beginWith(iperf3WR).then(iperf3LP).then(iperf3UP).enqueue(); - } else if(input.iperf3Json) { + } else if (input.iperf3Json) { iperf3WM.beginWith(iperf3WR).then(iperf3LP).enqueue(); } else { iperf3WM.beginWith(iperf3WR).enqueue(); } + } - - + private void observeWorkStatus(OneTimeWorkRequest iperf3WR, OneTimeWorkRequest iperf3UP) { Handler progressbarHandler = new Handler(Looper.myLooper()); iperf3WM.getWorkInfoByIdLiveData(iperf3WR.getId()).observeForever(workInfo -> { - int iperf3_result; - iperf3_result = workInfo.getOutputData().getInt("iperf3_result", -100); + int iperf3_result = workInfo.getOutputData().getInt("iperf3_result", -100); if (workInfo.getState().equals(WorkInfo.State.CANCELLED)) { iperf3_result = -1; } - iperf3RunResultDao.updateResult(iperf3WorkerID, iperf3_result); - Log.d(TAG, "onChanged: iperf3_result: " + iperf3_result); - if (iperf3_result == -100) { - progressIndicator.setVisibility(LinearProgressIndicator.VISIBLE); - if (!isModeSpinnerClient()) { - progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR); - } - } else if (iperf3_result != 0) { - progressIndicator.setIndicatorColor(failedColors); - progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR); + iperf3RunResultDao.updateResult(input.uuid, iperf3_result); + updateProgressIndicator(iperf3_result, progressbarHandler); + }); - } else { - progressIndicator.setIndicatorColor(succesColors); + iperf3WM.getWorkInfoByIdLiveData(iperf3UP.getId()).observeForever(workInfo -> { + boolean iperf3_upload = workInfo.getOutputData().getBoolean("iperf3_upload", false); + iperf3RunResultDao.updateUpload(input.uuid, iperf3_upload); + }); + } + + private void updateProgressIndicator(int iperf3_result, Handler progressbarHandler) { + if (iperf3_result == -100) { + progressIndicator.setVisibility(LinearProgressIndicator.VISIBLE); + if (!isModeSpinnerClient()) { progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR); } + } else if (iperf3_result != 0) { + progressIndicator.setIndicatorColor(failedColors); + progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR); + } else { + progressIndicator.setIndicatorColor(succesColors); + progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR); + } + } - }); - iperf3WM.getWorkInfoByIdLiveData(iperf3UP.getId()).observeForever(workInfo -> { - boolean iperf3_upload; - iperf3_upload = workInfo.getOutputData().getBoolean("iperf3_upload", false); - Log.d(TAG, "onChanged: iperf3_upload: " + iperf3_upload); - iperf3RunResultDao.updateUpload(iperf3WorkerID, iperf3_upload); - }); + private String getKeyFromId(String id, String value) { + Map commandMap = createCommandMap(); + + if (commandMap.containsKey(id)) { + CommandInfo commandInfo = commandMap.get(id); + commandInfo.setInput(value); + return commandInfo.getKey(); + } + + return ""; + } + + private Map createCommandMap() { + Map commandMap = new HashMap<>(); + + commandMap.put("iperf3_logfile", new CommandInfo("--logfile", value -> input.measurementName = value)); + commandMap.put("iperf3_streams", new CommandInfo("-P", value -> input.streams = value)); + commandMap.put("iperf3_ip", new CommandInfo("-c", value -> input.iperf3IP = value)); + commandMap.put("iperf3_port", new CommandInfo("-p", value -> input.iperf3Port = value)); + commandMap.put("iperf3_bandwidth", new CommandInfo("-b", value -> input.iperf3Bandwidth = value)); + commandMap.put("iperf3_duration", new CommandInfo("-t", value -> input.iperf3Duration = value)); + commandMap.put("iperf3_interval", new CommandInfo("-i", value -> input.iperf3Interval = value)); + commandMap.put("iperf3_bytes", new CommandInfo("-n", value -> input.iperf3Bytes = value)); + commandMap.put("iperf3_cport", new CommandInfo("--cport", value -> input.iperf3Cport = value)); + return commandMap; } - private String getKeyFromId(String s, String value) { - String key = ""; - switch (s) { - case "iperf3_logfile": - key = "--logfile"; - input.measurementName = value; - break; - case "iperf3_streams": - key = "-P"; - input.streams = value; - break; - case "iperf3_ip": - key = "-c"; - input.iperf3IP = value; - break; - case "iperf3_port": - key = "-p"; - input.iperf3Port = value; - break; - case "iperf3_bandwidth": - key = "-b"; - input.iperf3Bandwidth = value; - break; - case "iperf3_duration": - key = "-t"; - input.iperf3Duration = value; - break; - case "iperf3_interval": - key = "-i"; - input.iperf3Interval = value; - break; - case "iperf3_bytes": - key = "-n"; - input.iperf3Bytes = value; - break; - case "iperf3_cport": - key = "--cport"; - input.iperf3Cport = value; - break; + private static class CommandInfo { + private final String key; + private final Consumer inputSetter; + + public CommandInfo(String key, Consumer inputSetter) { + this.key = key; + this.inputSetter = inputSetter; + } + + public String getKey() { + return key; + } + + public void setInput(String value) { + inputSetter.accept(value); } - return key; } + private String parseInput() { - List stb = new LinkedList<>(); + List commandParts = new LinkedList<>(); + + addEditTextValues(commandParts); + addProtocolOption(commandParts); + setInputMetadata(); + addLogFileOptions(commandParts); + addModeOptions(commandParts); + addAdditionalOptions(commandParts); + + String command = String.join(" ", commandParts); + + Log.d(TAG, "parseInput: joined command " + command); + input.iperf3Command = command; + + return command; + } + + private void addEditTextValues(List commandParts) { for (EditText et : editTexts) { String value = et.getText().toString(); - if (!value.equals("")) { - String s = getResources().getResourceEntryName(et.getId()); - String key = getKeyFromId(s, value); - if (s.equals("iperf3_bandwidth")) { + if (!value.isEmpty()) { + String resourceName = getResources().getResourceEntryName(et.getId()); + String key = getKeyFromId(resourceName, value); + if (resourceName.equals("iperf3_bandwidth")) { value += "M"; } - stb.add(key); - stb.add(value); + commandParts.add(key); + commandParts.add(value); } } + } + private void addProtocolOption(List commandParts) { String protocol = protocolSpinner.getSelectedItem().toString(); if (!protocol.equals("TCP")) { - stb.add("--" + protocol.toLowerCase()); + commandParts.add("--" + protocol.toLowerCase()); } input.iperf3IdxProtocol = protocolSpinner.getSelectedItemPosition(); + } + private void setInputMetadata() { input.timestamp = new Timestamp(System.currentTimeMillis()); String iperf3TS = input.timestamp.toString().replace(" ", "_").replace(":", "_"); input.uuid = UUID.randomUUID().toString(); - input.measurementName = "Iperf3"; this.logFileName = String.format("iperf3_%s_%s.json", iperf3TS, input.uuid); - input.iperf3LogFileName = this.logFileName; + this.rawIperf3file = this.logFileDir + this.logFileName; input.iperf3rawIperf3file = this.rawIperf3file; + } + + private void addLogFileOptions(List commandParts) { + commandParts.add("--logfile"); + commandParts.add(this.rawIperf3file); + } - stb.add("--logfile"); - stb.add(this.rawIperf3file); + private void addModeOptions(List commandParts) { - input.iperf3BiDir = false; - input.iperf3Reverse = false; - input.iperf3OneOff = false; + input.iperf3OneOff = iperf3OneOff.isChecked(); input.iperf3Json = true; if (!isModeSpinnerClient()) { - stb.add("-s"); + commandParts.add("-s"); input.iperf3IdxMode = iperf3ModeSpinner.getSelectedItemPosition(); } - if (iperf3BiDir.isChecked()) { - stb.add("--bidir"); - input.iperf3BiDir = true; - } - if (iperf3Reverse.isChecked()) { - stb.add("--reverse"); - input.iperf3Reverse = true; - } - if (iperf3OneOff.isChecked()) { - stb.add("--one-off"); - input.iperf3OneOff = true; - } - stb.add("--json-stream"); - - stb.add("--connect-timeout"); - stb.add("500"); - - - String joined = String.join(" ", stb); + } - Log.d(TAG, "parseInput: joined command " + joined); - input.iperf3Command = joined; + private void addAdditionalOptions(List commandParts) { + if (iperf3OneOff.isChecked()) { + commandParts.add("--one-off"); + } + commandParts.add("--json-stream"); - return joined; + commandParts.add("--connect-timeout"); + commandParts.add("500"); } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -657,8 +676,7 @@ private void writeToSP() { editor.putString(IPERF3STREAMS, iperf3EtStreams.getText().toString()); editor.putString(IPERF3CPORT, iperf3Cport.getText().toString()); - editor.putBoolean(IPERF3BIDIR, iperf3BiDir.isChecked()); - editor.putBoolean(IPERF3REVERSE, iperf3Reverse.isChecked()); + editor.putBoolean(IPERF3ONEOFF, iperf3OneOff.isChecked()); editor.apply(); } diff --git a/app/src/main/res/layout/fragment_iperf3_card.xml b/app/src/main/res/layout/fragment_iperf3_card.xml new file mode 100644 index 00000000..590f680a --- /dev/null +++ b/app/src/main/res/layout/fragment_iperf3_card.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_iperf3_input.xml b/app/src/main/res/layout/fragment_iperf3_input.xml index 61fa0ff7..dd720af4 100644 --- a/app/src/main/res/layout/fragment_iperf3_input.xml +++ b/app/src/main/res/layout/fragment_iperf3_input.xml @@ -7,287 +7,166 @@ ~ SPDX-License-Identifier: BSD-3-Clause-Clear --> - + android:orientation="vertical"> - + - - - - - - - - - - - - - - - - - - - -