diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 70947ae76..c7d429e9a 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -61,7 +61,8 @@ class ContactsManager @UiThread constructor() { private val listeners = arrayListOf() - private val avatarsMap = hashMapOf() + private val knownContactsAvatarsMap = hashMapOf() + private val unknownContactsAvatarsMap = hashMapOf() private val friendListListener: FriendListListenerStub = object : FriendListListenerStub() { @WorkerThread @@ -70,8 +71,9 @@ class ContactsManager @UiThread constructor() { "$TAG Presence received for list [${list.displayName}] and [${friends.size}] friends, cleaning avatars map" ) - avatarsMap.values.forEach(ContactAvatarModel::destroy) - avatarsMap.clear() + // Do not clear the already known contacts avatars! + unknownContactsAvatarsMap.values.forEach(ContactAvatarModel::destroy) + unknownContactsAvatarsMap.clear() for (listener in listeners) { listener.onContactsLoaded() @@ -130,8 +132,10 @@ class ContactsManager @UiThread constructor() { nativeContactsLoaded = true Log.i("$TAG Native contacts have been loaded, cleaning avatars map") - avatarsMap.values.forEach(ContactAvatarModel::destroy) - avatarsMap.clear() + knownContactsAvatarsMap.values.forEach(ContactAvatarModel::destroy) + knownContactsAvatarsMap.clear() + unknownContactsAvatarsMap.values.forEach(ContactAvatarModel::destroy) + unknownContactsAvatarsMap.clear() notifyContactsListChanged() } @@ -210,7 +214,7 @@ class ContactsManager @UiThread constructor() { clone.clean() val key = clone.asStringUriOnly() - val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null + val foundInMap = getAvatarModelFromCache(key) if (foundInMap != null) { Log.i("$TAG Avatar model found in map for SIP URI [$key]") return foundInMap @@ -225,24 +229,28 @@ class ContactsManager @UiThread constructor() { fakeFriend.address = clone fakeFriend.name = LinphoneUtils.getDisplayName(localAccount.params.identityAddress) fakeFriend.photo = localAccount.params.pictureUri - ContactAvatarModel(fakeFriend) + val model = ContactAvatarModel(fakeFriend) + unknownContactsAvatarsMap[key] = model + model } else { Log.i("$TAG Looking for friend matching SIP URI [$key]") val friend = coreContext.contactsManager.findContactByAddress(clone) if (friend != null) { Log.i("$TAG Matching friend [${friend.name}] found for SIP URI [$key]") - ContactAvatarModel(friend) + val model = ContactAvatarModel(friend) + knownContactsAvatarsMap[key] = model + model } else { Log.i("$TAG No matching friend found for SIP URI [$key]...") val fakeFriend = coreContext.core.createFriend() fakeFriend.name = LinphoneUtils.getDisplayName(address) fakeFriend.address = clone - ContactAvatarModel(fakeFriend) + val model = ContactAvatarModel(fakeFriend) + unknownContactsAvatarsMap[key] = model + model } } - avatarsMap[key] = avatar - return avatar } @@ -264,7 +272,7 @@ class ContactsManager @UiThread constructor() { clone.clean() val key = clone.asStringUriOnly() - val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null + val foundInMap = getAvatarModelFromCache(key) if (foundInMap != null) { Log.i("$TAG Found avatar model in map using SIP URI [$key]") return foundInMap @@ -272,7 +280,7 @@ class ContactsManager @UiThread constructor() { Log.w("$TAG Avatar model not found in map with SIP URI [$key]") val avatar = ContactAvatarModel(friend) - avatarsMap[key] = avatar + knownContactsAvatarsMap[key] = avatar return avatar } @@ -286,11 +294,11 @@ class ContactsManager @UiThread constructor() { return ContactAvatarModel(fakeFriend) } - val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null + val foundInMap = getAvatarModelFromCache(key) if (foundInMap != null) return foundInMap val avatar = LinphoneUtils.getAvatarModelForConferenceInfo(conferenceInfo) - avatarsMap[key] = avatar + unknownContactsAvatarsMap[key] = avatar return avatar } @@ -437,6 +445,11 @@ class ContactsManager @UiThread constructor() { return personBuilder.build() } + @WorkerThread + private fun getAvatarModelFromCache(key: String): ContactAvatarModel? { + return knownContactsAvatarsMap[key] ?: unknownContactsAvatarsMap[key] + } + interface ContactsListener { fun onContactsLoaded() } diff --git a/app/src/main/java/org/linphone/ui/main/MainActivity.kt b/app/src/main/java/org/linphone/ui/main/MainActivity.kt index 609aa567e..d9571f8d9 100644 --- a/app/src/main/java/org/linphone/ui/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/ui/main/MainActivity.kt @@ -138,7 +138,7 @@ class MainActivity : AppCompatActivity() { it.consume { error -> val tag = "DEFAULT_ACCOUNT_REGISTRATION_ERROR" if (error) { - // First remove any already existing connection error toat + // First remove any already existing connection error toast removePersistentRedToast(tag) val message = getString(R.string.toast_default_account_connection_state_error) diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt index f019d8d9a..dda8f3548 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt @@ -170,6 +170,27 @@ class MainViewModel @UiThread constructor() : ViewModel() { else -> {} } } + + @WorkerThread + override fun onDefaultAccountChanged(core: Core, account: Account) { + Log.i( + "$TAG Default account changed, now is [${account.params.identityAddress?.asStringUriOnly()}]" + ) + removeAlert(NON_DEFAULT_ACCOUNT_NOTIFICATIONS) + + if (defaultAccountRegistrationFailed && account.state != RegistrationState.Failed) { + Log.i( + "$TAG Newly set default account isn't in failed registration state, clearing alert" + ) + defaultAccountRegistrationFailed = false + defaultAccountRegistrationErrorEvent.postValue(Event(false)) + + // Refresh REGISTER to re-compute alerts regarding accounts registration state + core.refreshRegisters() + } + + // TODO: compute other calls notifications count + } } init { @@ -204,6 +225,13 @@ class MainViewModel @UiThread constructor() : ViewModel() { @UiThread fun closeTopBar() { showAlert.value = false + + coreContext.postOnCoreThread { + Log.i("$TAG User closed alerts top bar, clearing alerts") + cancelAlertJob() + alertsList.clear() + updateDisplayedAlert() + } } @UiThread