From dfdc26a575f38d3c8e97bb4e56c2facf1540149d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 2 Jun 2025 14:03:57 +0200 Subject: [PATCH] Prevent crash for call notification due to empty person name, using all identification fields from vCard (first & last names, organization, job title) --- .../org/linphone/contacts/ContactsManager.kt | 26 ++++++++++++++++--- .../notifications/NotificationsManager.kt | 12 ++++----- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 9ce49e1b1..db271d034 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -683,7 +683,7 @@ fun Friend.getAvatarBitmap(round: Boolean = false): Bitmap? { photo ?: getNativeContactPictureUri()?.toString(), round ) - } catch (numberFormatException: NumberFormatException) { + } catch (_: NumberFormatException) { // Expected for contacts created by Linphone } return null @@ -720,7 +720,7 @@ fun Friend.getNativeContactPictureUri(): Uri? { lookupUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY ) - } catch (numberFormatException: NumberFormatException) { + } catch (_: NumberFormatException) { // Expected for contacts created by Linphone } } @@ -729,7 +729,25 @@ fun Friend.getNativeContactPictureUri(): Uri? { @WorkerThread fun Friend.getPerson(): Person { - val personBuilder = Person.Builder().setName(name) + val personBuilder = Person.Builder() + val personName = if (name.orEmpty().isNotEmpty()) { + name + } else { + if (!lastName.isNullOrEmpty() || !firstName.isNullOrEmpty()) { + Log.w("[Friend] Name is null or empty, using first and last name") + "$firstName $lastName".trim() + } else if (!organization.isNullOrEmpty()) { + Log.w("[Friend] Name, first name & last name are null or empty, using organization instead") + organization + } else if (!jobTitle.isNullOrEmpty()) { + Log.w("[Friend] Name, first and last names & organization are null or empty, using job title instead") + jobTitle + } else { + Log.e("[Friend] No identification field filled for this friend!") + "Unknown" + } + } + personBuilder.setName(personName) val bm: Bitmap? = getAvatarBitmap() personBuilder.setIcon( @@ -737,7 +755,7 @@ fun Friend.getPerson(): Person { Log.i( "[Friend] Can't use friend [$name] picture path, generating avatar based on initials" ) - AvatarGenerator(coreContext.context).setInitials(AppUtils.getInitials(name.orEmpty())).buildIcon() + AvatarGenerator(coreContext.context).setInitials(AppUtils.getInitials(personName.orEmpty())).buildIcon() } else { IconCompat.createWithAdaptiveBitmap(bm) } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index c75dd5eca..1e11eab28 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -1220,9 +1220,7 @@ class NotificationsManager } else { val contact = friend ?: coreContext.contactsManager.findContactByAddress(remoteAddress) - val displayName = contact?.name ?: LinphoneUtils.getDisplayName(remoteAddress) - - getPerson(contact, displayName) + getPerson(contact, LinphoneUtils.getDisplayName(remoteAddress)) } val isVideo = LinphoneUtils.isVideoEnabled(call) @@ -1588,14 +1586,14 @@ class NotificationsManager } @WorkerThread - private fun getPerson(friend: Friend?, displayName: String): Person { + private fun getPerson(friend: Friend?, fallbackDisplayName: String): Person { return friend?.getPerson() ?: Person.Builder() - .setName(displayName) + .setName(if (fallbackDisplayName.isEmpty()) "Unknown" else fallbackDisplayName) .setIcon( - AvatarGenerator(context).setInitials(AppUtils.getInitials(displayName)).buildIcon() + AvatarGenerator(context).setInitials(AppUtils.getInitials(fallbackDisplayName)).buildIcon() ) - .setKey(displayName) + .setKey(fallbackDisplayName) .setImportant(false) .build() }