Skip to content

Commit 8b6e018

Browse files
authored
Merge pull request #4320 from vector-im/feature/adm/malformed-group-link
Fixing grouped notification causing malformed url
2 parents 09fbd5f + 55c00a0 commit 8b6e018

File tree

4 files changed

+54
-22
lines changed

4 files changed

+54
-22
lines changed

changelog.d/4267.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixing malformed link pop up when tapping on notifications
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2021 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.core.extensions
18+
19+
import android.net.Uri
20+
21+
const val IGNORED_SCHEMA = "ignored"
22+
23+
fun Uri.isIgnored() = scheme == IGNORED_SCHEMA
24+
25+
fun createIgnoredUri(path: String): Uri = Uri.parse("$IGNORED_SCHEMA://$path")

vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import androidx.core.graphics.drawable.IconCompat
4747
import androidx.fragment.app.Fragment
4848
import im.vector.app.BuildConfig
4949
import im.vector.app.R
50+
import im.vector.app.core.extensions.createIgnoredUri
5051
import im.vector.app.core.resources.StringProvider
5152
import im.vector.app.core.services.CallService
5253
import im.vector.app.core.utils.startNotificationChannelSettingsIntent
@@ -317,7 +318,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
317318
mode = VectorCallActivity.INCOMING_RINGING
318319
).apply {
319320
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
320-
data = Uri.parse("foobar://${call.callId}")
321+
data = createIgnoredUri(call.callId)
321322
}
322323
val contentPendingIntent = PendingIntent.getActivity(context, System.currentTimeMillis().toInt(), contentIntent, 0)
323324

@@ -378,7 +379,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
378379
call = call,
379380
mode = null).apply {
380381
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
381-
data = Uri.parse("foobar://$call.callId")
382+
data = createIgnoredUri(call.callId)
382383
}
383384
val contentPendingIntent = PendingIntent.getActivity(context, System.currentTimeMillis().toInt(), contentIntent, 0)
384385

@@ -584,7 +585,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
584585
// Mark room as read
585586
val markRoomReadIntent = Intent(context, NotificationBroadcastReceiver::class.java)
586587
markRoomReadIntent.action = MARK_ROOM_READ_ACTION
587-
markRoomReadIntent.data = Uri.parse("foobar://${roomInfo.roomId}")
588+
markRoomReadIntent.data = createIgnoredUri(roomInfo.roomId)
588589
markRoomReadIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
589590
val markRoomReadPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), markRoomReadIntent,
590591
PendingIntent.FLAG_UPDATE_CURRENT)
@@ -652,7 +653,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
652653
// offer to type a quick reject button
653654
val rejectIntent = Intent(context, NotificationBroadcastReceiver::class.java)
654655
rejectIntent.action = REJECT_ACTION
655-
rejectIntent.data = Uri.parse("foobar://$roomId&$matrixId")
656+
rejectIntent.data = createIgnoredUri("$roomId&$matrixId")
656657
rejectIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
657658
val rejectIntentPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), rejectIntent,
658659
PendingIntent.FLAG_UPDATE_CURRENT)
@@ -665,7 +666,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
665666
// offer to type a quick accept button
666667
val joinIntent = Intent(context, NotificationBroadcastReceiver::class.java)
667668
joinIntent.action = JOIN_ACTION
668-
joinIntent.data = Uri.parse("foobar://$roomId&$matrixId")
669+
joinIntent.data = createIgnoredUri("$roomId&$matrixId")
669670
joinIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
670671
val joinIntentPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), joinIntent,
671672
PendingIntent.FLAG_UPDATE_CURRENT)
@@ -677,7 +678,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
677678
val contentIntent = HomeActivity.newIntent(context, inviteNotificationRoomId = inviteNotifiableEvent.roomId)
678679
contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
679680
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
680-
contentIntent.data = Uri.parse("foobar://" + inviteNotifiableEvent.eventId)
681+
contentIntent.data = createIgnoredUri(inviteNotifiableEvent.eventId)
681682
setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, 0))
682683

683684
if (inviteNotifiableEvent.noisy) {
@@ -716,7 +717,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
716717
val contentIntent = HomeActivity.newIntent(context)
717718
contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
718719
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
719-
contentIntent.data = Uri.parse("foobar://" + simpleNotifiableEvent.eventId)
720+
contentIntent.data = createIgnoredUri(simpleNotifiableEvent.eventId)
720721
setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, 0))
721722

