/* * Copyright © 2021 Soren Stoutner . * * This file is part of Privacy Cell . * * Privacy Cell is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Privacy Cell is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Privacy Cell. If not, see . */ package com.stoutner.privacycell.services import android.app.Notification import android.app.NotificationChannel import android.app.NotificationChannelGroup import android.app.NotificationManager import android.app.PendingIntent import android.app.Service import android.content.Context import android.content.Intent import android.os.IBinder import android.telephony.PhoneStateListener import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyManager import com.stoutner.privacycell.R import com.stoutner.privacycell.activities.PrivacyCellActivity // Define the class constants. const val REALTIME_MONITORING = "realtime_monitoring" const val NOTIFICATION_ID = 1 class RealtimeMonitoringService : Service() { companion object { // Define the public constants. const val SECURE_NETWORK = "secure_network" const val INSECURE_NETWORK = "insecure_network" } override fun onBind(intent: Intent?): IBinder? { // Do nothing. return null } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { // Get a handle for the notification manager. val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Create a notification channel group. notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring))) // Prepare the notification channels. val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_DEFAULT) val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_DEFAULT) // Set the notification channel group. secureNetworkChannel.group = REALTIME_MONITORING insecureNetworkChannel.group = REALTIME_MONITORING // Disable the notification dots. secureNetworkChannel.setShowBadge(false) insecureNetworkChannel.setShowBadge(false) // Set the notifications to be public. secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC // Create the notification channels. notificationManager.createNotificationChannel(secureNetworkChannel) notificationManager.createNotificationChannel(insecureNetworkChannel) // Create a notification builder. val notificationBuilder = Notification.Builder(this, INSECURE_NETWORK) // Create an intent to open Privacy Cell. val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java) // Create a pending intent from the Privacy Cell intent. val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE) // Set the notification to open Privacy Cell. notificationBuilder.setContentIntent(privacyCellPendingIntent) // Set the notification text. notificationBuilder.setContentText(getString(R.string.unknown_network)) // Set the notification icon. notificationBuilder.setSmallIcon(R.drawable.insecure_notification) // Set the color. notificationBuilder.setColor(getColor(R.color.red_text)) // Start the foreground notification. startForeground(NOTIFICATION_ID, notificationBuilder.build()) // Get a handle for the telephony manager and the context. val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager // Initialize the current status. var currentStatus = "" // Listen for changes to the phone state. telephonyManager.listen(object : PhoneStateListener() { override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) { // Populate the notification according to the network type. if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) { // This is a secure 5G NR SA network. // Only update the notification if the network status has changed. if (currentStatus != SECURE_NETWORK) { // Create a secure network notification builder. val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK) // Set the notification to open Privacy Cell. secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent) // Set the notification text. secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network)) // Set the notification icon. secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification) // Set the color. secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_text)) // Update the notification. notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build()) // Store the new network status. currentStatus = SECURE_NETWORK } } else { // This is not a secure 5G NR SA network. // Only update the notification if the network status has changed. if (currentStatus !=INSECURE_NETWORK) { // Create an insecure network notification builder. val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK) // Set the notification to open Privacy Cell. insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent) // Set the notification text. insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network)) // Set the notification icon. insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification) // Set the color. insecureNetworkNotificationBuilder.setColor(getColor(R.color.red_text)) // Update the notification. notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build()) // Store the new network status. currentStatus = INSECURE_NETWORK } } } }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) // Return a sticky service. return START_STICKY } }