]> gitweb.stoutner.com Git - PrivacyCell.git/blobdiff - app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt
Release 1.10.
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / services / RealtimeMonitoringService.kt
index 5d9ad3a4a76f6f7d746c9dfc6148e0ebb7fe8467..72ace814d742aac8de7f08c6e4540ba2205b302e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2023 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
  *
@@ -148,47 +148,65 @@ class RealtimeMonitoringService : Service() {
             // Set the color.
             notificationBuilder.setColor(getColor(R.color.red_notification_icon))
 
+            // Prevent swiping to dismiss the notification.  This no longer works (except on the lock screen) in API >= 34.
+            notificationBuilder.setOngoing(true)
+
             // Start the foreground notification.
             startForeground(NOTIFICATION_ID, notificationBuilder.build())
 
             // Instantiate the protocol helper.
             val protocolHelper = ProtocolHelper()
 
+            // Get a handle for the telephony manager.
+            val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
             // Define the phone state listener.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
             phoneStateListener = object : PhoneStateListener() {
                 @Deprecated("Deprecated in Java")
                 override fun onServiceStateChanged(serviceState: ServiceState) {  // Update the voice network status.
-                    // Get the network registration info for the voice network, which is the second of the three entries (the first appears to be Wi-Fi and the third appears to be the cell data network).
-                    val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
-
-                    // Get the consider 3G antiquated preference.
-                    val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
-
-                    // Update the voice network security status.
-                    voiceNetworkSecurityStatus = protocolHelper.checkNetwork(networkRegistrationInfo.accessNetworkTechnology, consider3gAntiquated)
-
-                    // Populate the notification.
-                    populateNotification()
+                    // Check to see if realtime monitoring is enabled.  Sometimes the system keeps running the service even when it is supposed to shut down.
+                    if (sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)) {  // Realtime monitoring is enabled.
+                        // Get the network registration info for the voice network, which is the second of the three entries (the first appears to be Wi-Fi and the third appears to be the cell data network).
+                        val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
+
+                        // Get the consider 3G antiquated preference.
+                        val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
+
+                        // Update the voice network security status.
+                        voiceNetworkSecurityStatus = protocolHelper.checkNetwork(networkRegistrationInfo.accessNetworkTechnology, consider3gAntiquated)
+
+                        // Populate the notification.
+                        populateNotification()
+                    } else {  // Realtime monitoring is disabled.
+                        // Cancel the current listener if it exists.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
+                        telephonyManager.listen(phoneStateListener, LISTEN_NONE)
+                    }
                 }
 
                 @Deprecated("Deprecated in Java")
                 override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {  // Update the data network status.
-                    // Get the consider 3G antiquated preference.
-                    val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
-
-                    // Update the data network security status.
-                    dataNetworkSecurityStatus = protocolHelper.checkNetwork(telephonyDisplayInfo.networkType, consider3gAntiquated)
-
-                    // Populate the notification.
-                    populateNotification()
+                    // Check to see if realtime monitoring is enabled.  Sometimes the system keeps running the service even when it is supposed to shut down.
+                    if (sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)) {  // Realtime monitoring is enabled.
+                        // Get the consider 3G antiquated preference.
+                        val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
+
+                        // Update the data network security status.
+                        dataNetworkSecurityStatus = protocolHelper.checkNetwork(telephonyDisplayInfo.networkType, consider3gAntiquated)
+
+                        // Populate the notification.
+                        populateNotification()
+                    } else {  // Realtime monitoring is disabled.
+                        // Cancel the current listener if it exists.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
+                        telephonyManager.listen(phoneStateListener, LISTEN_NONE)
+                    }
                 }
             }
 
             // Check to see if the read phone state permission has been granted.
             if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