722723
if (simpleNotifiableEvent.noisy) {
@@ -738,7 +739,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
738739
val roomIntentTap = RoomDetailActivity.newIntent(context, RoomDetailArgs(roomId))
739740
roomIntentTap.action = TAP_TO_VIEW_ACTION
740741
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
741-
roomIntentTap.data = Uri.parse("foobar://openRoom?$roomId")
742+
roomIntentTap.data = createIgnoredUri("openRoom?$roomId")
742743

743744
// Recreate the back stack
744745
return TaskStackBuilder.create(context)
@@ -750,7 +751,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
750751
private fun buildOpenHomePendingIntentForSummary(): PendingIntent {
751752
val intent = HomeActivity.newIntent(context, clearNotification = true)
752753
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
753-
intent.data = Uri.parse("foobar://tapSummary")
754+
intent.data = createIgnoredUri("tapSummary")
754755
return PendingIntent.getActivity(context, Random.nextInt(1000), intent, PendingIntent.FLAG_UPDATE_CURRENT)
755756
}
756757

@@ -766,7 +767,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
766767
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
767768
intent = Intent(context, NotificationBroadcastReceiver::class.java)
768769
intent.action = SMART_REPLY_ACTION
769-
intent.data = Uri.parse("foobar://$roomId")
770+
intent.data = createIgnoredUri(roomId)
770771
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
771772
return PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), intent,
772773
PendingIntent.FLAG_UPDATE_CURRENT)
@@ -781,7 +782,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
781782
782783
// the action must be unique else the parameters are ignored
783784
quickReplyIntent.action = QUICK_LAUNCH_ACTION
784-
quickReplyIntent.data = Uri.parse("foobar://$roomId")
785+
quickReplyIntent.data = createIgnoredUri($roomId")
785786
return PendingIntent.getActivity(context, 0, quickReplyIntent, 0)
786787
}
787788
*/
@@ -835,7 +836,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
835836
private fun getDismissSummaryPendingIntent(): PendingIntent {
836837
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
837838
intent.action = DISMISS_SUMMARY_ACTION
838-
intent.data = Uri.parse("foobar://deleteSummary")
839+
intent.data = createIgnoredUri("deleteSummary")
839840
return PendingIntent.getBroadcast(context.applicationContext,
840841
0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
841842
}

vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import android.content.Context
2020
import android.net.Uri
2121
import im.vector.app.R
2222
import im.vector.app.core.di.ActiveSessionHolder
23+
import im.vector.app.core.extensions.isIgnored
2324
import im.vector.app.core.utils.toast
2425
import im.vector.app.features.navigation.Navigator
2526
import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData
@@ -53,15 +54,19 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
5354
navigationInterceptor: NavigationInterceptor? = null,
5455
buildTask: Boolean = false
5556
): Boolean {
56-
if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) {
57-
return false
58-
}
59-
return tryOrNull {
60-
withContext(Dispatchers.Default) {
61-
val permalinkData = PermalinkParser.parse(deepLink)
62-
handlePermalink(permalinkData, deepLink, context, navigationInterceptor, buildTask)
57+
return when {
58+
deepLink == null -> false
59+
deepLink.isIgnored() -> true
60+
!isPermalinkSupported(context, deepLink.toString()) -> false
61+
else -> {
62+
tryOrNull {
63+
withContext(Dispatchers.Default) {
64+
val permalinkData = PermalinkParser.parse(deepLink)
65+
handlePermalink(permalinkData, deepLink, context, navigationInterceptor, buildTask)
66+
}
67+
} ?: false
6368
}
64-
} ?: false
69+
}
6570
}
6671

6772
private suspend fun handlePermalink(
@@ -115,8 +120,8 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
115120
private fun isPermalinkSupported(context: Context, url: String): Boolean {
116121
return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) ||
117122
context.resources.getStringArray(R.array.permalink_supported_hosts).any {
118-
url.startsWith(it)
119-
}
123+
url.startsWith(it)
124+
}
120125
}
121126

122127
private suspend fun PermalinkData.RoomLink.getRoomId(): String? {

0 commit comments

Comments
 (0)