summaryrefslogtreecommitdiffstats
path: root/android/app/src/main/java/eu/jopek/dingdongmail/MainWorkerService.kt
blob: 4991c3afad4bc422e8f35c0474168bd15df5261f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package eu.jopek.dingdongmail

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ApplicationInfo
import android.content.pm.ServiceInfo
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import android.util.Log
import android.widget.Toast
import eu.jopek.dingdongmail.ui.theme.DingDongMailTheme

fun log(str: String) {
    if (BuildConfig.DEBUG) {
        Log.d("Ding-Dong Mail", str)
    }
}

enum class Actions {
    START,
    STOP
}

class MainWorkerService : Service() {
    private var wakeLock: PowerManager.WakeLock? = null
    private var isServiceStarted = false

    override fun onBind(intent: Intent): IBinder? {
        log("Some component want to bind with the service")
        // We don't provide binding, so return null
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (intent != null) {
            val action = intent.action
            log("using an intent with action $action")
            when (action) {
                Actions.START.name -> startService()
                Actions.STOP.name -> stopService()
                else -> log("This should never happen. No action in the received intent")
            }
        } else {
            log("with a null intent. It has been probably restarted by the system.")
        }
        // by returning this we make sure the service is restarted if the system kills the service
        return START_STICKY
    }

    override fun onCreate() {
        super.onCreate()
        log("The service has been created")
        val notification = createNotification()
        startForeground(ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE, notification)
    }

    override fun onDestroy() {
        super.onDestroy()
        log("The service has been destroyed")
        Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show()
    }

    private fun startService() {
        if (isServiceStarted) return
        log("Starting the foreground service task")
        Toast.makeText(this, "Service starting its task", Toast.LENGTH_SHORT).show()
        isServiceStarted = true

        // we need this lock so our service gets not affected by Doze Mode
        wakeLock =
            (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
                newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DingDongMail::lock").apply {
                    acquire()
                }
            }

        val i = Intent("eu.faircode.email.DISABLE").apply {
            setPackage("eu.faircode.email")
        }
        startService(i)
        val intentFilter = IntentFilter("io.heckel.ntfy.MESSAGE_RECEIVED")
        registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED)
    }

    private val receiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val msg = intent.getStringExtra("message") ?: return
            val (email, _mailbox) = msg.split(":", ignoreCase = false, limit = 2)
            log("email: $email")
            val i = Intent("eu.faircode.email.POLL").apply {
                setPackage("eu.faircode.email")
                putExtra("account", email)
            }
            startService(i)
        }
    }

    private fun stopService() {
        log("Stopping the foreground service")
        Toast.makeText(this, "Service stopping", Toast.LENGTH_SHORT).show()
        val i = Intent("eu.faircode.email.ENABLE").apply {
            setPackage("eu.faircode.email")
        }
        startService(i)
        wakeLock?.let {
            if (it.isHeld) {
                it.release()
            }
        }
        stopSelf()
        unregisterReceiver(receiver)
        isServiceStarted = false
    }

    private fun createNotification(): Notification {
        val notificationChannelId = "DING-DONG MAIL - FOREGROUND SERVICE"

        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channel = NotificationChannel(
            notificationChannelId,
            "Foreground service",
            NotificationManager.IMPORTANCE_MIN
        ).let {
            it.description = "Foreground service"
            it.enableLights(true)
            it.lightColor = Color.RED
            it.enableVibration(true)
            it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
            it
        }
        notificationManager.createNotificationChannel(channel)

        val pendingIntent: PendingIntent =
            Intent(this, MainActivity::class.java).let { notificationIntent ->
                PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
            }

        val builder: Notification.Builder =
            Notification.Builder(
                this,
                notificationChannelId
            )

        return builder
            .setContentTitle("Ding-Dong Mail - Foreground Service")
            .setContentText("This makes Ding-Dong Mail works so good")
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.drawable.notification)
            .setColor(resources.getColor(R.color.notification_bg, theme))
            .setLargeIcon(
                BitmapFactory.decodeResource(
                    applicationContext.resources,
                    R.mipmap.logo
                )
            )
            .build()
    }
}