Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 957b5324 authored by Michael Enoma's avatar Michael Enoma
Browse files

Fix lock screen notification when there's only one new message

parent e02925cc
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ import androidx.core.app.NotificationManagerCompat
import com.fsck.k9.AccountPreferenceSerializer
import java.util.concurrent.Executors
import org.koin.dsl.module

val coreNotificationModule = module {
    single { NotificationController(get(), get(), get(), get(), get()) }
    single { NotificationManagerCompat.from(get()) }
@@ -32,8 +31,8 @@ val coreNotificationModule = module {
    single { SendFailedNotifications(get(), get(), get()) }
    single { NewMailNotifications(get(), get(), get(), get()) }
    single { NotificationContentCreator(get(), get()) }
    single { WearNotifications(get(), get(), get()) }
    single { DeviceNotifications(get(), get(), get(), get(), get()) }
    single { SingleMessageNotifications(get(), get(), get(), get()) }
    single { MessageSummaryNotifications(get(), get(), get(), get(), get()) }
    single { LockScreenNotification(get(), get()) }
    single {
        PushNotificationManager(
+25 −2
Original line number Diff line number Diff line
@@ -26,7 +26,11 @@ internal open class NewMailNotifications(
                val notificationId = result.notificationId
                cancelNotification(notificationId)
            }
            if (notificationData.isSingleMessageNotification) {
                createSingleMessageNotificationWithLockScreenNotification(account, notificationData)
            } else {
                createSingleMessageNotification(account, result.notificationHolder)
            }
            createSummaryNotification(account, notificationData, silent)
        }
    }
@@ -37,7 +41,9 @@ internal open class NewMailNotifications(
            val result = notificationData.removeNotificationForMessage(messageReference)
            if (result.isUnknownNotification) return
            cancelNotification(result.notificationId)
            if (result.shouldCreateNotification) {
            if (notificationData.isSingleMessageNotification) {
                createSingleMessageNotificationWithLockScreenNotification(account, notificationData)
            } else if (result.shouldCreateNotification) {
                createSingleMessageNotification(account, result.notificationHolder)
            }
            updateSummaryNotification(account, notificationData)
@@ -102,6 +108,23 @@ internal open class NewMailNotifications(
        notificationManager.notify(notificationId, notification)
    }

    // When there's only one notification the "public version" of the notification that might be displayed on a secure
    // lockscreen isn't taken from the summary notification, but from the single "grouped" notification.
    private fun createSingleMessageNotificationWithLockScreenNotification(
        account: Account,
        notificationData: NotificationData
    ) {
        val holder = notificationData.holderForLatestNotification
        val notification = singleMessageNotifications.buildSingleMessageNotificationWithLockScreenNotification(
            account,
            holder,
            notificationData
        )

        val notificationId = holder.notificationId
        notificationManager.notify(notificationId, notification)
    }

    private val notificationManager: NotificationManagerCompat
        get() = notificationHelper.getNotificationManager()
}
+18 −3
Original line number Diff line number Diff line
@@ -8,7 +8,9 @@ import com.fsck.k9.K9
internal open class SingleMessageNotifications(
    notificationHelper: NotificationHelper,
    actionCreator: NotificationActionCreator,
    resourceProvider: NotificationResourceProvider

    resourceProvider: NotificationResourceProvider,
    private val lockScreenNotification: LockScreenNotification,
) : BaseNotifications(notificationHelper, actionCreator, resourceProvider) {

    fun buildSingleMessageNotification(account: Account, holder: NotificationHolder): Notification {
@@ -18,6 +20,20 @@ internal open class SingleMessageNotifications(
            .build()
    }

    fun buildSingleMessageNotificationWithLockScreenNotification(
        account: Account,
        holder: NotificationHolder,
        notificationData: NotificationData
    ): Notification {
        val notificationId = holder.notificationId
        return createSingleMessageNotificationBuilder(account, holder, notificationId)
            .setNotificationSilent()
            .apply {
                lockScreenNotification.configureLockScreenNotification(this, notificationData)
            }
            .build()
    }

    fun createSingleMessageNotificationBuilder(
        account: Account,
        holder: NotificationHolder,
@@ -25,7 +41,6 @@ internal open class SingleMessageNotifications(
    ): NotificationCompat.Builder {
        val content = holder.content
        val builder = createBigTextStyleNotification(account, holder, notificationId)

        val deletePendingIntent = actionCreator.createDismissMessagePendingIntent(
            context, content.messageReference, holder.notificationId
        )
+112 −91
Original line number Diff line number Diff line
@@ -41,15 +41,13 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        val holder = createNotificationHolder(content, notificationIndex)
        addToNotificationContentCreator(message, content)
        whenAddingContentReturn(content, AddNotificationResult.newNotification(holder))
        val wearNotification = createNotification()
        val singleMessageNotification = createNotification()
        val summaryNotification = createNotification()
        addToWearNotifications(holder, wearNotification)
        addToDeviceNotifications(summaryNotification)

        addToSingleMessageNotifications(holder, singleMessageNotification)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, message, 42, silent = false)

        val wearNotificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        verify(notificationManager).notify(wearNotificationId, wearNotification)
        val singleMessageNotificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        verify(notificationManager).notify(singleMessageNotificationId, singleMessageNotification)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager).notify(summaryNotificationId, summaryNotification)
    }
@@ -62,16 +60,14 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        val holder = createNotificationHolder(content, notificationIndex)
        addToNotificationContentCreator(message, content)
        whenAddingContentReturn(content, AddNotificationResult.replaceNotification(holder))
        val wearNotification = createNotification()
        val singleMessageNotification = createNotification()
        val summaryNotification = createNotification()
        addToWearNotifications(holder, wearNotification)
        addToDeviceNotifications(summaryNotification)

        addToSingleMessageNotifications(holder, singleMessageNotification)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, message, 42, silent = false)

        val wearNotificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        verify(notificationManager).notify(wearNotificationId, wearNotification)
        verify(notificationManager).cancel(wearNotificationId)
        val singleMessageNotificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        verify(notificationManager).notify(singleMessageNotificationId, singleMessageNotification)
        verify(notificationManager).cancel(singleMessageNotificationId)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager).notify(summaryNotificationId, summaryNotification)
    }
@@ -90,19 +86,20 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        addToNotificationContentCreator(messageTwo, contentTwo)
        whenAddingContentReturn(contentOne, AddNotificationResult.newNotification(holderOne))
        whenAddingContentReturn(contentTwo, AddNotificationResult.newNotification(holderTwo))
        val wearNotificationOne = createNotification()
        val wearNotificationTwo = createNotification()
        val singleMessageNotificationOne = createNotification()
        val singleMessageNotificationTwo = createNotification()
        val summaryNotification = createNotification()
        addToWearNotifications(holderOne, wearNotificationOne)
        addToWearNotifications(holderTwo, wearNotificationTwo)
        addToDeviceNotifications(summaryNotification)

        addToSingleMessageNotifications(holderOne, singleMessageNotificationOne)
        addToSingleMessageNotifications(holderTwo, singleMessageNotificationTwo)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, messageOne, 42, silent = false)
        newMailNotifications.addNewMailNotification(account, messageTwo, 42, silent = false)
        val wearNotificationIdOne = NotificationIds.getNewMailStackedNotificationId(account, notificationIndexOne)
        verify(notificationManager).notify(wearNotificationIdOne, wearNotificationOne)
        val wearNotificationIdTwo = NotificationIds.getNewMailStackedNotificationId(account, notificationIndexTwo)
        verify(notificationManager).notify(wearNotificationIdTwo, wearNotificationTwo)
        val singleMessageNotificationIdOne =
            NotificationIds.getSingleMessageNotificationId(account, notificationIndexOne)
        verify(notificationManager).notify(singleMessageNotificationIdOne, singleMessageNotificationOne)
        val singleMessageNotificationIdTwo =
            NotificationIds.getSingleMessageNotificationId(account, notificationIndexTwo)
        verify(notificationManager).notify(singleMessageNotificationIdTwo, singleMessageNotificationTwo)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager, times(2)).notify(summaryNotificationId, summaryNotification)
    }