-                // Create a register realtime listener work request that fires every hour.
-                // This periodic request will fire shortly after being created (it fires about every hour near the beginning of the hour) and will reregister the listener if it gets garbage collected.
-                val registerRealtimeListenerWorkRequest = PeriodicWorkRequestBuilder<RegisterRealtimeListenerWorker>(1, TimeUnit.HOURS).build()
+                // Create a register realtime listener work request that fires every fifteen minutes.
+                // This periodic request will fire shortly after being created and will reregister the listener if it gets garbage collected.
+                val registerRealtimeListenerWorkRequest = PeriodicWorkRequestBuilder<RegisterRealtimeListenerWorker>(15, TimeUnit.MINUTES).build()
 
                 // Register the realtime listener work request.
                 WorkManager.getInstance(this).enqueueUniquePeriodicWork(getString(R.string.register_listener_work_request), ExistingPeriodicWorkPolicy.REPLACE, registerRealtimeListenerWorkRequest)
@@ -217,10 +235,16 @@ class RealtimeMonitoringService : Service() {
     }
 
     fun populateNotification() {
+        // Get the list of current notifications.
+        val activeNotificationsArray = notificationManager.activeNotifications
+
+        // Check to see if there is a current notification.
+        val noCurrentNotification = activeNotificationsArray.isEmpty()
+
         // Populate the notification according to the security status.
         if ((voiceNetworkSecurityStatus == ProtocolHelper.ANTIQUATED) || (dataNetworkSecurityStatus == ProtocolHelper.ANTIQUATED)) {  // This is an antiquated network.
             // Only update the notification if the network status has changed.
-            if (currentStatus != ANTIQUATED_NETWORK) {
+            if ((currentStatus != ANTIQUATED_NETWORK) || noCurrentNotification) {
                 // Create an antiquated network notification builder.
                 val antiquatedNetworkNotificationBuilder = Notification.Builder(applicationContext, ANTIQUATED_NETWORK)
 
@@ -236,6 +260,9 @@ class RealtimeMonitoringService : Service() {
                 // Set the color.
                 antiquatedNetworkNotificationBuilder.setColor(getColor(R.color.red_notification_icon))
 
+                // Prevent swiping to dismiss the notification.  This no longer works (except on the lock screen) in API >= 34.
+                antiquatedNetworkNotificationBuilder.setOngoing(true)
+
                 // Update the notification.
                 notificationManager.notify(NOTIFICATION_ID, antiquatedNetworkNotificationBuilder.build())
 
@@ -244,7 +271,7 @@ class RealtimeMonitoringService : Service() {
             }
         } else if ((voiceNetworkSecurityStatus == ProtocolHelper.INSECURE) || (dataNetworkSecurityStatus == ProtocolHelper.INSECURE)) {  // This is an insecure network.
             // Only update the notification if the network status has changed.
-            if (currentStatus != INSECURE_NETWORK) {
+            if ((currentStatus != INSECURE_NETWORK) || noCurrentNotification) {
                 // Create an insecure network notification builder.
                 val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK)
 
@@ -260,6 +287,9 @@ class RealtimeMonitoringService : Service() {
                 // Set the color.
                 insecureNetworkNotificationBuilder.setColor(getColor(R.color.yellow_notification_icon))
 
+                // Prevent swiping to dismiss the notification.  This no longer works (except on the lock screen) in API >= 34.
+                insecureNetworkNotificationBuilder.setOngoing(true)
+
                 // Update the notification.
                 notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build())
 
@@ -268,7 +298,7 @@ class RealtimeMonitoringService : Service() {
             }
         } else {  // This is a secure network.
             // Only update the notification if the network status has changed.
-            if (currentStatus != SECURE_NETWORK) {
+            if ((currentStatus != SECURE_NETWORK) || noCurrentNotification) {
                 // Create a secure network notification builder.
                 val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK)
 
@@ -284,6 +314,9 @@ class RealtimeMonitoringService : Service() {
                 // Set the color.
                 secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_icon))
 
+                // Prevent swiping to dismiss the notification.  This no longer works (except on the lock screen) in API >= 34.
+                secureNetworkNotificationBuilder.setOngoing(true)
+
                 // Update the notification.
                 notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build())
 
@@ -292,4 +325,4 @@ class RealtimeMonitoringService : Service() {
             }
         }
     }
-}
\ No newline at end of file
+}