diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f6a3225cb8..d5f08e0795 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -139,6 +139,12 @@ + + diff --git a/app/src/main/res/xml/shortcuts.xml b/app/src/main/res/xml/shortcuts.xml new file mode 100644 index 0000000000..d4995157d8 --- /dev/null +++ b/app/src/main/res/xml/shortcuts.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt index f898e4a9ed..7b08958cd1 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt @@ -42,6 +42,12 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import timber.log.Timber +/** + * Category shared with the `` in `app/src/main/res/xml/shortcuts.xml`. The system only offers a shortcut + * in the Direct Share row of the share sheet when the two match, so the literal has to be kept in step with that file. + */ +private const val SHARE_TARGET_CATEGORY = "io.element.android.category.SHARE_TARGET" + @SingleIn(AppScope::class) @ContributesBinding(AppScope::class) class DefaultNotificationConversationService( @@ -86,7 +92,8 @@ class DefaultNotificationConversationService( } val categories = setOfNotNull( - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION else null + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION else null, + SHARE_TARGET_CATEGORY, ) val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationServiceTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationServiceTest.kt index 41e601c50d..cb5fad7509 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationServiceTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationServiceTest.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.push.impl.notifications.conversations import android.content.Context import android.content.Intent +import android.content.pm.ShortcutInfo import android.os.Build import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat @@ -52,6 +53,27 @@ class DefaultNotificationConversationServiceTest : RobolectricTest() { assertThat(shortcuts).isNotEmpty() } + @Test + fun `the shortcut is offered to the share sheet as a conversation`() = runTest { + val context = InstrumentationRegistry.getInstrumentation().context + val service = createService(context) + + service.onSendMessage( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + roomName = "Room title", + roomIsDirect = false, + roomAvatarUrl = null, + ) + + val shortcut = ShortcutManagerCompat.getDynamicShortcuts(context).single() + assertThat(shortcut.categories).containsAtLeast( + ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, + // Matches the category in app/src/main/res/xml/shortcuts.xml + "io.element.android.category.SHARE_TARGET", + ) + } + @Test fun `onLeftRoom removes a shortcut`() = runTest { val context = InstrumentationRegistry.getInstrumentation().context