@@ -110,9 +107,7 @@ class NewMailNotificationsTest : K9RobolectricTest() {
    @Test
    fun testRemoveNewMailNotificationWithoutNotificationData() {
        val messageReference = createMessageReference(1)

        newMailNotifications.removeNewMailNotification(account, messageReference)

        verify(notificationManager, never()).cancel(anyInt())
    }

@@ -126,12 +121,10 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        addToNotificationContentCreator(message, content)
        whenAddingContentReturn(content, AddNotificationResult.newNotification(holder))
        val summaryNotification = createNotification()
        addToDeviceNotifications(summaryNotification)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, message, 23, silent = false)
        whenRemovingContentReturn(messageReference, RemoveNotificationResult.unknownNotification())

        newMailNotifications.removeNewMailNotification(account, messageReference)

        verify(notificationManager, never()).cancel(anyInt())
    }

@@ -139,19 +132,17 @@ class NewMailNotificationsTest : K9RobolectricTest() {
    fun testRemoveNewMailNotification() {
        val messageReference = createMessageReference(1)
        val notificationIndex = 0
        val notificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        val notificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        val message = createLocalMessage()
        val content = createNotificationContent()
        val holder = createNotificationHolder(content, notificationIndex)
        addToNotificationContentCreator(message, content)
        whenAddingContentReturn(content, AddNotificationResult.newNotification(holder))
        val summaryNotification = createNotification()
        addToDeviceNotifications(summaryNotification)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, message, 23, silent = false)
        whenRemovingContentReturn(messageReference, RemoveNotificationResult.cancelNotification(notificationId))

        newMailNotifications.removeNewMailNotification(account, messageReference)

        verify(notificationManager).cancel(notificationId)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager, times(2)).notify(summaryNotificationId, summaryNotification)
