Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.ichi2.anki.common.time.TimeManager
import com.ichi2.anki.reviewreminders.ReviewReminder
import com.ichi2.anki.reviewreminders.ReviewRemindersDatabase
import com.ichi2.anki.showThemedToast
import kotlinx.serialization.SerializationException
import timber.log.Timber
import java.util.Calendar
import kotlin.time.Duration
Expand Down Expand Up @@ -223,7 +224,25 @@ class AlarmManagerService : BroadcastReceiver() {
private fun scheduleAllEnabledReviewReminderNotifications(context: Context) {
Timber.d("scheduleAllEnabledReviewReminderNotifications")
val allReviewRemindersAsMap =
ReviewRemindersDatabase.getAllAppWideReminders() + ReviewRemindersDatabase.getAllDeckSpecificReminders()
try {
ReviewRemindersDatabase.getAllAppWideReminders() + ReviewRemindersDatabase.getAllDeckSpecificReminders()
} catch (e: SerializationException) {
Timber.w(e, "Failed to read review reminders from storage")
try {
showThemedToast(context, context.getString(R.string.boot_service_review_reminders_corrupt), false)
} catch (toastException: Exception) {
Timber.w(toastException, "Failed to show review reminders corrupt toast")
}
return
} catch (e: IllegalArgumentException) {
Timber.w(e, "Failed to read review reminders from storage")
try {
showThemedToast(context, context.getString(R.string.boot_service_review_reminders_corrupt), false)
} catch (toastException: Exception) {
Timber.w(toastException, "Failed to show review reminders corrupt toast")
}
return
}
val enabledReviewReminders = allReviewRemindersAsMap.values.filter { it.enabled }
for (reviewReminder in enabledReviewReminders) {
scheduleReviewReminderNotification(context, reviewReminder)
Expand Down
1 change: 1 addition & 0 deletions AnkiDroid/src/main/res/values/03-dialogs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
<!-- Boot Service -->
<string name="boot_service_failed_to_schedule_notifications">Failed to schedule reminders</string>
<string name="boot_service_too_many_notifications">Too many reminders scheduled. Some will not appear</string>
<string name="boot_service_review_reminders_corrupt">Review reminder data could not be read. Some reminders may not appear</string>

<!-- Locale Selection Dialog -->
<string name="locale_selection_dialog_title_new">Set Language</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.ichi2.anki.reviewreminders.ReviewReminder
import com.ichi2.anki.reviewreminders.ReviewReminderId
import com.ichi2.anki.reviewreminders.ReviewReminderTime
import com.ichi2.anki.reviewreminders.ReviewRemindersDatabase
import com.ichi2.anki.showThemedToast
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
Expand Down Expand Up @@ -159,6 +160,21 @@ class AlarmManagerServiceTest : RobolectricTest() {
verify(exactly = 3) { alarmManager.setWindow(AlarmManager.RTC_WAKEUP, any(), 10.minutes.inWholeMilliseconds, any()) }
}

@Test
fun `scheduleAllNotifications does not crash and shows toast when review reminder data is corrupt`() {
mockkStatic("com.ichi2.anki.UIUtilsKt")
every { showThemedToast(any(), any<String>(), any()) } returns Unit

ReviewRemindersDatabase.remindersSharedPrefs.edit {
putString(ReviewRemindersDatabase.APP_WIDE_KEY, "not valid json at all")
}

AlarmManagerService.scheduleAllNotifications(context)

verify(exactly = 0) { alarmManager.setWindow(any(), any(), any(), any()) }
verify(exactly = 1) { showThemedToast(any(), any<String>(), false) }
}

@Test
fun `onReceive schedules snoozed notification and cancels clicked notification`() {
val extras = mockk<Bundle>()
Expand Down
Loading