Fix problems with the realtime notifications. https://redmine.stoutner.com/issues/764
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / workers / RegisterRealtimeListener.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.workers
21
22 import android.app.ActivityManager
23 import android.content.ComponentName
24 import android.content.Context
25 import android.content.Intent
26 import android.content.ServiceConnection
27 import android.os.IBinder
28
29 import androidx.preference.PreferenceManager
30 import androidx.work.WorkManager
31 import androidx.work.Worker
32 import androidx.work.WorkerParameters
33
34 import com.stoutner.privacycell.R
35 import com.stoutner.privacycell.services.RealtimeMonitoringService
36
37 class RegisterRealtimeListener (appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
38     override fun doWork(): Result {
39         // Get a handle for the shared preferences.
40         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
41
42         // Get the realtime monitoring preference.  Sometimes the shared preferences can't return a value in time, because Android sucks.
43         // So, the default value is set to true, which is the safest value if the shared preferences can't be queried.
44         val realtimeMonitoring = sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)
45
46         // Perform the functions according to the realtime monitoring status.
47         if (realtimeMonitoring) {  // Realtime monitoring is enabled.
48             // Get a handle for the activity manager.
49             val activityManager: ActivityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
50
51             // Get a list of the running service info.  The deprecated `getRunningServices()` now only returns services stared by Privacy Cell, but that is all we want to know anyway.
52             val runningServiceInfoList: List<ActivityManager.RunningServiceInfo> = activityManager.getRunningServices(1)
53
54             // Check to see if the service is currently running.
55             if (runningServiceInfoList.isEmpty()) {  // The service is currently stopped.
56                 // Start the service.
57                 applicationContext.startService(Intent(applicationContext, RealtimeMonitoringService::class.java))
58             } else {  // The service is currently running.
59                 // Create a service connection.
60                 val serviceConnection = object : ServiceConnection {
61                     override fun onServiceConnected(componentName: ComponentName, serviceIBinder: IBinder) {
62                         // Get a handle for the realtime monitoring service binder.
63                         val realtimeMonitoringServiceBinder = serviceIBinder as RealtimeMonitoringService.ServiceBinder
64
65                         // Get a handle for the realtime monitoring service.
66                         val realtimeMonitoringService = realtimeMonitoringServiceBinder.getService()
67
68                         // Register the telephony manager listener.
69                         realtimeMonitoringService.registerTelephonyManagerListener()
70
71                         // Unbind the service.
72                         applicationContext.unbindService(this)
73                     }
74
75                     override fun onServiceDisconnected(componentName: ComponentName) {
76                         // Do nothing.
77                     }
78                 }
79
80                 // Bind to the realtime monitoring service.
81                 applicationContext.bindService(Intent(applicationContext, RealtimeMonitoringService::class.java), serviceConnection, 0)
82             }
83         } else {  // Realtime monitoring is disabled.
84             // Cancel the realtime listener work request.
85             WorkManager.getInstance(applicationContext).cancelUniqueWork(applicationContext.getString(R.string.register_listener_work_request))
86         }
87
88         // Return a success.
89         return Result.success()
90     }
91 }