@@ -161,21 +152,19 @@ class NewMailNotificationsTest : K9RobolectricTest() {
    fun testRemoveNewMailNotificationClearingAllNotifications() {
        val messageReference = createMessageReference(1)
        val notificationIndex = 0
        val notificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        val notificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        val message = createLocalMessage()
        val content = createNotificationContent()
        val holder = createNotificationHolder(content, notificationIndex)
        addToNotificationContentCreator(message, content)
        whenAddingContentReturn(content, AddNotificationResult.newNotification(holder))
        val summaryNotification = createNotification()
        addToDeviceNotifications(summaryNotification)
        addToSummaryNotifications(summaryNotification)
        newMailNotifications.addNewMailNotification(account, message, 23, silent = false)
        whenRemovingContentReturn(messageReference, RemoveNotificationResult.cancelNotification(notificationId))
        whenever(newMailNotifications.notificationData.newMessagesCount).thenReturn(0)
        setActiveNotificationIds()

        newMailNotifications.removeNewMailNotification(account, messageReference)

        verify(notificationManager).cancel(notificationId)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager).cancel(summaryNotificationId)
@@ -185,7 +174,7 @@ class NewMailNotificationsTest : K9RobolectricTest() {
    fun testRemoveNewMailNotificationWithCreateNotification() {
        val messageReference = createMessageReference(1)
        val notificationIndex = 0
        val notificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        val notificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        val message = createLocalMessage()
        val contentOne = createNotificationContent()
        val contentTwo = createNotificationContent()
@@ -194,18 +183,16 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        addToNotificationContentCreator(message, contentOne)
        whenAddingContentReturn(contentOne, AddNotificationResult.newNotification(holderOne))
        val summaryNotification = createNotification()
        addToDeviceNotifications(summaryNotification)
        val wearNotificationOne = createNotification()
        val wearNotificationTwo = createNotification()
        addToWearNotifications(holderOne, wearNotificationOne)
        addToWearNotifications(holderTwo, wearNotificationTwo)
        addToSummaryNotifications(summaryNotification)
        val singleMessageNotificationOne = createNotification()
        val singleMessageNotificationTwo = createNotification()
        addToSingleMessageNotifications(holderOne, singleMessageNotificationOne)
        addToSingleMessageNotifications(holderTwo, singleMessageNotificationTwo)
        newMailNotifications.addNewMailNotification(account, message, 23, silent = false)
        whenRemovingContentReturn(messageReference, RemoveNotificationResult.createNotification(holderTwo))

        newMailNotifications.removeNewMailNotification(account, messageReference)

        verify(notificationManager).cancel(notificationId)
        verify(notificationManager).notify(notificationId, wearNotificationTwo)
        verify(notificationManager).notify(notificationId, singleMessageNotificationTwo)
        val summaryNotificationId = NotificationIds.getNewMailSummaryNotificationId(account)
        verify(notificationManager, times(2)).notify(summaryNotificationId, summaryNotification)
    }
@@ -219,7 +206,7 @@ class NewMailNotificationsTest : K9RobolectricTest() {
    @Test
    fun testClearNewMailNotifications() {
        val notificationIndex = 0
        val notificationId = NotificationIds.getNewMailStackedNotificationId(account, notificationIndex)
        val notificationId = NotificationIds.getSingleMessageNotificationId(account, notificationIndex)
        val message = createLocalMessage()
        val content = createNotificationContent()
        val holder = createNotificationHolder(content, notificationIndex)
@@ -227,12 +214,7 @@ class NewMailNotificationsTest : K9RobolectricTest() {
        setActiveNotificationIds(notificationId)
        whenAddingContentReturn(content, AddNotificationResult.newNotification(holder))
        newMailNotifications.addNewMailNotification(account, message, 3, silent = false)

        newMailNotifications.clearNewMa
    }
}
ilNotifications(account)

        newMailNotifications.clearNewMailNotifications(account)
        verify(notificationManager).cancel(notificationId)
        verify(notificationManager).cancel(NotificationIds.getNewMailSummaryNotificationId(account))
    }
@@ -244,19 +226,17 @@ private fun createAccount(): Account {
    }

    private fun createLocalMessage(): LocalMessage = mock()

    private fun createNotificationContent(): NotificationContent {
        val messageReference = MessageReference("irrelevant", 1, "irrelevant", null)
        return NotificationContent(messageReference, "irrelevant", "irrelevant", "irrelevant", "irrelevant", false)
    }

    private fun createNotificationHolder(content: NotificationContent, index: Int): NotificationHolder {
    val notificationId = NotificationIds.getNewMailStackedNotificationId(account, index)
        val notificationId = NotificationIds.getSingleMessageNotificationId(account, index)
        return NotificationHolder(notificationId, content)
    }

    private fun createNotificationManager(): NotificationManagerCompat = mock()

    private fun createNotificationHelper(notificationManager: NotificationManagerCompat): NotificationHelper {
        return mock {
            on { getNotificationManager() } doReturn notificationManager
@@ -264,17 +244,15 @@ private fun createNotificationHelper(notificationManager: NotificationManagerCom
    }

    private fun createNotificationContentCreator(): NotificationContentCreator = mock()

    private fun addToNotificationContentCreator(message: LocalMessage, content: NotificationContent) {
        stubbing(contentCreator) {
            on { createFromMessage(account, message) } doReturn content
        }
    }

private fun createDeviceNotifications(): DeviceNotifications = mock()

private fun addToDeviceNotifications(notificationToReturn: Notification) {
    stubbing(deviceNotifications) {
    private fun createMessageSummaryNotifications(): MessageSummaryNotifications = mock()
    private fun addToSummaryNotifications(notificationToReturn: Notification) {
        stubbing(messageSummaryNotifications) {
            on {
                buildSummaryNotification(eq(account), eq(newMailNotifications.notificationData), anyBoolean())
            } doReturn notificationToReturn
@@ -282,13 +260,56 @@ private fun addToDeviceNotifications(notificationToReturn: Notification) {
    }

    private fun createNotification(): Notification = mock()

private fun createWearNotifications(): WearNotifications = mock()

    private fun createSingleMessageNotifications(): SingleMessageNotifications = mock()
    private fun createMessageReference(number: Int): MessageReference {
        return MessageReference("account", 1, number.toString(), null)
    }

    private fun addToSingleMessageNotifications(
        notificationHolder: NotificationHolder,
        notificationToReturn: Notification
    ) {
        stubbing(singleMessageNotifications) {
            on { buildSingleMessageNotification(account, notificationHolder) } doReturn notificationToReturn
        }
    }

    private fun whenAddingContentReturn(content: NotificationContent, result: AddNotificationResult) {
        val notificationData = newMailNotifications.notificationData
        val newCount = notificationData.newMessagesCount + 1
        stubbing(notificationData) {
            on { addNotificationContent(content) } doReturn result
            on { newMessagesCount } doReturn newCount
        }
    }

    private fun whenRemovingContentReturn(messageReference: MessageReference, result: RemoveNotificationResult) {
        stubbing(newMailNotifications.notificationData) {
            on { removeNotificationForMessage(messageReference) } doReturn result
        }
    }

    private fun setActiveNotificationIds(vararg notificationIds: Int) {
        stubbing(newMailNotifications.notificationData) {
            on { getActiveNotificationIds() } doReturn notificationIds
        }
    }

    internal class TestNewMailNotifications(
        notificationHelper: NotificationHelper,
        contentCreator: NotificationContentCreator,
        messageSummaryNotifications: MessageSummaryNotifications,
        singleMessageNotifications: SingleMessageNotifications
    ) : NewMailNotifications(
        notificationHelper, contentCreator, messageSummaryNotifications, singleMessageNotifications
    ) {
        val notificationData = mock<NotificationData>()
        override fun createNotificationData(account: Account, unreadMessageCount: Int): NotificationData {
            return notificationData
        }
    }
}

private fun addToWearNotifications(notificationHolder: NotificationHolder, notificationToReturn: Notification) {
    whenever(wearNotifications.buildStackedNotification(account, notificationHolder))
        .thenReturn(notificationToReturn)
+249 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading