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

Unverified Commit 50ac77e3 authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #5952 from k9mail/fix_notification_channel_races

Avoid race conditions when recreating the messages NotificationChannel
parents 2607b24b f3241622
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -490,11 +490,6 @@ class Account(override val uuid: String) : BaseAccount {
            (oldSyncMode != FolderMode.NONE && syncMode == FolderMode.NONE)
    }

    @Synchronized
    fun incrementMessagesNotificationChannelVersion() {
        messagesNotificationChannelVersion++
    }

    @Synchronized
    fun isSortAscending(sortType: SortType): Boolean {
        return sortAscending.getOrPut(sortType) { sortType.isDefaultAscending }
+12 −6
Original line number Diff line number Diff line
@@ -144,12 +144,16 @@ class NotificationChannelManager(

    fun getChannelIdFor(account: Account, channelType: ChannelType): String {
        return if (channelType == ChannelType.MESSAGES) {
            "messages_channel_${account.uuid}${account.messagesNotificationChannelSuffix}"
            getMessagesChannelId(account, account.messagesNotificationChannelSuffix)
        } else {
            "miscellaneous_channel_${account.uuid}"
        }
    }

    private fun getMessagesChannelId(account: Account, suffix: String): String {
        return "messages_channel_${account.uuid}$suffix"
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun getNotificationConfiguration(account: Account): NotificationConfiguration {
        val channelId = getChannelIdFor(account, ChannelType.MESSAGES)
@@ -175,11 +179,8 @@ class NotificationChannelManager(
            return
        }

        notificationManager.deleteNotificationChannel(oldChannelId)

        account.incrementMessagesNotificationChannelVersion()

        val newChannelId = getChannelIdFor(account, ChannelType.MESSAGES)
        val newChannelVersion = account.messagesNotificationChannelVersion + 1
        val newChannelId = getMessagesChannelId(account, "_$newChannelVersion")
        val channelName = resourceProvider.messagesChannelName
        val importance = oldNotificationChannel.importance

@@ -195,6 +196,11 @@ class NotificationChannelManager(
        Timber.v("Old NotificationChannel: %s", oldNotificationChannel)
        Timber.v("New NotificationChannel: %s", newNotificationChannel)
        notificationManager.createNotificationChannel(newNotificationChannel)

        // To avoid a race condition we first create the new NotificationChannel, point the Account to it,
        // then delete the old one.
        account.messagesNotificationChannelVersion = newChannelVersion
        notificationManager.deleteNotificationChannel(oldChannelId)
    }

    @RequiresApi(Build.VERSION_CODES.O)
+10 −1
Original line number Diff line number Diff line
@@ -101,8 +101,17 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
        val account = getAccount()
        initializeCryptoSettings(account)

        // Don't update the notification preferences when resuming after the user has selected a new notification sound
        // via NotificationSoundPreference. Otherwise we race the background thread and might read data from the old
        // NotificationChannel, overwriting the notification sound with the previous value.
        notificationSoundPreference?.let { notificationSoundPreference ->
            if (notificationSoundPreference.receivedActivityResultJustNow) {
                notificationSoundPreference.receivedActivityResultJustNow = false
            } else {
                maybeUpdateNotificationPreferences(account)
            }
        }
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ constructor(
    ),
    defStyleRes: Int = 0
) : Preference(context, attrs, defStyleAttr, defStyleRes), PreferenceActivityResultListener {
    var receivedActivityResultJustNow = false

    fun setNotificationSound(sound: Uri?) {
        persistRingtone(sound)
@@ -42,6 +43,7 @@ constructor(
        val uri = data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)

        if (callChangeListener(uri?.toString().orEmpty())) {
            receivedActivityResultJustNow = true
            persistRingtone(uri)
        }
    }