663c178016e701f2ea4650feb72745cc93b53dad
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / services / RealtimeMonitoringService.kt
1 /*
2  * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
5  *
6  * Privacy Cell is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Cell is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Cell.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacycell.services
21
22 import android.app.Notification
23 import android.app.NotificationChannel
24 import android.app.NotificationChannelGroup
25 import android.app.NotificationManager
26 import android.app.PendingIntent
27 import android.app.Service
28 import android.content.Context
29 import android.content.Intent
30 import android.os.IBinder
31 import android.telephony.PhoneStateListener
32 import android.telephony.TelephonyDisplayInfo
33 import android.telephony.TelephonyManager
34
35 import com.stoutner.privacycell.R
36 import com.stoutner.privacycell.activities.PrivacyCellActivity
37
38 // Define the class constants.
39 const val REALTIME_MONITORING = "realtime_monitoring"
40 const val NOTIFICATION_ID = 1
41
42 class RealtimeMonitoringService : Service() {
43     companion object {
44         // Define the public constants.
45         const val SECURE_NETWORK = "secure_network"
46         const val INSECURE_NETWORK = "insecure_network"
47         const val UNKNOWN_NETWORK = "unknown_network"
48     }
49
50     override fun onBind(intent: Intent?): IBinder? {
51         // Do nothing.
52         return null
53     }
54
55     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
56         // Get a handle for the notification manager.
57         val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
58
59         // Create a notification channel group.
60         notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring)))
61
62         // Prepare the notification channels.
63         val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_DEFAULT)
64         val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_DEFAULT)
65         val unknownNetworkChannel = NotificationChannel(UNKNOWN_NETWORK, getString(R.string.unknown_network_channel), NotificationManager.IMPORTANCE_LOW)
66
67         // Set the notification channel group.
68         secureNetworkChannel.group = REALTIME_MONITORING
69         insecureNetworkChannel.group = REALTIME_MONITORING
70         unknownNetworkChannel.group = REALTIME_MONITORING
71
72         // Disable the notification dots.
73         secureNetworkChannel.setShowBadge(false)
74         insecureNetworkChannel.setShowBadge(false)
75         unknownNetworkChannel.setShowBadge(false)
76
77         // Set the notifications to be public for the secure and insecure networks.
78         secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
79         insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
80
81         // Create the notification channels.
82         notificationManager.createNotificationChannel(secureNetworkChannel)
83         notificationManager.createNotificationChannel(insecureNetworkChannel)
84         notificationManager.createNotificationChannel(unknownNetworkChannel)
85
86         // Create a notification builder.
87         val notificationBuilder = Notification.Builder(this, UNKNOWN_NETWORK)
88
89         // Create an intent to open Privacy Cell.
90         val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java)
91
92         // Create a pending intent from the Privacy Cell intent.
93         val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE)
94
95         // Set the notification to open Privacy Cell.
96         notificationBuilder.setContentIntent(privacyCellPendingIntent)
97
98         // Set the notification text.
99         notificationBuilder.setContentText(getString(R.string.unknown_network))
100
101         // Set the notification icon.
102         notificationBuilder.setSmallIcon(R.drawable.insecure_notification)
103
104         // Set the color.
105         notificationBuilder.setColor(getColor(R.color.red_text))
106
107         // Start the foreground notification.
108         startForeground(NOTIFICATION_ID, notificationBuilder.build())
109
110         // Get a handle for the telephony manager and the context.
111         val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
112
113         // Initialize the current status.
114         var currentStatus = ""
115
116         // Listen for changes to the phone state.
117         telephonyManager.listen(object : PhoneStateListener() {
118             override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
119                 // Populate the notification according to the network type.
120                 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) {  // This is a secure 5G NR SA network.
121                     // Only update the notification if the network status has changed.
122                     if (currentStatus != SECURE_NETWORK) {
123                         // Create a secure network notification builder.
124                         val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK)
125
126                         // Set the notification to open Privacy Cell.
127                         secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
128
129                         // Set the notification text.
130                         secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network))
131
132                         // Set the notification icon.
133                         secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification)
134
135                         // Set the color.
136                         secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_text))
137
138                         // Update the notification.
139                         notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build())
140
141                         // Store the new network status.
142                         currentStatus = SECURE_NETWORK
143                     }
144                 } else {  // This is not a secure 5G NR SA network.
145                     // Only update the notification if the network status has changed.
146                     if (currentStatus !=INSECURE_NETWORK) {
147                         // Create an insecure network notification builder.
148                         val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK)
149
150                         // Set the notification to open Privacy Cell.
151                         insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
152
153                         // Set the notification text.
154                         insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network))
155
156                         // Set the notification icon.
157                         insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification)
158
159                         // Set the color.
160                         insecureNetworkNotificationBuilder.setColor(getColor(R.color.red_text))
161
162                         // Update the notification.
163                         notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build())
164
165                         // Store the new network status.
166                         currentStatus = INSECURE_NETWORK
167                     }
168                 }
169             }
170         }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
171
172         // Return a sticky service.
173         return START_STICKY
174     }
175 }