Address API23 notification issues and update when conversation content changes.

fork-5.53.8
Cody Henthorne 2021-05-04 20:31:29 -04:00 zatwierdzone przez GitHub
rodzic efc3e7b25d
commit 29a0b86411
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
8 zmienionych plików z 78 dodań i 51 usunięć

Wyświetl plik

@ -48,6 +48,7 @@ class MessageNotifierV2(context: Application) : MessageNotifier {
@Volatile private var lastScheduledReminder: Long = 0
@Volatile private var previousLockedStatus: Boolean = KeyCachingService.isLocked(context)
@Volatile private var previousPrivacyPreference: NotificationPrivacyPreference = TextSecurePreferences.getNotificationPrivacy(context)
@Volatile private var previousState: NotificationStateV2 = NotificationStateV2.EMPTY
private val threadReminders: MutableMap<Long, Reminder> = ConcurrentHashMap()
private val stickyThreads: MutableMap<Long, StickyThread> = mutableMapOf()
@ -167,9 +168,11 @@ class MessageNotifierV2(context: Application) : MessageNotifier {
defaultBubbleState = defaultBubbleState,
lastAudibleNotification = lastAudibleNotification,
notificationConfigurationChanged = notificationConfigurationChanged,
alertOverrides = alertOverrides
alertOverrides = alertOverrides,
previousState = previousState
)
previousState = state
lastAudibleNotification = System.currentTimeMillis()
updateReminderTimestamps(context, alertOverrides, threadsThatAlerted)
@ -281,7 +284,7 @@ private fun StatusBarNotification.isMessageNotification(): Boolean {
}
private fun NotificationManager.getDisplayedNotificationIds(): Result<Set<Int>> {
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 24) {
return Result.failure(UnsupportedOperationException("SDK level too low"))
}
@ -294,7 +297,7 @@ private fun NotificationManager.getDisplayedNotificationIds(): Result<Set<Int>>
}
private fun NotificationManager.cancelOrphanedNotifications(context: Context, state: NotificationStateV2, stickyNotifications: Set<Int>) {
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 24) {
return
}

Wyświetl plik

