dc5b49483425cc043c238790452d5d48c4899259
[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     }
48
49     override fun onBind(intent: Intent?): IBinder? {
50         // Do nothing.
51         return null
52     }
53
54     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
55         // Get a handle for the notification manager.
56         val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
57
58         // Create a notification channel group.
59         notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring)))
60
61         // Prepare the notification channels.
62         val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_DEFAULT)
63         val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_DEFAULT)
64
65         // Set the notification channel group.
66         secureNetworkChannel.group = REALTIME_MONITORING
67         insecureNetworkChannel.group = REALTIME_MONITORING
68
69         // Disable the notification dots.
70         secureNetworkChannel.setShowBadge(false)
71         insecureNetworkChannel.setShowBadge(false)
72
73         // Set the notifications to be public.
74         secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
75         insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
76
77         // Create the notification channels.
78         notificationManager.createNotificationChannel(secureNetworkChannel)
79         notificationManager.createNotificationChannel(insecureNetworkChannel)
80
81         // Create a notification builder.
82         val notificationBuilder = Notification.Builder(this, INSECURE_NETWORK)
83
84         // Create an intent to open Privacy Cell.
85         val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java)
86
87         // Create a pending intent from the Privacy Cell intent.
88         val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE)
89
90         // Set the notification to open Privacy Cell.
91         notificationBuilder.setContentIntent(privacyCellPendingIntent)
92
93         // Set the notification text.
94         notificationBuilder.setContentText(getString(R.string.unknown_network))
95
96         // Set the notification icon.
97         notificationBuilder.setSmallIcon(R.drawable.insecure_notification)
98
99         // Set the color.
100         notificationBuilder.setColor(getColor(R.color.red_text))
101
102         // Start the foreground notification.
103         startForeground(NOTIFICATION_ID, notificationBuilder.build())
104
105         // Get a handle for the telephony manager and the context.
106         val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
107
108         // Initialize the current status.
109         var currentStatus = ""
110
111         // Listen for changes to the phone state.
112         telephonyManager.listen(object : PhoneStateListener() {
113             override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
114                 // Populate the notification according to the network type.
115                 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) {  // This is a secure 5G NR SA network.
116                     // Only update the notification if the network status has changed.
117                     if (currentStatus != SECURE_NETWORK) {
118                         // Create a secure network notification builder.
119                         val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK)
120
121                         // Set the notification to open Privacy Cell.
122                         secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
123
124                         // Set the notification text.
125                         secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network))
126
127                         // Set the notification icon.
128                         secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification)
129
130                         // Set the color.
131                         secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_text))
132
133                         // Update the notification.
134                         notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build())
135
136                         // Store the new network status.
137                         currentStatus = SECURE_NETWORK
138                     }
139                 } else {  // This is not a secure 5G NR SA network.
140                     // Only update the notification if the network status has changed.
141                     if (currentStatus !=INSECURE_NETWORK) {
142                         // Create an insecure network notification builder.
143                         val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK)
144
145                         // Set the notification to open Privacy Cell.
146                         insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
147
148                         // Set the notification text.
149                         insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network))
150
151                         // Set the notification icon.
152                         insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification)
153
154                         // Set the color.
155                         insecureNetworkNotificationBuilder.setColor(getColor(R.color.red_text))
156
157                         // Update the notification.
158                         notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build())
159
160                         // Store the new network status.
161                         currentStatus = INSECURE_NETWORK
162                     }
163                 }
164             }
165         }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
166
167         // Return a sticky service.
168         return START_STICKY
169     }
170 }