Added use of LocusId to conversations notifications & shortcuts

This commit is contained in:
Sylvain Berfini 2021-02-02 11:55:48 +01:00
parent 98fdb56f45
commit a757b097fa
10 changed files with 86 additions and 12 deletions

View file

@ -185,7 +185,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.media:media:1.2.0'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.core:core-ktx:1.5.0-beta01'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
@ -199,8 +199,8 @@ dependencies {
implementation 'androidx.emoji:emoji:1.1.0'
implementation 'androidx.emoji:emoji-bundled:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
if (firebaseEnabled()) {
implementation 'com.google.firebase:firebase-messaging:19.0.1'

View file

@ -52,6 +52,10 @@
android:windowSoftInputMode="adjustResize">
<nav-graph android:value="@navigation/main_nav_graph" />
<intent-filter>
<action android:name="android.intent.action.VIEW_LOCUS" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

View file

@ -211,6 +211,11 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
handleTelOrSipUri(uri)
}
}
Intent.ACTION_VIEW_LOCUS -> {
if (corePreferences.disableChat) return
val locus = Compatibility.extractLocusIdFromIntent(intent)
if (locus != null) handleLocus(locus)
}
else -> {
when {
intent.hasExtra("ContactId") -> {
@ -365,4 +370,17 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink))
}
}
private fun handleLocus(id: String) {
Log.i("[Main Activity] Found chat room locus intent extra: $id")
val split = id.split("~")
if (split.size == 2) {
val localAddress = split[0]
val peerAddress = split[1]
val deepLink = "linphone-android://chat-room/$localAddress/$peerAddress"
findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink))
} else {
Log.e("[Main Activity] Failed to parse locus id: $id")
}
}
}

View file