@ -68,7 +68,7 @@ sealed class NotificationBuilder(protected val context: Context) {
abstract fun addMarkAsReadActionActual(state: NotificationStateV2)
abstract fun setPriority(priority: Int)
abstract fun setAlarms(recipient: Recipient?)
abstract fun setTicker(ticker: CharSequence)
abstract fun setTicker(ticker: CharSequence?)
abstract fun addTurnOffJoinedNotificationsAction(pendingIntent: PendingIntent)
abstract fun setAutoCancel(autoCancel: Boolean)
abstract fun build(): Notification
@ -100,8 +100,8 @@ sealed class NotificationBuilder(protected val context: Context) {
}
}
fun setWhen(notificationItem: NotificationItemV2) {
if (notificationItem.timestamp != 0L) {
fun setWhen(notificationItem: NotificationItemV2?) {
if (notificationItem != null && notificationItem.timestamp != 0L) {
setWhen(notificationItem.timestamp)
}
}
@ -136,12 +136,12 @@ sealed class NotificationBuilder(protected val context: Context) {
}
}
fun setSummaryContentText(recipient: Recipient) {
if (privacy.isDisplayContact) {
fun setSummaryContentText(recipient: Recipient?) {
if (privacy.isDisplayContact && recipient != null) {
setContentText(context.getString(R.string.MessageNotifier_most_recent_from_s, recipient.getDisplayName(context)))
}
recipient.notificationChannel?.let { channel -> setChannelId(channel) }
recipient?.notificationChannel?.let { channel -> setChannelId(channel) }
}
fun setLights() {
@ -244,8 +244,8 @@ sealed class NotificationBuilder(protected val context: Context) {
val self: PersonCompat = PersonCompat.Builder()
.setBot(false)
.setName(Recipient.self().getDisplayName(context))
.setIcon(Recipient.self().getContactDrawable(context).toLargeBitmap(context).toIconCompat())
.setName(if (includeShortcut) Recipient.self().getDisplayName(context) else context.getString(R.string.SingleRecipientNotificationBuilder_you))
.setIcon(if (includeShortcut) Recipient.self().getContactDrawable(context).toLargeBitmap(context).toIconCompat() else null)
.build()
val messagingStyle: NotificationCompat.MessagingStyle = NotificationCompat.MessagingStyle(self)
@ -332,7 +332,7 @@ sealed class NotificationBuilder(protected val context: Context) {
}
override fun setGroup(group: String) {
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 24) {
return
}
@ -340,7 +340,7 @@ sealed class NotificationBuilder(protected val context: Context) {
}
override fun setGroupAlertBehavior(behavior: Int) {
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 24) {
return
}
@ -375,7 +375,7 @@ sealed class NotificationBuilder(protected val context: Context) {
builder.setContentText(contentText)
}
override fun setTicker(ticker: CharSequence) {
override fun setTicker(ticker: CharSequence?) {
builder.setTicker(ticker)
}
@ -489,8 +489,8 @@ sealed class NotificationBuilder(protected val context: Context) {
override fun addMessagesActual(conversation: NotificationConversation, includeShortcut: Boolean) {
val self: Person = Person.Builder()
.setBot(false)
.setName(Recipient.self().getDisplayName(context))
.setIcon(Recipient.self().getContactDrawable(context).toLargeBitmap(context).toIcon())
.setName(if (includeShortcut) Recipient.self().getDisplayName(context) else context.getString(R.string.SingleRecipientNotificationBuilder_you))
.setIcon(if (includeShortcut) Recipient.self().getContactDrawable(context).toLargeBitmap(context).toIcon() else null)
.build()
val messagingStyle: Notification.MessagingStyle = Notification.MessagingStyle(self)
@ -598,7 +598,7 @@ sealed class NotificationBuilder(protected val context: Context) {
builder.setContentText(contentText)
}
override fun setTicker(ticker: CharSequence) {
override fun setTicker(ticker: CharSequence?) {
builder.setTicker(ticker)
}

Wyświetl plik

@ -88,14 +88,10 @@ data class NotificationConversation(
}
fun getConversationTitle(context: Context): CharSequence? {
if (isGroup) {
return if (TextSecurePreferences.getNotificationPrivacy(context).isDisplayContact) {
recipient.getDisplayName(context)
} else {
context.getString(R.string.SingleRecipientNotificationBuilder_signal)
}
if (TextSecurePreferences.getNotificationPrivacy(context).isDisplayContact) {
return if (isGroup) recipient.getDisplayName(context) else null
}
return null
return context.getString(R.string.SingleRecipientNotificationBuilder_signal)
}
fun getWhen(): Long {
@ -114,6 +110,14 @@ data class NotificationConversation(
}
}
fun hasSameContent(other: NotificationConversation?): Boolean {
if (other == null) {
return false
}
return messageCount == other.messageCount && notificationItems.zip(other.notificationItems).all { (item, otherItem) -> item.hasSameContent(otherItem) }
}
fun getPendingIntent(context: Context): PendingIntent {
val intent: Intent = ConversationIntents.createBuilder(context, recipient.id, threadId)
.withStartingPosition(mostRecentNotification.getStartingPosition(context))

Wyświetl plik

@ -1,10 +1,12 @@
package org.thoughtcrime.securesms.notifications.v2
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.Transformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
@ -17,6 +19,7 @@ import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.notifications.NotificationIds
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.BitmapUtil
import org.thoughtcrime.securesms.util.BlurTransformation
@ -84,3 +87,13 @@ fun Intent.makeUniqueToPreventMerging(): Intent {
fun Recipient.getFallback(context: Context): FallbackContactPhoto {
return GeneratedContactPhoto(getDisplayName(context), R.drawable.ic_profile_outline_40)
}
fun NotificationManager.isDisplayingSummaryNotification(): Boolean {
if (Build.VERSION.SDK_INT > 23) {
try {
return activeNotifications.any { notification -> notification.id == NotificationIds.MESSAGE_SUMMARY }
} catch (e: Throwable) {
}
}
return false
}

Wyświetl plik

@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.notifications.v2
import android.annotation.TargetApi
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
@ -46,15 +45,16 @@ object NotificationFactory {
defaultBubbleState: BubbleUtil.BubbleState,
lastAudibleNotification: Long,
notificationConfigurationChanged: Boolean,
alertOverrides: Set<Long>
alertOverrides: Set<Long>,
previousState: NotificationStateV2
): Set<Long> {
if (state.isEmpty) {
Log.d(TAG, "State is empty, bailing")
return emptySet()
}
val nonVisibleThreadCount = state.conversations.count { it.threadId != visibleThreadId }
return if (Build.VERSION.SDK_INT < 23) {
val nonVisibleThreadCount: Int = state.conversations.count { it.threadId != visibleThreadId }
return if (Build.VERSION.SDK_INT < 24) {
notify19(
context = context,
state = state,
@ -66,7 +66,7 @@ object NotificationFactory {
nonVisibleThreadCount = nonVisibleThreadCount
)
} else {
notify23(
notify24(
context = context,
state = state,
visibleThreadId = visibleThreadId,
@ -75,7 +75,8 @@ object NotificationFactory {
lastAudibleNotification = lastAudibleNotification,
notificationConfigurationChanged = notificationConfigurationChanged,
alertOverrides = alertOverrides,
nonVisibleThreadCount = nonVisibleThreadCount
nonVisibleThreadCount = nonVisibleThreadCount,
previousState = previousState
)
}
}
@ -121,8 +122,8 @@ object NotificationFactory {
return threadsThatNewlyAlerted
}
@TargetApi(23)
private fun notify23(
@TargetApi(24)
private fun notify24(
context: Context,
state: NotificationStateV2,
visibleThreadId: Long,
@ -131,7 +132,8 @@ object NotificationFactory {
lastAudibleNotification: Long,
notificationConfigurationChanged: Boolean,
alertOverrides: Set<Long>,
nonVisibleThreadCount: Int
nonVisibleThreadCount: Int,
previousState: NotificationStateV2
): Set<Long> {
val threadsThatNewlyAlerted: MutableSet<Long> = mutableSetOf()
@ -139,7 +141,7 @@ object NotificationFactory {
if (conversation.threadId == visibleThreadId && conversation.hasNewNotifications()) {
Log.internal().i(TAG, "Thread is visible, notifying in thread. notificationId: ${conversation.notificationId}")
notifyInThread(context, conversation.recipient, lastAudibleNotification)
} else if (notificationConfigurationChanged || conversation.hasNewNotifications() || alertOverrides.contains(conversation.threadId)) {
} else if (notificationConfigurationChanged || conversation.hasNewNotifications() || alertOverrides.contains(conversation.threadId) || !conversation.hasSameContent(previousState.getConversation(conversation.threadId))) {
if (conversation.hasNewNotifications()) {
threadsThatNewlyAlerted += conversation.threadId
}
@ -206,7 +208,7 @@ object NotificationFactory {
builder.addTurnOffJoinedNotificationsAction(conversation.getTurnOffJoinedNotificationsIntent(context))
}
val notificationId: Int = if (Build.VERSION.SDK_INT < 23) NotificationIds.MESSAGE_SUMMARY else conversation.notificationId
val notificationId: Int = if (Build.VERSION.SDK_INT < 24) NotificationIds.MESSAGE_SUMMARY else conversation.notificationId
NotificationManagerCompat.from(context).safelyNotify(context, conversation.recipient, notificationId, builder.build())
}
@ -240,7 +242,7 @@ object NotificationFactory {
setPriority(TextSecurePreferences.getNotificationPriority(context))
setLights()
setAlarms(state.mostRecentSender)
setTicker(state.mostRecentNotification.getStyledPrimaryText(context, true))
setTicker(state.mostRecentNotification?.getStyledPrimaryText(context, true))
}
Log.d(TAG, "showing summary notification")
@ -313,16 +315,6 @@ object NotificationFactory {
NotificationManagerCompat.from(context).safelyNotify(context, recipient, threadId.toInt(), builder.build())
}
private fun NotificationManager.isDisplayingSummaryNotification(): Boolean {
if (Build.VERSION.SDK_INT >= 23) {
try {
return activeNotifications.any { notification -> notification.id == NotificationIds.MESSAGE_SUMMARY }
} catch (e: Throwable) {
}
}
return false
}
private fun NotificationManagerCompat.safelyNotify(context: Context, threadRecipient: Recipient?, notificationId: Int, notification: Notification) {
try {
notify(notificationId, notification)

Wyświetl plik

@ -90,7 +90,7 @@ sealed class NotificationItemV2(val threadRecipient: Recipient, protected val re
return if (TextSecurePreferences.getNotificationPrivacy(context).isDisplayContact) {
individualRecipient.getDisplayName(context)
} else {
""
context.getString(R.string.SingleRecipientNotificationBuilder_signal)
}
}
@ -133,6 +133,16 @@ sealed class NotificationItemV2(val threadRecipient: Recipient, protected val re
}
}
fun hasSameContent(other: NotificationItemV2): Boolean {
return timestamp == other.timestamp &&
id == other.id &&
isMms == other.isMms &&
individualRecipient == other.individualRecipient &&
individualRecipient.hasSameContent(other.individualRecipient) &&
slideDeck?.thumbnailSlide?.isInProgress == other.slideDeck?.thumbnailSlide?.isInProgress &&
record.isRemoteDelete == other.record.isRemoteDelete
}
private fun CharSequence?.trimToDisplayLength(): CharSequence {
val text: CharSequence = this ?: ""
return if (text.length <= AbstractNotificationBuilder.MAX_DISPLAY_LENGTH) {

Wyświetl plik

@ -33,16 +33,20 @@ data class NotificationStateV2(val conversations: List<NotificationConversation>
.toSet()
}
val mostRecentNotification: NotificationItemV2
get() = notificationItems.last()
val mostRecentNotification: NotificationItemV2?
get() = notificationItems.lastOrNull()
val mostRecentSender: Recipient
get() = mostRecentNotification.individualRecipient
val mostRecentSender: Recipient?
get() = mostRecentNotification?.individualRecipient
fun getNonVisibleConversation(visibleThreadId: Long): List<NotificationConversation> {
return conversations.filterNot { it.threadId == visibleThreadId }
}
fun getConversation(threadId: Long): NotificationConversation? {
return conversations.firstOrNull { it.threadId == threadId }
}
fun getDeleteIntent(context: Context): PendingIntent? {
val ids = LongArray(messageCount)
val mms = BooleanArray(ids.size)

Wyświetl plik

@ -1751,6 +1751,7 @@
<string name="SingleRecipientNotificationBuilder_signal">Signal</string>
<string name="SingleRecipientNotificationBuilder_new_message">New message</string>
<string name="SingleRecipientNotificationBuilder_message_request">Message request</string>
<string name="SingleRecipientNotificationBuilder_you">You</string>
<!-- ThumbnailView -->
<string name="ThumbnailView_Play_video_description">Play video</string>