From 033a9f1e8c63d73534cc748d1a3e0caf91a4a9bc Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 11:37:07 +0100 Subject: [PATCH 1/7] Add a nullguard to DetailFragment --- .../DetailFragment.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java index 2fbcb82c..dce4a0f0 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/DetailFragment.java @@ -27,6 +27,7 @@ import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; @@ -532,16 +533,19 @@ private CardView get_network_card_view() { NetworkCallback nc = new NetworkCallback(context); TableLayout tl = new TableLayout(context); - addRows(tl, new String[][]{ - {getString(R.string.networkOperatorName), ni.getNetworkOperatorName()}, - {getString(R.string.simOperatorName), ni.getSimOperatorName()}, - {getString(R.string.networkSpecifier), ni.getNetworkSpecifier()}, - {getString(R.string.dataState), ni.getDataStateString()}, - {getString(R.string.dataNetworkType), ni.getDataNetworkTypeString()}, - {getString(R.string.phoneType), ni.getPhoneTypeString()}, - {getString(R.string.preferredOpportunisticDataSubscriptionId), String.valueOf(ni.getPreferredOpportunisticDataSubscriptionId())}, - }, true); - + if (ni != null) { + addRows(tl, new String[][]{ + {getString(R.string.networkOperatorName), ni.getNetworkOperatorName()}, + {getString(R.string.simOperatorName), ni.getSimOperatorName()}, + {getString(R.string.networkSpecifier), ni.getNetworkSpecifier()}, + {getString(R.string.dataState), ni.getDataStateString()}, + {getString(R.string.dataNetworkType), ni.getDataNetworkTypeString()}, + {getString(R.string.phoneType), ni.getPhoneTypeString()}, + {getString(R.string.preferredOpportunisticDataSubscriptionId), String.valueOf(ni.getPreferredOpportunisticDataSubscriptionId())}, + }, true); + } else { + Toast.makeText(getContext(), "NetworkInformation was not ready!", Toast.LENGTH_SHORT).show(); + } if (GlobalVars.getInstance().isPermission_phone_state() && tm.getSimState() == TelephonyManager.SIM_STATE_READY) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { @@ -644,4 +648,4 @@ private CardView get_wifi_card_view() { public void onDestroyView() { super.onDestroyView(); } -} \ No newline at end of file +} From 2beea70dcb557443f31176d4f3e44040b3e4a7eb Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 12:15:33 +0100 Subject: [PATCH 2/7] Added nullguarding to QuickFragment too --- .../QuickFragment.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java index f9671c7c..868f05c7 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java @@ -1,5 +1,6 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit; +import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; @@ -10,6 +11,7 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; @@ -305,31 +307,36 @@ private void addCellInformationToView(CellInformation cellInformation){ final Runnable updateUI = new Runnable() { @Override public void run() { - mainLL.removeAllViews(); - List cellInformationList = dp.getRegisteredCells(); - List neighborCells = dp.getNeighbourCellInformation(); - if(cellInformationList.isEmpty()){ - LinearLayout error = new LinearLayout(context); - error.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - )); - error.setOrientation(LinearLayout.VERTICAL); - TextView errorText = new TextView(context); - errorText.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - )); - errorText.setText(getString(R.string.cell_na)); - error.addView(errorText); - mainLL.addView(error); - } else { - cellInformationList.forEach(cellInformation -> addCellInformationToView(cellInformation)); - } - if (spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false)) { - if(!neighborCells.isEmpty()){ - neighborCells.forEach(cellInformation -> addCellInformationToView(cellInformation)); + Activity parentActivity = getActivity(); + if (parentActivity != null && isAdded()) { + mainLL.removeAllViews(); + List cellInformationList = dp.getRegisteredCells(); + List neighborCells = dp.getNeighbourCellInformation(); + if (cellInformationList.isEmpty()) { + LinearLayout error = new LinearLayout(context); + error.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )); + error.setOrientation(LinearLayout.VERTICAL); + TextView errorText = new TextView(context); + errorText.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )); + errorText.setText(getString(R.string.cell_na)); + error.addView(errorText); + mainLL.addView(error); + } else { + cellInformationList.forEach(cellInformation -> addCellInformationToView(cellInformation)); } + if (spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false)) { + if (!neighborCells.isEmpty()) { + neighborCells.forEach(cellInformation -> addCellInformationToView(cellInformation)); + } + } + } else { + Toast.makeText(getContext(), "Tried updating QuickFragment UI while not being added/attached!", Toast.LENGTH_SHORT).show(); } updateUIHandler.postDelayed(updateUI, 500); } From 656930b7fe3f13f497d359ca099858fb54e7addf Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 16:52:44 +0100 Subject: [PATCH 3/7] Better fix for QuickFragment The old one was trying to make it safe for all view interactions rather than just making the getString() call safe when not attached... --- .../QuickFragment.java | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java index 868f05c7..3db647bc 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java @@ -1,6 +1,5 @@ package de.fraunhofer.fokus.OpenMobileNetworkToolkit; -import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; @@ -11,8 +10,8 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; +import androidx.annotation.StringRes; import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; @@ -307,36 +306,31 @@ private void addCellInformationToView(CellInformation cellInformation){ final Runnable updateUI = new Runnable() { @Override public void run() { - Activity parentActivity = getActivity(); - if (parentActivity != null && isAdded()) { - mainLL.removeAllViews(); - List cellInformationList = dp.getRegisteredCells(); - List neighborCells = dp.getNeighbourCellInformation(); - if (cellInformationList.isEmpty()) { - LinearLayout error = new LinearLayout(context); - error.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - )); - error.setOrientation(LinearLayout.VERTICAL); - TextView errorText = new TextView(context); - errorText.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - )); - errorText.setText(getString(R.string.cell_na)); - error.addView(errorText); - mainLL.addView(error); - } else { - cellInformationList.forEach(cellInformation -> addCellInformationToView(cellInformation)); - } - if (spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false)) { - if (!neighborCells.isEmpty()) { - neighborCells.forEach(cellInformation -> addCellInformationToView(cellInformation)); - } - } + mainLL.removeAllViews(); + List cellInformationList = dp.getRegisteredCells(); + List neighborCells = dp.getNeighbourCellInformation(); + if(cellInformationList.isEmpty()){ + LinearLayout error = new LinearLayout(context); + error.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )); + error.setOrientation(LinearLayout.VERTICAL); + TextView errorText = new TextView(context); + errorText.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )); + errorText.setText(getSafeString(R.string.cell_na)); + error.addView(errorText); + mainLL.addView(error); } else { - Toast.makeText(getContext(), "Tried updating QuickFragment UI while not being added/attached!", Toast.LENGTH_SHORT).show(); + cellInformationList.forEach(cellInformation -> addCellInformationToView(cellInformation)); + } + if (spg.getSharedPreference(SPType.default_sp).getBoolean("show_neighbour_cells", false)) { + if(!neighborCells.isEmpty()){ + neighborCells.forEach(cellInformation -> addCellInformationToView(cellInformation)); + } } updateUIHandler.postDelayed(updateUI, 500); } @@ -350,4 +344,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, updateUIHandler.postDelayed(updateUI, 500); return view; } + + public String getSafeString(@StringRes int resId) { + if (context == null) { + return "NOT AVAILABLE AT THE MOMENT"; + } else { + return context.getResources().getString(resId); + } + } } From 0ee07f5a79be417951c62528841cedebb5715911 Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 17:04:10 +0100 Subject: [PATCH 4/7] Different fix for MainActivity thread ... Rather than running the update thread on the Main Thread, lets run it in a handler. The handler will be backed by a separate HandlerThread and it seems like it will simply run forever... --- .../OpenMobileNetworkToolkit/MainActivity.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 3f3e54ca..68a9bc64 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java @@ -24,7 +24,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; +import android.os.HandlerThread; import android.os.StrictMode; import android.provider.Settings; import android.telephony.CarrierConfigManager; @@ -71,6 +71,7 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen Intent loggingServiceIntent; NavController navController; private Handler requestCellInfoUpdateHandler; + private HandlerThread requestCellInfoUpdateHandlerThread; private GlobalVars gv; /** * Runnable to handle Cell Info Updates @@ -191,8 +192,7 @@ protected void onCreate(Bundle savedInstanceState) { } } - requestCellInfoUpdateHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); - requestCellInfoUpdateHandler.post(requestCellInfoUpdate); + initHandlerAndHandlerThread(); loggingServiceIntent = new Intent(this, LoggingService.class); if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_logging", false)) { @@ -475,4 +475,11 @@ public boolean onPreferenceStartFragment(@NonNull PreferenceFragmentCompat calle } return true; } -} \ No newline at end of file + + private void initHandlerAndHandlerThread() { + requestCellInfoUpdateHandlerThread = new HandlerThread("RequestCellInfoUpdateHandlerThread"); + requestCellInfoUpdateHandlerThread.start(); + requestCellInfoUpdateHandler = new Handler(Objects.requireNonNull(requestCellInfoUpdateHandlerThread.getLooper())); + requestCellInfoUpdateHandler.post(requestCellInfoUpdate); + } +} From 0fa3ebf59f8ff5f7c7f14d115a710927ffe6b1f3 Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 17:46:53 +0100 Subject: [PATCH 5/7] PingService - moving things off of main thread --- .../Ping/PingService.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 aa895bcc..8f9f1f6e 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 @@ -6,6 +6,7 @@ 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; @@ -48,6 +49,7 @@ 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; @@ -128,7 +130,9 @@ private void setupPing(){ return; } spg.getSharedPreference(SPType.ping_sp).edit().putBoolean("ping", true).apply(); - pingLogging = new Handler(Objects.requireNonNull(Looper.myLooper())); + pingLoggingHandleThread = new HandlerThread("PingLoggingHandlerThread"); + pingLoggingHandleThread.start(); + pingLogging = new Handler(Objects.requireNonNull(pingLoggingHandleThread.getLooper())); PingParser pingParser = PingParser.getInstance(null); propertyChangeListener = pingParser.getListener(); if(propertyChangeListener != null){ @@ -230,6 +234,15 @@ public void onChanged(Object o) { private void stopPing(){ if (pingLogging != null )pingLogging.removeCallbacks(pingUpdate); + if (pingLoggingHandleThread != null) { + pingLoggingHandleThread.quitSafely(); + try { + pingLoggingHandleThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, "Exception happened!! "+e, e); + } + pingLoggingHandleThread = null; + } try { if (ping_stream != null) ping_stream.close(); } catch (IOException e) { From e7db9f63870ecc5cd79f0b2139c7af4d88868e2c Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Mon, 4 Nov 2024 19:10:32 +0100 Subject: [PATCH 6/7] LoggingService - moving things off of main thread Step1: moved LocalFileHandler Step2: moved NotificationHandler Step3: moved RemoteInfluxHandler Step4: moved LocalInfluxHandler Moving Handlers and their threads off of the UI thread because they were slowing things down a bit. --- .../LoggingService.java | 69 +++++++++++++++++-- 1 file changed, 62 insertions(+), 7 deletions(-) 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 4cdf5bc4..354632e1 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java @@ -19,8 +19,8 @@ import android.os.Build; 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.ImageView; import android.widget.Toast; @@ -60,9 +60,13 @@ public class LoggingService extends Service { DataProvider dp; SharedPreferencesGrouper spg; private Handler notificationHandler; + private HandlerThread notificationHandlerThread; private Handler remoteInfluxHandler; + private HandlerThread remoteInfluxHandlerThread; private Handler localInfluxHandler; + private HandlerThread localInfluxHandlerThread; private Handler localFileHandler; + private HandlerThread localFileHandlerThread; private List logFilePoints; private FileOutputStream stream; private int interval; @@ -250,6 +254,7 @@ public void onDestroy() { if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) { stopRemoteInfluxDB(); } + if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_local_file_log", false)) { stopLocalFile(); } @@ -398,8 +403,7 @@ private void setupLocalFile() { Log.d(TAG,e.toString()); } - localFileHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); - localFileHandler.post(localFileUpdate); + initLocalFileHandlerAndItsThread(); } private void stopLocalFile() { @@ -414,11 +418,22 @@ private void stopLocalFile() { Log.d(TAG,e.toString()); } } + + if (localFileHandlerThread != null) { + localFileHandlerThread.quitSafely(); + try { + localFileHandlerThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, "Exception happened!! "+e, e); + } + } } private void setupNotificationUpdate() { Log.d(TAG, "setupNotificationUpdate"); - notificationHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); + notificationHandlerThread = new HandlerThread("NotificationHandlerThread"); + notificationHandlerThread.start(); + notificationHandler = new Handler(Objects.requireNonNull(notificationHandlerThread.getLooper())); notificationHandler.post(notification_updater); } @@ -427,13 +442,25 @@ private void stopNotificationUpdate() { notificationHandler.removeCallbacks(notification_updater); builder.setContentText(null); nm.notify(1, builder.build()); + + if (notificationHandlerThread != null) { + notificationHandlerThread.quitSafely(); + try { + notificationHandlerThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, "Exception happened!! "+e, e); + } + notificationHandlerThread = null; + } } private void setupLocalInfluxDB() { Log.d(TAG, "setupLocalInfluxDB"); lic = InfluxdbConnections.getLicInstance(getApplicationContext()); Objects.requireNonNull(lic).open_write_api(); - localInfluxHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); + localInfluxHandlerThread = new HandlerThread("LocalInfluxHandlerThread"); + localInfluxHandlerThread.start(); + localInfluxHandler = new Handler(Objects.requireNonNull(localFileHandlerThread.getLooper())); localInfluxHandler.post(localInfluxUpdate); } @@ -449,6 +476,15 @@ private void stopLocalInfluxDB() { if (lic != null) { lic.disconnect(); } + if (localInfluxHandlerThread != null) { + localInfluxHandlerThread.quitSafely(); + try { + localInfluxHandlerThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, "Exception happened!! "+e, e); + } + localInfluxHandlerThread = null; + } } /** @@ -458,7 +494,9 @@ private void setupRemoteInfluxDB() { Log.d(TAG, "setupRemoteInfluxDB"); ic = InfluxdbConnections.getRicInstance(getApplicationContext()); Objects.requireNonNull(ic).open_write_api(); - remoteInfluxHandler = new Handler(Objects.requireNonNull(Looper.myLooper())); + remoteInfluxHandlerThread = new HandlerThread("RemoteInfluxHandlerThread"); + remoteInfluxHandlerThread.start(); + remoteInfluxHandler = new Handler(Objects.requireNonNull(remoteInfluxHandlerThread.getLooper())); remoteInfluxHandler.post(RemoteInfluxUpdate); ImageView log_status = gv.getLog_status(); if (log_status != null) { @@ -480,6 +518,16 @@ private void stopRemoteInfluxDB() { } } + if (remoteInfluxHandlerThread != null) { + remoteInfluxHandlerThread.quitSafely(); + try { + remoteInfluxHandlerThread.join(); + } catch (InterruptedException e) { + Log.e(TAG, "Exception happened!! "+e, e); + } + remoteInfluxHandlerThread = null; + } + // close disconnect influx connection if existing if (ic != null) { ic.disconnect(); @@ -496,4 +544,11 @@ private void stopRemoteInfluxDB() { public IBinder onBind(Intent intent) { return null; } -} \ No newline at end of file + + private void initLocalFileHandlerAndItsThread() { + localFileHandlerThread = new HandlerThread("LocalFileHandlerThread"); + localFileHandlerThread.start(); + localFileHandler = new Handler(Objects.requireNonNull(localFileHandlerThread.getLooper())); + localFileHandler.post(localFileUpdate); + } +} From 62a0bd1d17380fcfe3b9b40baafbb49a22be1774 Mon Sep 17 00:00:00 2001 From: RkShaRkz Date: Tue, 5 Nov 2024 12:01:13 +0100 Subject: [PATCH 7/7] Address CR comments --- .../fokus/OpenMobileNetworkToolkit/QuickFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java index 3db647bc..09b6b7de 100644 --- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java +++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/QuickFragment.java @@ -347,7 +347,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, public String getSafeString(@StringRes int resId) { if (context == null) { - return "NOT AVAILABLE AT THE MOMENT"; + return "N/A"; } else { return context.getResources().getString(resId); }