@ -50,6 +50,7 @@ import org.linphone.activities.main.chat.viewmodels.*
import org.linphone.activities.main.fragments.MasterFragment
import org.linphone.activities.main.viewmodels.DialogViewModel
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.compatibility.Compatibility
import org.linphone.core.*
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatRoomDetailFragmentBinding
@ -118,6 +119,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
Compatibility.setLocusIdInContentCaptureSession(binding.root, chatRoom)
chatRoomAddress = chatRoom.peerAddress.asStringUriOnly()
isSecure = chatRoom.currentParams.encryptionEnabled()
@ -337,7 +340,10 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch {
for (fileToUploadPath in ImageUtils.getFilesPathFromPickerIntent(data, chatSendingViewModel.temporaryFileUploadPath)) {
for (fileToUploadPath in ImageUtils.getFilesPathFromPickerIntent(
data,
chatSendingViewModel.temporaryFileUploadPath
)) {
if (fileToUploadPath != null) {
chatSendingViewModel.addAttachment(fileToUploadPath)
}

View file

@ -22,17 +22,37 @@ package org.linphone.compatibility
import android.annotation.TargetApi
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.view.contentcapture.ContentCaptureContext
import android.view.contentcapture.ContentCaptureSession
import org.linphone.R
import org.linphone.core.ChatRoom
import org.linphone.core.Content
import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
import org.linphone.utils.FileUtils
import org.linphone.utils.LinphoneUtils
@TargetApi(29)
class Api29Compatibility {
companion object {
fun extractLocusIdFromIntent(intent: Intent): String? {
return intent.getStringExtra(Intent.EXTRA_LOCUS_ID)
}
fun setLocusIdInContentCaptureSession(root: View, chatRoom: ChatRoom) {
val session: ContentCaptureSession? = root.contentCaptureSession
if (session != null) {
val localAddress = chatRoom.localAddress.asStringUriOnly()
val peerAddress = chatRoom.peerAddress.asStringUriOnly()
val id = LinphoneUtils.getChatRoomId(localAddress, peerAddress)
session.contentCaptureContext = ContentCaptureContext.forLocusId(id)
}
}
suspend fun addImageToMediaStore(context: Context, content: Content): Boolean {
val filePath = content.filePath
if (filePath == null) {

View file

@ -23,6 +23,7 @@ import android.annotation.TargetApi
import android.content.Context
import android.content.pm.ShortcutManager
import org.linphone.core.ChatRoom
import org.linphone.utils.LinphoneUtils
@TargetApi(30)
class Api30Compatibility {
@ -32,7 +33,8 @@ class Api30Compatibility {
val localAddress = chatRoom.localAddress.asStringUriOnly()
val shortcutManager = context.getSystemService(ShortcutManager::class.java)
val shortcutsToRemoveList = arrayListOf("$localAddress#$peerAddress")
val id = LinphoneUtils.getChatRoomId(localAddress, peerAddress)
val shortcutsToRemoveList = arrayListOf(id)
shortcutManager.removeLongLivedShortcuts(shortcutsToRemoveList)
}
}

View file

@ -21,8 +21,10 @@ package org.linphone.compatibility
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Vibrator
import android.view.View
import android.view.WindowManager
import androidx.core.app.NotificationManagerCompat
import org.linphone.core.ChatRoom
@ -152,6 +154,19 @@ class Compatibility {
}
}
fun extractLocusIdFromIntent(intent: Intent): String? {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return Api29Compatibility.extractLocusIdFromIntent(intent)
}
return null
}
fun setLocusIdInContentCaptureSession(root: View, chatRoom: ChatRoom) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return Api29Compatibility.setLocusIdInContentCaptureSession(root, chatRoom)
}
}
suspend fun addImageToMediaStore(context: Context, content: Content): Boolean {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return Api29Compatibility.addImageToMediaStore(context, content)

View file

@ -33,6 +33,7 @@ import androidx.core.app.NotificationManagerCompat
import androidx.core.app.Person
import androidx.core.app.RemoteInput
import androidx.core.content.ContextCompat
import androidx.core.content.LocusIdCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.navigation.NavDeepLinkBuilder
import org.linphone.LinphoneApplication.Companion.coreContext
@ -528,8 +529,9 @@ class NotificationsManager(private val context: Context) {
.setArguments(args)
.createPendingIntent()
val notification = createMessageNotification(notifiable, pendingIntent, "$localAddress#$peerAddress")
if (notification != null) notify(notifiable.notificationId, notification)
val id = LinphoneUtils.getChatRoomId(localAddress, peerAddress)
val notification = createMessageNotification(notifiable, pendingIntent, id)
notify(notifiable.notificationId, notification)
}
private fun displayIncomingChatNotification(room: ChatRoom, message: ChatMessage) {
@ -621,8 +623,8 @@ class NotificationsManager(private val context: Context) {
private fun createMessageNotification(
notifiable: Notifiable,
pendingIntent: PendingIntent,
shortcutId: String
): Notification? {
id: String
): Notification {
val me = Person.Builder().setName(notifiable.myself).build()
val style = NotificationCompat.MessagingStyle(me)
val largeIcon: Bitmap? = notifiable.messages.last().senderAvatar
@ -676,7 +678,8 @@ class NotificationsManager(private val context: Context) {
.setColor(ContextCompat.getColor(context, R.color.primary_color))
.addAction(getReplyMessageAction(notifiable))
.addAction(getMarkMessageAsReadAction(notifiable))
.setShortcutId(shortcutId)
.setShortcutId(id)
.setLocusId(LocusIdCompat(id))
if (corePreferences.markAsReadUponChatMessageNotificationDismissal) {
Log.i("[Notifications Manager] Chat room will be marked as read when notification will be dismissed")
notificationBuilder

View file

@ -23,7 +23,6 @@ import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.telephony.TelephonyManager.*
import androidx.core.content.ContextCompat.getSystemService
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
@ -136,5 +135,9 @@ class LinphoneUtils {
callLog.status == Call.Status.Aborted ||
callLog.status == Call.Status.EarlyAborted))
}
fun getChatRoomId(localAddress: String, remoteAddress: String): String {
return "$localAddress~$remoteAddress"
}
}
}

View file

@ -27,6 +27,7 @@ import android.content.pm.ShortcutManager
import android.os.Bundle
import androidx.collection.ArraySet
import androidx.core.app.Person
import androidx.core.content.LocusIdCompat
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.graphics.drawable.IconCompat
import org.linphone.LinphoneApplication.Companion.coreContext
@ -201,13 +202,15 @@ class ShortcutsHelper(val context: Context) {
intent.putExtra("RemoteSipUri", peerAddress)
intent.putExtra("LocalSipUri", localAddress)
return ShortcutInfoCompat.Builder(context, "$localAddress#$peerAddress")
val id = LinphoneUtils.getChatRoomId(localAddress, peerAddress)
return ShortcutInfoCompat.Builder(context, id)
.setShortLabel(subject)
.setIcon(icon)
.setPersons(persons)
.setCategories(categories)
.setIntent(intent)
.setLongLived(Version.sdkAboveOrEqual(Version.API30_ANDROID_11))
.setLocusId(LocusIdCompat(id))
.build().toShortcutInfo()
} catch (e: Exception) {
Log.e("[Shortcuts Helper] ShortcutInfo.Builder exception: $e")