diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..a495ae22 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,41 @@ +--- +name: Bug Report +about: Use this template for creating bug report. +title: "[BUG] - BUG_DESCRIPTION" +labels: bug +assignees: "" +--- + +## Bug Report + +### Context +- **Device:** +- **Carrier Privileges (Y/N):** +- **Android Version:** +- **App Version:** +- **Git Hash:** + +### Description + + +### How to Reproduce +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '...' +3. Scroll down to '...' +4. See error + +### Expected Behavior + + +### Actual Behavior + + +### Screenshots + + +### Additional Context + + +### Possible Fix + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 00000000..753c5d57 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,27 @@ +--- +name: Feature Request +about: Use this template for creating feature request. +title: "[FEATURE] - FEATURE_DESCRIPTION" +labels: feature +assignees: "" +--- + +## Feature Request + +### Summary + + +### Context + + +### Proposed Solution + + +### Alternatives Considered + + +### Additional Context + + +### Related Issues + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d3bed70..02316bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,20 @@ # OpenMobileNetworkToolkit Changelog +## Release [0.3.1] + +### Added +- Add Issue Template [PR 21](https://github.com/omnt/OpenMobileNetworkToolkit/pull/21) + +### Changed +- Use [TelephonyCallback](https://developer.android.com/reference/android/telephony/TelephonyCallback) instead of [PhoneStateListener](https://developer.android.com/reference/android/telephony/PhoneStateListener) +- Bump gradle to 8.5.0 +- Bump lib depencies +- disable Radio Settings if Carrier Permissions are not available +- minor documentation update + +### Fixed +- Fix Bug if DP is not available, resulting in a crash +- Fix Bug if two Sim Cards are available, see [Issue 22](https://github.com/omnt/OpenMobileNetworkToolkit/issues/22) + ## Release [0.3] ### Added @@ -11,7 +27,7 @@ - iPerf3 GUI [PR 14](https://github.com/omnt/OpenMobileNetworkToolkit/pull/14) - Fix Ping Bug, where button is enabled but now Ping is running after app restart [PR 14](https://github.com/omnt/OpenMobileNetworkToolkit/pull/14) - Update Ping Fragment, now uses the Metric class to display [PR 14](https://github.com/omnt/OpenMobileNetworkToolkit/pull/14) -- + ### Breaking Changes - see [PR 14](https://github.com/omnt/OpenMobileNetworkToolkit/pull/14) diff --git a/app/build.gradle b/app/build.gradle index 8f016df5..a734ee29 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -122,10 +122,10 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'com.google.guava:guava:33.1.0-jre' + implementation 'com.google.guava:guava:33.2.1-jre' implementation 'androidx.concurrent:concurrent-futures:1.2.0' implementation 'androidx.activity:activity:1.9.0' - implementation 'androidx.fragment:fragment:1.8.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' @@ -133,8 +133,8 @@ dependencies { implementation 'androidx.navigation:navigation-ui:2.7.7' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.3.2' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DataProvider/DataProvider.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DataProvider/DataProvider.java index 17177cc0..eb938b0b 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DataProvider/DataProvider.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DataProvider/DataProvider.java @@ -74,7 +74,7 @@ import de.fraunhofer.fokus.OpenMobileNetworkToolkit.GlobalVars; -public class DataProvider extends PhoneStateListener implements LocationListener, TelephonyCallback.CellInfoListener, TelephonyCallback.PhysicalChannelConfigListener { +public class DataProvider extends TelephonyCallback implements LocationListener, TelephonyCallback.CellInfoListener, TelephonyCallback.PhysicalChannelConfigListener, TelephonyCallback.SignalStrengthsListener { private static final String TAG = "DataProvider"; private final Context ct; private final SharedPreferences sp; @@ -191,7 +191,6 @@ public Point getNetworkInformationPoint() { // ## Device Information - @SuppressLint({"MissingPermission", "HardwareIds", "ObsoleteSdkInt"}) public void refreshDeviceInformation() { updateTimestamp(); di.setTimeStamp(ts); @@ -210,13 +209,19 @@ public void refreshDeviceInformation() { if (permission_phone_state) { di.setDeviceSoftwareVersion(String.valueOf(tm.getDeviceSoftwareVersion())); } + Log.d(TAG, "refreshDeviceInformation: Carrier Privileges is " + cp); if (cp) { // todo try root privileges or more fine granular permission - di.setIMEI(tm.getImei()); - di.setMEID(tm.getMeid()); + try { + di.setIMEI(tm.getImei()); + di.setMEID(tm.getMeid()); + di.setSimSerial(tm.getSimSerialNumber()); + di.setSubscriberId(tm.getSubscriberId()); + di.setNetworkAccessIdentifier(tm.getNai()); + } catch (SecurityException e) { + Log.d(TAG, "Can't get IMEI, MEID, SimSerial or SubscriberId"); + } di.setIMSI(getIMSI()); - di.setSimSerial(tm.getSimSerialNumber()); - di.setSubscriberId(tm.getSubscriberId()); - di.setNetworkAccessIdentifier(tm.getNai()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { di.setSubscriberId(String.valueOf(tm.getSubscriptionId())); } @@ -280,7 +285,6 @@ public List getNetworkInterfaceInformationPoints() { return points; } - // ### Cell Information ### /** @@ -526,8 +530,6 @@ public Point getNetworkCapabilitiesPoint() { point.addField("MobileRxBytes", TrafficStats.getMobileRxBytes()); return point; } - - // ### Signal Strength Information ### @SuppressLint("ObsoleteSdkInt") @Override @@ -837,7 +839,15 @@ public List getSubscriptions() { } else { subscriptions = sm.getActiveSubscriptionInfoList(); } - return subscriptions; + + ArrayList activeSubscriptions = new ArrayList<>(); + for (SubscriptionInfo info : Objects.requireNonNull(subscriptions)) { + Log.d(TAG, "Subscription Info: " + info.toString()); + if(tm.getSimState(info.getSimSlotIndex()) == TelephonyManager.SIM_STATE_READY){ + activeSubscriptions.add(info); + } + } + return activeSubscriptions; } /** diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java index 75a4dfaa..45bf2e5a 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java @@ -103,6 +103,10 @@ public void run() { private final Runnable notification_updater = new Runnable() { @Override public void run() { + if(dp == null) { + Log.e(TAG, "run: Dataprovider is null!"); + return; + } List cil = dp.getRegisteredCells(); StringBuilder s = new StringBuilder(); for (CellInformation ci : cil) { 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 cfd384f5..8da549f7 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java @@ -235,7 +235,6 @@ public void onClick(DialogInterface dialog, int which) { } requestCellInfoUpdateHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); requestCellInfoUpdateHandler.post(requestCellInfoUpdate); - tm.listen(dp, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); } 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 037950c2..76805f60 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 @@ -64,22 +64,7 @@ private void startPingService(){ Intent pingStart = new Intent(ct, PingService.class); ct.startService(pingStart); rttMetric.resetMetric(); - PingParser pingParser = PingParser.getInstance(null); - pingParser.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent 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.resetMetric(); } private void stopPingService(){ input.setEnabled(true); @@ -123,7 +108,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, aSwitch = verticalLL.findViewById(R.id.ping_switch); input = verticalLL.findViewById(R.id.ping_input); input.setText(sp.getString("ping_input", "-w 5 8.8.8.8")); - + input.setEnabled(!PingService.isRunning()); ct = requireContext(); saveTextInputToSharedPreferences(input, "ping_input"); @@ -150,6 +135,25 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean b) { metricsLL.addView(packetLossMetric.createMainLL("Packet Loss [%]")); horizontalLL1.addView(metricsLL); + + + PingParser pingParser = PingParser.getInstance(null); + pingParser.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent 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/PingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingService.java index 3db18077..646bc749 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 @@ -57,7 +57,6 @@ public class PingService extends Service { private static final String TAG = "PingService"; private FileOutputStream ping_stream; private Handler pingLogging; - private String pingInput; private WorkManager wm; private Context context; private ArrayList pingWRs; @@ -67,10 +66,7 @@ public class PingService extends Service { DataProvider dp; InfluxdbConnection influx; private static boolean isRunning = false; - private static PingParser pingParser; - private Process pingProcess; private String pingCommand; - private Runtime runtime = Runtime.getRuntime(); private PropertyChangeListener propertyChangeListener; HashMap parsedCommand = new HashMap<>(); @@ -95,9 +91,10 @@ public int onStartCommand(Intent intent, int flags, int startId) { defaultSP = PreferenceManager.getDefaultSharedPreferences(context); if(defaultSP.getBoolean("enable_influx", false)) influx = InfluxdbConnections.getRicInstance(context); wm = WorkManager.getInstance(context); + wm.cancelAllWorkByTag("Ping"); if(intent == null) return START_NOT_STICKY; - pingInput = intent.getStringExtra("input"); pingWRs = new ArrayList<>(); + setupPing(); isRunning = true; return START_STICKY; @@ -233,6 +230,7 @@ public void onChanged(Object o) { } wm.getWorkInfoByIdLiveData(pingWR.getId()).removeObserver(this); + pingWRs.remove(pingWR); pingLogging.postDelayed(pingUpdate, 200); } }; diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingWorker.java index df2062af..b3b2f0bf 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingWorker.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Ping/PingWorker.java @@ -162,7 +162,6 @@ public void propertyChange(PropertyChangeEvent evt) { case RTT: rtt = ((RTTLine)pi).getRtt(); break; - } updateNotification.run(); } diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java index 3ef247e3..b6a1ba1d 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/SettingPreferences/MobileNetworkSettingsFragment.java @@ -70,16 +70,31 @@ private boolean setNetworkSelection(){ } private void handleSetNetwork(){ - boolean result = setNetworkSelection(); - Toast.makeText(ct, String.valueOf(result), Toast.LENGTH_SHORT).show(); + if(gv.isCarrier_permissions()){ + if(setNetworkSelection()){ + Toast.makeText(ct, "Network Selection Successful", Toast.LENGTH_SHORT).show(); + return; + } else { + Toast.makeText(ct, "Network Selection Failed", Toast.LENGTH_SHORT).show(); + return; + } + } + Toast.makeText(ct, "App doesn't have Carrier Permissions", Toast.LENGTH_SHORT).show(); } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); DropDownPreference selectNetworkType = findPreference(SELECTNETWORKTYPE); EditTextPreference inputPLMN = findPreference(ADDPLMN); SwitchPreference reboot = findPreference(PERSISTREBOOT); + + if(!gv.isCarrier_permissions()){ + selectNetworkType.setEnabled(false); + inputPLMN.setEnabled(false); + reboot.setEnabled(false); + } ct = requireContext(); plmnId = ct.getString(R.string.select_plmn); accessNetworkType = ct.getString(R.string.access_networktype); diff --git a/build.gradle b/build.gradle index 0273d8d5..b827f8d9 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.4.2' + classpath 'com.android.tools.build:gradle:8.5.0' def nav_version = "2.5.3" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21' diff --git a/docs/images/iperf3_edit.gif b/docs/images/iperf3_edit.gif new file mode 100644 index 00000000..11284e71 Binary files /dev/null and b/docs/images/iperf3_edit.gif differ diff --git a/docs/images/iperf3_stop.gif b/docs/images/iperf3_stop.gif new file mode 100644 index 00000000..b548a0da Binary files /dev/null and b/docs/images/iperf3_stop.gif differ diff --git a/docs/iperf3.md b/docs/iperf3.md index ca951c2a..f929cc10 100644 --- a/docs/iperf3.md +++ b/docs/iperf3.md @@ -13,6 +13,15 @@ You can type into the GUI the server IP and port, the duration of the test, and You can also choose the protocol you want to use, TCP or UDP. ![iPerf3](images/iperf3.png) +#### Stop iPerf3 Run +To stop an iPerf3 run, click on the `Instance` button, swipe left on the instance you want to stop, and click on the `Stop` button. +![iPerf3_stop](images/iperf3_stop.gif) + +#### Edit iPerf3 Run +To stop an iPerf3 run, click on the `Instance` button, swipe right on the instance you want to stop, and click on the `Edit` button. +![iPerf3_edit](images/iperf3_edit.gif) + + ### Results The results of the iPerf3 test are displayed in the GUI. ![iPerf3_results](images/iPerf3_run_view.gif) diff --git a/docs/ping.md b/docs/ping.md index 415ff562..3e8bacfa 100644 --- a/docs/ping.md +++ b/docs/ping.md @@ -2,6 +2,5 @@ [ICMP](https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol) allows a high level analysis of the current network conditions. The input field allows entering the target IP address as well as options of the ICMP command. If logging is enabled, the results of the ICMP test are pushed to the InfluxDB and can be viewed in the dashboards. The most relevant KPIs gathered here are: * packet loss * RTT round trip time -* jitter [Home](OpenMobileNetworkToolkit.md) \ No newline at end of file diff --git a/docs/quick-start.md b/docs/quick-start.md index 6ee282ea..1aee5c59 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -17,9 +17,11 @@ both services can be used for free to get a first impression, more advanced usag # Installation The simplest way to install the app is by downloading it on the phone, if ADB is at hand installing via adb more convenient. -The latest release APK can be found on the [Github release page](https://github.com/omnt/OpenMobileNetworkToolkit/releases/). +The latest release APK ```omnt-release.apk``` can be found on the [Github release page](https://github.com/omnt/OpenMobileNetworkToolkit/releases/). + + + adb install omnt-release.apk - adb install release.apk or use android studio to build and install OMNT. Follow [build](build.md) for more information on building the app. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 928f96bc..45559980 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,15 +1,7 @@ -# -# SPDX-FileCopyrightText: 2023 Peter Hasse -# SPDX-FileCopyrightText: 2023 Johann Hackler -# SPDX-FileCopyrightText: 2023 Fraunhofer FOKUS -# -# SPDX-License-Identifier: BSD-3-Clause-Clear -# - -#Thu Oct 12 12:17:46 CEST 2023 +#Fri Jul 05 13:11:21 CEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-rc-1-bin.zip r= zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists