Be lenient on the Json format for received data in a Push.
This commit is contained in:
		
							parent
							
								
									56e6f512fc
								
							
						
					
					
						commit
						279b9b5d6a
					
				| @ -187,12 +187,12 @@ class VectorMessagingReceiver : MessagingReceiver() { | ||||
|             if (session == null) { | ||||
|                 Timber.tag(loggerTag.value).w("## Can't sync from push, no current session") | ||||
|             } else { | ||||
|                 if (isEventAlreadyKnown(pushData.eventId, pushData.roomId)) { | ||||
|                 if (isEventAlreadyKnown(pushData)) { | ||||
|                     Timber.tag(loggerTag.value).d("Ignoring push, event already known") | ||||
|                 } else { | ||||
|                     // Try to get the Event content faster | ||||
|                     Timber.tag(loggerTag.value).d("Requesting event in fast lane") | ||||
|                     getEventFastLane(session, pushData.roomId, pushData.eventId) | ||||
|                     getEventFastLane(session, pushData) | ||||
| 
 | ||||
|                     Timber.tag(loggerTag.value).d("Requesting background sync") | ||||
|                     session.syncService().requireBackgroundSync() | ||||
| @ -203,12 +203,12 @@ class VectorMessagingReceiver : MessagingReceiver() { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun getEventFastLane(session: Session, roomId: String?, eventId: String?) { | ||||
|         roomId?.takeIf { it.isNotEmpty() } ?: return | ||||
|         eventId?.takeIf { it.isNotEmpty() } ?: return | ||||
|     private fun getEventFastLane(session: Session, pushData: PushData) { | ||||
|         pushData.roomId ?: return | ||||
|         pushData.eventId ?: return | ||||
| 
 | ||||
|         // If the room is currently displayed, we will not show a notification, so no need to get the Event faster | ||||
|         if (notificationDrawerManager.shouldIgnoreMessageEventInRoom(roomId)) { | ||||
|         if (notificationDrawerManager.shouldIgnoreMessageEventInRoom(pushData.roomId)) { | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
| @ -219,7 +219,7 @@ class VectorMessagingReceiver : MessagingReceiver() { | ||||
| 
 | ||||
|         coroutineScope.launch { | ||||
|             Timber.tag(loggerTag.value).d("Fast lane: start request") | ||||
|             val event = tryOrNull { session.eventService().getEvent(roomId, eventId) } ?: return@launch | ||||
|             val event = tryOrNull { session.eventService().getEvent(pushData.roomId, pushData.eventId) } ?: return@launch | ||||
| 
 | ||||
|             val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event, canBeReplaced = true) | ||||
| 
 | ||||
| @ -233,12 +233,12 @@ class VectorMessagingReceiver : MessagingReceiver() { | ||||
| 
 | ||||
|     // check if the event was not yet received | ||||
|     // a previous catchup might have already retrieved the notified event | ||||
|     private fun isEventAlreadyKnown(eventId: String?, roomId: String?): Boolean { | ||||
|         if (null != eventId && null != roomId) { | ||||
|     private fun isEventAlreadyKnown(pushData: PushData): Boolean { | ||||
|         if (pushData.eventId != null && pushData.roomId != null) { | ||||
|             try { | ||||
|                 val session = activeSessionHolder.getSafeActiveSession() ?: return false | ||||
|                 val room = session.getRoom(roomId) ?: return false | ||||
|                 return room.getTimelineEvent(eventId) != null | ||||
|                 val room = session.getRoom(pushData.roomId) ?: return false | ||||
|                 return room.getTimelineEvent(pushData.eventId) != null | ||||
|             } catch (e: Exception) { | ||||
|                 Timber.tag(loggerTag.value).e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined") | ||||
|             } | ||||
|  | ||||
| @ -16,8 +16,15 @@ | ||||
| 
 | ||||
| package im.vector.app.core.pushers.model | ||||
| 
 | ||||
| /** | ||||
|  * Represent parsed data that the app has received from a Push content. | ||||
|  * | ||||
|  * @property eventId The Event ID. If not null, it will not be empty, and will have a valid format. | ||||
|  * @property roomId The Room ID. If not null, it will not be empty, and will have a valid format. | ||||
|  * @property unread Number of unread message. | ||||
|  */ | ||||
| data class PushData( | ||||
|         val eventId: String, | ||||
|         val roomId: String, | ||||
|         val unread: Int, | ||||
|         val eventId: String?, | ||||
|         val roomId: String?, | ||||
|         val unread: Int?, | ||||
| ) | ||||
|  | ||||
| @ -18,6 +18,7 @@ package im.vector.app.core.pushers.model | ||||
| 
 | ||||
| import com.squareup.moshi.Json | ||||
| import com.squareup.moshi.JsonClass | ||||
| import org.matrix.android.sdk.api.MatrixPatterns | ||||
| 
 | ||||
| /** | ||||
|  * In this case, the format is: | ||||
| @ -33,17 +34,13 @@ import com.squareup.moshi.JsonClass | ||||
|  */ | ||||
| @JsonClass(generateAdapter = true) | ||||
| data class PushDataFcm( | ||||
|         @Json(name = "event_id") val eventId: String, | ||||
|         @Json(name = "room_id") val roomId: String, | ||||
|         @Json(name = "unread") var unread: Int, | ||||
|         @Json(name = "event_id") val eventId: String?, | ||||
|         @Json(name = "room_id") val roomId: String?, | ||||
|         @Json(name = "unread") var unread: Int?, | ||||
| ) | ||||
| 
 | ||||
| fun PushDataFcm.toPushData(): PushData? { | ||||
|     if (eventId.isEmpty()) return null | ||||
|     if (roomId.isEmpty()) return null | ||||
|     return PushData( | ||||
|             eventId = eventId, | ||||
|             roomId = roomId, | ||||
|             unread = unread | ||||
|     ) | ||||
| } | ||||
| fun PushDataFcm.toPushData() = PushData( | ||||
|         eventId = eventId?.takeIf { MatrixPatterns.isEventId(it) }, | ||||
|         roomId = roomId?.takeIf { MatrixPatterns.isRoomId(it) }, | ||||
|         unread = unread | ||||
| ) | ||||
|  | ||||
| @ -18,6 +18,7 @@ package im.vector.app.core.pushers.model | ||||
| 
 | ||||
| import com.squareup.moshi.Json | ||||
| import com.squareup.moshi.JsonClass | ||||
| import org.matrix.android.sdk.api.extensions.ensureNotEmpty | ||||
| 
 | ||||
| /** | ||||
|  * In this case, the format is: | ||||
| @ -37,27 +38,23 @@ import com.squareup.moshi.JsonClass | ||||
|  */ | ||||
| @JsonClass(generateAdapter = true) | ||||
| data class PushDataUnifiedPush( | ||||
|         @Json(name = "notification") val notification: PushDataUnifiedPushNotification | ||||
|         @Json(name = "notification") val notification: PushDataUnifiedPushNotification? | ||||
| ) | ||||
| 
 | ||||
| @JsonClass(generateAdapter = true) | ||||
| data class PushDataUnifiedPushNotification( | ||||
|         @Json(name = "event_id") val eventId: String, | ||||
|         @Json(name = "room_id") val roomId: String, | ||||
|         @Json(name = "counts") var counts: PushDataUnifiedPushCounts, | ||||
|         @Json(name = "event_id") val eventId: String?, | ||||
|         @Json(name = "room_id") val roomId: String?, | ||||
|         @Json(name = "counts") var counts: PushDataUnifiedPushCounts?, | ||||
| ) | ||||
| 
 | ||||
| @JsonClass(generateAdapter = true) | ||||
| data class PushDataUnifiedPushCounts( | ||||
|         @Json(name = "unread") val unread: Int | ||||
|         @Json(name = "unread") val unread: Int? | ||||
| ) | ||||
| 
 | ||||
| fun PushDataUnifiedPush.toPushData(): PushData? { | ||||
|     if (notification.eventId.isEmpty()) return null | ||||
|     if (notification.roomId.isEmpty()) return null | ||||
|     return PushData( | ||||
|             eventId = notification.eventId, | ||||
|             roomId = notification.roomId, | ||||
|             unread = notification.counts.unread | ||||
|     ) | ||||
| } | ||||
| fun PushDataUnifiedPush.toPushData() = PushData( | ||||
|         eventId = notification?.eventId?.ensureNotEmpty(), | ||||
|         roomId = notification?.roomId?.ensureNotEmpty(), | ||||
|         unread = notification?.counts?.unread | ||||
| ) | ||||
|  | ||||
| @ -29,12 +29,18 @@ class PushParserTest { | ||||
|                 "{\"event_id\":\"\$anEventId\",\"room_id\":\"!aRoomId\",\"unread\":\"1\",\"prio\":\"high\"}" | ||||
|     } | ||||
| 
 | ||||
|     private val parsedData = PushData( | ||||
|     private val validData = PushData( | ||||
|             eventId = "\$anEventId", | ||||
|             roomId = "!aRoomId", | ||||
|             unread = 1 | ||||
|     ) | ||||
| 
 | ||||
|     private val emptyData = PushData( | ||||
|             eventId = null, | ||||
|             roomId = null, | ||||
|             unread = null | ||||
|     ) | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test edge cases`() { | ||||
|         doAllEdgeTests(true) | ||||
| @ -46,7 +52,7 @@ class PushParserTest { | ||||
|         // Empty string | ||||
|         pushParser.parseData("", firebaseFormat) shouldBe null | ||||
|         // Empty Json | ||||
|         pushParser.parseData("{}", firebaseFormat) shouldBe null | ||||
|         pushParser.parseData("{}", firebaseFormat) shouldBeEqualTo emptyData | ||||
|         // Bad Json | ||||
|         pushParser.parseData("ABC", firebaseFormat) shouldBe null | ||||
|     } | ||||
| @ -55,31 +61,47 @@ class PushParserTest { | ||||
|     fun `test unified push format`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA, false) shouldBeEqualTo parsedData | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA, true) shouldBe null | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA, false) shouldBeEqualTo validData | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA, true) shouldBeEqualTo emptyData | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test firebase push format`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA, true) shouldBeEqualTo parsedData | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA, false) shouldBe null | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA, true) shouldBeEqualTo validData | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA, false) shouldBeEqualTo emptyData | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test empty roomId`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId", ""), true) shouldBe null | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId", ""), false) shouldBe null | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId", ""), true) shouldBeEqualTo validData.copy(roomId = null) | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId", ""), false) shouldBeEqualTo validData.copy(roomId = null) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test invalid roomId`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId", "aRoomId"), true) shouldBeEqualTo validData.copy(roomId = null) | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId", "aRoomId"), false) shouldBeEqualTo validData.copy(roomId = null) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test empty eventId`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", ""), true) shouldBe null | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", ""), false) shouldBe null | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", ""), true) shouldBeEqualTo validData.copy(eventId = null) | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", ""), false) shouldBeEqualTo validData.copy(eventId = null) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun `test invalid eventId`() { | ||||
|         val pushParser = PushParser() | ||||
| 
 | ||||
|         pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", "anEventId"), true) shouldBeEqualTo validData.copy(eventId = null) | ||||
|         pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", "anEventId"), false) shouldBeEqualTo validData.copy(eventId = null) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user