Use coroutines in notification manager

pull/1055/head
Alex Baker 4 years ago
parent 0a1a1d870d
commit 9cd9f1ada2

@ -55,7 +55,7 @@ class GeofenceTransitionsIntentService : InjectingJobIntentService() {
}
geofences
.map { toNotification(place, it, arrival) }
.apply(notifier::triggerNotifications)
.let { notifier.triggerNotifications(it) }
} catch (e: Exception) {
Timber.e(e, "Error triggering geofence %s: %s", requestId, e.message)
}

@ -170,18 +170,6 @@ public class AndroidUtilities {
return Thread.currentThread() == Looper.getMainLooper().getThread();
}
/**
* Sleep, ignoring interruption. Before using this method, think carefully about why you are
* ignoring interruptions.
*/
public static void sleepDeep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
// ignore
}
}
/** Capitalize the first character */
public static String capitalize(String string) {
return string.substring(0, 1).toUpperCase() + string.substring(1);

@ -173,7 +173,9 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
})
if (!model.isNew) {
notificationManager.cancel(model.id)
lifecycleScope.launch {
notificationManager.cancel(model.id)
}
if (preferences.getBoolean(R.string.p_linkify_task_edit, false)) {
linkify.linkify(title)
}

@ -28,10 +28,6 @@ class TaskDaoBlocking @Inject constructor(private val dao: TaskDao) {
dao.activeTimers()
}
fun activeNotifications(): List<Task> = runBlocking {
dao.activeNotifications()
}
fun snooze(taskIds: List<Long>, millis: Long) = runBlocking {
dao.snooze(taskIds, millis)
}

@ -3,12 +3,12 @@ package org.tasks
import android.app.PendingIntent
import android.content.Context
import androidx.core.app.NotificationCompat
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDaoBlocking
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.reminders.ReminderService
import com.todoroo.astrid.voice.VoiceOutputAssistant
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.delay
import org.tasks.intents.TaskIntents
import org.tasks.notifications.AudioManager
import org.tasks.notifications.Notification
@ -24,7 +24,7 @@ import kotlin.math.min
class Notifier @Inject constructor(
@param:ApplicationContext private val context: Context,
private val taskDao: TaskDaoBlocking,
private val taskDao: TaskDao,
private val notificationManager: NotificationManager,
private val telephonyManager: TelephonyManager,
private val audioManager: AudioManager,
@ -33,7 +33,7 @@ class Notifier @Inject constructor(
private val colorProvider: ColorProvider = ColorProvider(context, preferences)
fun triggerFilterNotification(filter: Filter) {
suspend fun triggerFilterNotification(filter: Filter) {
val tasks = taskDao.fetchFiltered(filter)
val count = tasks.size
if (count == 0) {
@ -66,12 +66,12 @@ class Notifier @Inject constructor(
notificationManager.notify(filter.listingTitle.hashCode().toLong(), builder, true, false, false)
}
fun triggerNotifications(entries: List<Notification>) {
suspend fun triggerNotifications(entries: List<Notification>) {
val notifications: MutableList<Notification> = ArrayList()
var ringFiveTimes = false
var ringNonstop = false
for (entry in entries.takeLast(NotificationManager.MAX_NOTIFICATIONS)) {
val task = taskDao.fetchBlocking(entry.taskId) ?: continue
val task = taskDao.fetch(entry.taskId) ?: continue
if (entry.type != ReminderService.TYPE_RANDOM) {
ringFiveTimes = ringFiveTimes or task.isNotifyModeFive
ringNonstop = ringNonstop or task.isNotifyModeNonstop
@ -85,7 +85,7 @@ class Notifier @Inject constructor(
return
}
Timber.d("Triggering %s", notifications)
Timber.d("Triggering $notifications")
notificationManager.notifyTasks(notifications, true, ringNonstop, ringFiveTimes)
@ -98,7 +98,7 @@ class Notifier @Inject constructor(
notificationManager.getTaskNotification(it)?.build()?.tickerText?.toString()
}
.forEach {
AndroidUtilities.sleepDeep(2000)
delay(2000)
voiceOutputAssistant.speak(it)
}
}

@ -3,6 +3,7 @@ package org.tasks.notifications
import android.content.Context
import android.content.Intent
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.runBlocking
import org.tasks.injection.InjectingBroadcastReceiver
import timber.log.Timber
import javax.inject.Inject
@ -15,6 +16,8 @@ class NotificationClearedReceiver : InjectingBroadcastReceiver() {
super.onReceive(context, intent)
val notificationId = intent.getLongExtra(NotificationManager.EXTRA_NOTIFICATION_ID, -1L)
Timber.d("cleared $notificationId")
notificationManager.cancel(notificationId)
runBlocking {
notificationManager.cancel(notificationId)
}
}
}

@ -11,18 +11,14 @@ import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDaoBlocking
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.reminders.ReminderService
import dagger.hilt.android.qualifiers.ApplicationContext
import io.reactivex.Completable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.LocationDaoBlocking
import org.tasks.data.LocationDao
import org.tasks.intents.TaskIntents
import org.tasks.preferences.Preferences
import org.tasks.receivers.CompleteTaskReceiver
@ -41,9 +37,9 @@ import kotlin.math.min
class NotificationManager @Inject constructor(
@param:ApplicationContext private val context: Context,
private val preferences: Preferences,
private val notificationDao: NotificationDaoBlocking,
private val taskDao: TaskDaoBlocking,
private val locationDao: LocationDaoBlocking,
private val notificationDao: NotificationDao,
private val taskDao: TaskDao,
private val locationDao: LocationDao,
private val localBroadcastManager: LocalBroadcastManager) {
private val notificationManagerCompat = NotificationManagerCompat.from(context)
private val colorProvider = ColorProvider(context, preferences)
@ -51,35 +47,25 @@ class NotificationManager @Inject constructor(
private val queue = NotificationLimiter(MAX_NOTIFICATIONS)
@SuppressLint("CheckResult")
fun cancel(id: Long) {
suspend fun cancel(id: Long) {
if (id == SUMMARY_NOTIFICATION_ID.toLong()) {
Single.fromCallable { notificationDao.getAll() + id }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { ids: Iterable<Long> -> this.cancel(ids) }
cancel(notificationDao.getAll() + id)
} else {
cancel(listOf(id))
}
}
@SuppressLint("CheckResult")
fun cancel(ids: Iterable<Long>) {
suspend fun cancel(ids: Iterable<Long>) {
for (id in ids) {
notificationManagerCompat.cancel(id.toInt())
queue.remove(id)
}
Completable.fromAction { notificationDao.deleteAll(ids.toList()) }
.subscribeOn(Schedulers.io())
.subscribe {
notifyTasks(
emptyList(),
alert = false,
nonstop = false,
fiveTimes = false)
}
notificationDao.deleteAll(ids.toList())
notifyTasks(emptyList(), alert = false, nonstop = false, fiveTimes = false)
}
fun restoreNotifications(cancelExisting: Boolean) {
suspend fun restoreNotifications(cancelExisting: Boolean) {
val notifications = notificationDao.getAllOrdered()
if (cancelExisting) {
for (notification in notifications) {
@ -109,8 +95,11 @@ class NotificationManager @Inject constructor(
}
}
fun notifyTasks(
newNotifications: List<Notification>, alert: Boolean, nonstop: Boolean, fiveTimes: Boolean) {
suspend fun notifyTasks(
newNotifications: List<Notification>,
alert: Boolean,
nonstop: Boolean,
fiveTimes: Boolean) {
val existingNotifications = notificationDao.getAllOrdered()
notificationDao.insertAll(newNotifications)
val totalCount = existingNotifications.size + newNotifications.size
@ -151,7 +140,7 @@ class NotificationManager @Inject constructor(
localBroadcastManager.broadcastRefresh()
}
private fun createNotifications(
private suspend fun createNotifications(
notifications: List<Notification>,
alert: Boolean,
nonstop: Boolean,
@ -166,7 +155,7 @@ class NotificationManager @Inject constructor(
} else {
builder
.setGroup(
if (useGroupKey) GROUP_KEY else if (AndroidUtilities.atLeastNougat()) java.lang.Long.toString(notification.taskId) else null)
if (useGroupKey) GROUP_KEY else if (AndroidUtilities.atLeastNougat()) notification.taskId.toString() else null)
.setGroupAlertBehavior(
if (alert) NotificationCompat.GROUP_ALERT_CHILDREN else NotificationCompat.GROUP_ALERT_SUMMARY)
notify(notification.taskId, builder, alert, nonstop, fiveTimes)
@ -175,7 +164,7 @@ class NotificationManager @Inject constructor(
}
}
fun notify(
suspend fun notify(
notificationId: Long,
builder: NotificationCompat.Builder,
alert: Boolean,
@ -217,7 +206,7 @@ class NotificationManager @Inject constructor(
}
}
private fun updateSummary(
private suspend fun updateSummary(
notify: Boolean, nonStop: Boolean, fiveTimes: Boolean, newNotifications: List<Notification>) {
val tasks = taskDao.activeNotifications()
val taskCount = tasks.size
@ -275,11 +264,11 @@ class NotificationManager @Inject constructor(
notify(SUMMARY_NOTIFICATION_ID.toLong(), builder, notify, nonStop, fiveTimes)
}
fun getTaskNotification(notification: Notification): NotificationCompat.Builder? {
suspend fun getTaskNotification(notification: Notification): NotificationCompat.Builder? {
val id = notification.taskId
val type = notification.type
val `when` = notification.timestamp
val task = taskDao.fetchBlocking(id)
val task = taskDao.fetch(id)
if (task == null) {
Timber.e("Could not find %s", id)
return null

Loading…
Cancel
Save