From 951a4aeb507a9f1fa95e53d3926f6f57019f6bf1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 5 May 2023 15:38:58 +0200 Subject: [PATCH 01/94] Fixed CHANGELOG format --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cc330195..205f132e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Group changes to describe their impact on the project, as follows: - Messages not marked as reply in basic chat room if sending more than 1 content ## [5.0.10] - 2023-01-04 + ### Fixed - Plain copy of encrypted files (when VFS is enabled) not cleaned - Avatar display issue if contact's "initials" contains more than 1 emoji or an emoji + a character From d5e4e71a681d09b8c703b15346f9f60e677f9cdb Mon Sep 17 00:00:00 2001 From: NPL Date: Tue, 21 Mar 2023 02:10:02 +0000 Subject: [PATCH 02/94] Translated using Weblate (Japanese) Currently translated at 98.8% (774 of 783 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/ja/ --- app/src/main/res/values-ja/strings.xml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index da8d369c9..807422bc3 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -87,9 +87,9 @@ デバイス( %s )を削除しました %s は管理者です セキュリティレベルは %s のため低下しました - 一時的なメッセージを無効にしました - 一時的なメッセージを有効にしました: %s - 一時的なメッセージの有効期限: %s + 期限付きメッセージを無効にしました + 期限付きメッセージを有効にしました: %s + 期限付きメッセージの有効期限: %s ダウンロード ソースを選択 グループ名 @@ -119,10 +119,10 @@ メッセージを削除 グループ情報 連絡先を開く - 一時的なメッセージ + 期限付きメッセージ 通知を無効にする 通知を有効にする - 一時的なメッセージ + 期限付きメッセージ 1分 1時間 1日 @@ -145,7 +145,7 @@ テキストとして開く メディアボリュームが低いため、高くする必要があります - %1$d はメッセージを読んでいません + %1$d件のメッセージを読んでいません メッセージは削除されます 中止 @@ -391,8 +391,8 @@ 電話番号は1つの &appName; アカウントでのみ使用できます。 \n \n既に他のアカウントに番号を紐付けているものの、このアカウントを使用したい場合、今すぐ紐付けることで番号が自動的にこのアカウントに移動されます。 - 一時的なメッセージのファイルは、自動ダウンロード機能ではダウンロードしません - フレンドリストを定期購読 + 期限付きメッセージのファイルは、自動ダウンロード機能ではダウンロードしません + 友達リストを定期購読 ホーム画面に連絡先へのショートカットを作成 新しく作成された連絡先を保存するアカウントを常に尋ねる 電源管理設定 @@ -731,8 +731,8 @@ 現在の通話を他人に転送する 選択した項目から連絡先を削除 参加者のデバイスの表示を切り替える - 一時的の期間を選択しました - 選択した値から一時的の期間を変更しました + 期限付きメッセージの期間を選択しました + 選択した値から期限付きメッセージの期間を変更しました チャットルームを作成 参加者を追加 安全ではありません @@ -770,4 +770,10 @@ 次のように入力: ユーザーはオンラインです ユーザーはオフラインです + アカウントはローカルでのみ削除されます。 +\n永久に削除するには、SIPプロバイダーのウェブサイトから行ってください。 + アカウントは、ローカルでのみ削除されます。 +\n永久に削除するには、アカウント管理プラットフォームへアクセスしてください: + アカウントを削除しますか? + 標準の連絡先に情報を追加する \ No newline at end of file From 1c46d9ae3c5330bc37fc61732996c111bf3e96a6 Mon Sep 17 00:00:00 2001 From: Tomas Ivanek Date: Fri, 17 Mar 2023 10:42:34 +0000 Subject: [PATCH 03/94] Translated using Weblate (Czech) Currently translated at 100.0% (783 of 783 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/cs/ --- app/src/main/res/values-cs/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 9a6ef74bb..773d15e73 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -781,4 +781,10 @@ Zveřejňovat informace o přítomnosti Uživatel je online Uživatel je offline + Přepojení hovoru s ohlášením + Váš účet bude smazán pouze lokálně. +\nChcete-li jej odstranit trvale, přejděte na webové stránky poskytovatele SIP. + Chcete svůj účet smazat\? + Váš účet bude smazán pouze lokálně. +\nChcete-li jej odstranit trvale, přejděte na naši platformu pro správu účtů: \ No newline at end of file From 4392da062b8bb7540a940e3c27fc8f28922f82f9 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 21 Mar 2023 14:36:21 +0000 Subject: [PATCH 04/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (783 of 783 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 63225e538..19c38bea0 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -775,4 +775,10 @@ 上線時間:昨天 上線時間: 發布上線資訊 + 您確定要刪除帳號嗎? + 將只會刪除您本機上的帳號。 +\n若要永久刪除,請到您的 SIP 服務業者網站刪除。 + 將只會刪除您本機上的帳號。 +\n若要永久刪除,請到帳號管理平台刪除: + 保留轉接 \ No newline at end of file From 7e4cf381be7f1249e0cd2a63b13c287319537760 Mon Sep 17 00:00:00 2001 From: NPL Date: Tue, 21 Mar 2023 04:50:09 +0000 Subject: [PATCH 05/94] Translated using Weblate (Japanese) Currently translated at 98.8% (774 of 783 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/ja/ --- app/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 807422bc3..98d063e9e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -213,7 +213,7 @@ この会議を暗号化しますか? 再生ボタンをクリックすると、再び会議に参加できます。 リモートグループ通話 - あなたは現在会議に参加しています。 + あなたは現在会議から外れています。 ローカルグループ通話 会議への招待: 会議 From f895d2ac190022ff68fea44c0d7b0fddc7598916 Mon Sep 17 00:00:00 2001 From: George Salukvadze Date: Fri, 24 Mar 2023 16:08:12 +0000 Subject: [PATCH 06/94] Translated using Weblate (Georgian) Currently translated at 100.0% (783 of 783 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/ka/ --- app/src/main/res/values-ka/strings.xml | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 30af133a8..fe8d4d42d 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -756,4 +756,32 @@ მონაწილეს მიკროფონი აქვს გათიშული შეხვედრის ინფორმაციის დეტალების ჩვენების გადართვა ჩანაწერის ექსპორტირება + ეკრანის ანაბეჭდი იქნა გადაღებული: %s + შეხვედრის რედაქტირება + შეხვედრა განახლდა: + შეხვედრა გაუქმდა: + &appName;-ს მეშვეობით განახლების გაგზავნა + გსურთ თქვენი ანგარიშის წაშლა\? + თქვენი ანგარიში წაიშლება მხოლოდ ლოკალურად. +\nმისი მუდმივად წასაშლელად, გადადით თქვენი SIP მიმწოდებლის ვებსაიტზე. + თქვენი ანგარიში წაიშლება მხოლოდ ლოკალურად. +\nმისი მუდმივად წასაშლელად, გადადით თქვენი ანგარიშის მართვის პლატფორმაზე: + თქვენ მიიღეთ ხმოვანი შეტყობინება + ხმოვანი შეტყობინება + განახლების გაგზავნა ელ. ფოსტის მეშვეობით + დასწრების ინფორმაციის გამოქვეყნება + მომხმარებელი ქსელშია + დასწრებით გადამისამართება + E2E დაშიფრვის გასაღებების სერვერის URL + მომხმარებელი არ არის ქსელში + ქსელში + ქსელში დღეს + ქსელში გუშინ + ქსელში + გსურთ ამ შეხვედრების წაშლა\? + კონფერენცია გაუქმდა შემქმნელის მიერ + თქვენ გააუქმეთ კონფერენცია + უსაფრთხოების დონის გასაზრდელად, შეგიძლიათ თქვენს მოკავშირესთან შეამოწმოთ შემდეგი კოდები. + მოგვიანებით + შესწორება \ No newline at end of file From 7a541ff79794c25c801d845536a3644add74c41e Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Sun, 26 Mar 2023 10:35:11 +0000 Subject: [PATCH 07/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (785 of 785 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 19c38bea0..dd40316e0 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -781,4 +781,6 @@ 將只會刪除您本機上的帳號。 \n若要永久刪除,請到帳號管理平台刪除: 保留轉接 + 勿干擾 + 使用者要求勿干擾 \ No newline at end of file From 48b185ae0c42c89f0163d647bedee1321b71e47f Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 29 Mar 2023 07:52:51 +0000 Subject: [PATCH 08/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (788 of 788 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index dd40316e0..6e16b4ac5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -783,4 +783,7 @@ 保留轉接 勿干擾 使用者要求勿干擾 + 套用 + 您確認要從這個網址下載套用設定資訊嗎? + %s: \ No newline at end of file From 01a10fb806f47f0c32067be463c6c65aad3127e8 Mon Sep 17 00:00:00 2001 From: Ville Hartikainen Date: Mon, 3 Apr 2023 06:24:49 +0000 Subject: [PATCH 09/94] Translated using Weblate (Finnish) Currently translated at 54.5% (430 of 788 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/fi/ --- app/src/main/res/values-fi/strings.xml | 45 +++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 8755a96fc..a53d1c8d8 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -368,7 +368,7 @@ SRTP ZRTP DTLS-SRTP - + Median salaus pakollinen Aloita puhelu välittömästi Automaattivastaus tuleville puheluille @@ -384,4 +384,47 @@ Käytä satunnaisia portteja Käytettävä SIP portti Kaverilistan tilaus + Kaiunpoiston kalibrointi aloitettu + %s: + Näytettävä nimi (valinnainen) + Yhdistä tili + Hae asetukset palvelimelta + Syötä konfiguraation URL + Olet liittämässä puhelinnumerosi seuraavaan käyttäjätunnukseen: + URL + Väärinmuotoiltu URL, provisiointiprofiilia ei voida ladata… + Provisiointiprofiilin lataus tai asennus epäonnistui… + Nouda ja aseta + QR-koodi + SIP-tilit + Oletustili + Asetukset + Tunneli + Ääni + Video + Keskustelu + Verkko + Paina aloittaaksesi kaiun testaus + Kaiun testaus lopetettu + Kaiun testaus käynnissä + Muutokset tulevat voimaan seuraavasta puhelusta + Käytä laitteen soittoääntä + Puhelu + Koodekit + Älä häiritse + Ohita + Yhteystiedot + Lisäasetukset + Kokoukset + Päätili + Näytettävä nimi + Käyttäjätunnus + Kaiunpoisto + Poistaa vastaanottajan kuuleman kaiun + Kaiunpoiston kalibrointi + Paina ja aloit kaiunpoiston kalibrointi + Kalibroitu %s ms:ssa + Kalibrointi epäonnistui + Kaikua ei havaittu + Testaa kaikua \ No newline at end of file From 05d76898dc17378a0634c4a88d61638350bd22ee Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 5 Apr 2023 03:53:27 +0000 Subject: [PATCH 10/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (793 of 793 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6e16b4ac5..25e6586de 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -786,4 +786,9 @@ 套用 您確認要從這個網址下載套用設定資訊嗎? %s: + 密碼 + 驗證 + 密碼不正確! + 發生未預期的錯誤… + 請在下方輸入密碼,來存取設定內容 \ No newline at end of file From 04e7533687fcdd597be623f2251b29ee115cf6fd Mon Sep 17 00:00:00 2001 From: Tomas Ivanek Date: Fri, 7 Apr 2023 10:51:10 +0000 Subject: [PATCH 11/94] Translated using Weblate (Czech) Currently translated at 100.0% (793 of 793 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/cs/ --- app/src/main/res/values-cs/strings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 773d15e73..af8f6c9d8 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -787,4 +787,14 @@ Chcete svůj účet smazat\? Váš účet bude smazán pouze lokálně. \nChcete-li jej odstranit trvale, přejděte na naši platformu pro správu účtů: + Použít + Chcete stáhnout a použít konfiguraci z této adresy URL\? + Neočekávaná chyba… + Pro přístup k nastavení zadejte níže své heslo + Heslo + Ověřit + Nesprávné heslo! + Uživatel si nepřeje být vyrušován + %s: + Nerušit \ No newline at end of file From 60af85a380cbdf8adaf8335e30a98c2a0201ddd2 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 14 Apr 2023 02:28:30 +0000 Subject: [PATCH 12/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (793 of 793 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 25e6586de..c1bb1d95d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -791,4 +791,5 @@ 密碼不正確! 發生未預期的錯誤… 請在下方輸入密碼,來存取設定內容 + 軟體迴音消除 \ No newline at end of file From 17d9237a7a486d0e2882935cbd6556212f2355e5 Mon Sep 17 00:00:00 2001 From: NPL Date: Sat, 15 Apr 2023 09:45:39 +0000 Subject: [PATCH 13/94] Translated using Weblate (Japanese) Currently translated at 99.2% (787 of 793 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/ja/ --- app/src/main/res/values-ja/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 98d063e9e..61a1eeaee 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -776,4 +776,16 @@ \n永久に削除するには、アカウント管理プラットフォームへアクセスしてください: アカウントを削除しますか? 標準の連絡先に情報を追加する + 適用 + 予期せぬエラー… + 設定にアクセスするにはパスワードを入力してください + パスワード + 確認 + 無効なパスワードです! + ソフトウェアエコーキャンセラー + このURLから設定をダウンロードして適用しますか? + %s: + 今日オンラインでした - + 昨日オンラインでした - + オンラインでした - \ No newline at end of file From c3be132dff46805f41377c6dcbd30761b50ca8dc Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 19 Apr 2023 05:31:40 +0000 Subject: [PATCH 14/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (794 of 794 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c1bb1d95d..f537a6c02 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -792,4 +792,5 @@ 發生未預期的錯誤… 請在下方輸入密碼,來存取設定內容 軟體迴音消除 + 離開 \ No newline at end of file From 35151ad83f9a3dbe86c4d0c3ec909f02cd0497d6 Mon Sep 17 00:00:00 2001 From: Tomas Ivanek Date: Sat, 22 Apr 2023 16:09:51 +0000 Subject: [PATCH 15/94] Translated using Weblate (Czech) Currently translated at 100.0% (794 of 794 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/cs/ --- app/src/main/res/values-cs/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index af8f6c9d8..0876d1ab7 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -797,4 +797,6 @@ Uživatel si nepřeje být vyrušován %s: Nerušit + Pryč + Softwarové potlačení ozvěny \ No newline at end of file From 8cf2e96abbf47ea2c19290215d94053978856748 Mon Sep 17 00:00:00 2001 From: Tomas Ivanek Date: Sun, 30 Apr 2023 05:09:12 +0000 Subject: [PATCH 16/94] Translated using Weblate (Czech) Currently translated at 100.0% (794 of 794 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/cs/ --- app/src/main/res/values-cs/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 0876d1ab7..583bf047e 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -19,7 +19,7 @@ Port v bajtech Bude používat jeden server pro nahrávání a druhý pro stahování - Se soubory v mizejících zprávách takto nebude nakládáno, toto nefunguje s funkcí automatického stahování + Automatické stahování nefunguje u souborů v mizejích zprávách Automaticky Skrýt chatovací místnosti z odstraněných konfigurací proxy serverů Uživatelské jméno @@ -90,7 +90,7 @@ Otevřít konverzaci v aplikaci místo bubliny Zastavit nahrávání hlasu Posun na konec nebo na první nepřečtenou zprávu - Toto je nutné pro příjem hovorů na pozadí + Umožňuje příjem hovorů na pozadí &appName; kontakty &appName; Služba Odeslání logu selhalo! @@ -144,7 +144,7 @@ Kontakt nemůže být smazán Ladění Povolit logování - Odeslat logy + Odeslat log Zobrazit konfigurační soubor Hovor se přepojuje Hovor nelze přepojit @@ -390,7 +390,7 @@ Nikdy Pokud je menší než daná maximální velikost Maximální velikost - Zpřístupnění stažených médií + Zpřístupnit stažená média Skrytí obsahu zpráv v oznámeních Zobrazí se pouze jméno odesílatele Vytvoření zástupců chatovacích místností ve spouštěči @@ -400,7 +400,7 @@ Vždy otevírejte soubory v této aplikaci I nadále je budete moci exportovat v aplikacích třetích stran Automatické stahování příchozích hlasových nahrávek - Používejte pouze na Wi-Fi + Používat jen na Wi-Fi Povolit IPv6 Použít náhodné porty SIP port @@ -436,7 +436,7 @@ Doména Různé Ladění - Ladící logy + Logování Režim na pozadí Spuštění při startu systému Tmavé téma @@ -452,8 +452,8 @@ Nastavení správce napájení Jméno hostitele Jakmile je jednou povoleno, nelze již vypnout! - Odeslat logy - Reset logů + Odeslat log + Resetovat log Nastavení ladění Vypnutí zabezpečeného režimu uživatelského rozhraní Duální režim je zapnutý From 4e613d0d1ee820570ac0962c3dcb66126751cbf2 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 4 May 2023 08:37:32 +0000 Subject: [PATCH 17/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 99.8% (795 of 796 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f537a6c02..718e66993 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -793,4 +793,5 @@ 請在下方輸入密碼,來存取設定內容 軟體迴音消除 離開 + 關閉 bundle mode \ No newline at end of file From f31b3daeac62c82dece31c766cca27f3fbbc8143 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Sat, 6 May 2023 07:11:57 +0000 Subject: [PATCH 18/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 99.7% (797 of 799 strings) Translation: Linphone/Linphone Android (master) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 718e66993..58e722e66 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -330,7 +330,7 @@ 在主畫面中放置聊天室捷徑 如果啟用,將取代為聯絡人捷徑 隱藏空的聊天室 - 於代理伺服器設定中隱藏聊天室名稱 + 於移除的帳號中隱藏聊天室 若您有一些聊天室不見了,可嘗試取消此選項 Android 通知設定 只使用 Wi-Fi @@ -383,7 +383,7 @@ 連結您的帳號 刪除 進階 - 於代理伺服器設定不取消註冊 + 帳號不取消註冊 傳輸方式 UDP TCP @@ -794,4 +794,9 @@ 軟體迴音消除 離開 關閉 bundle mode + 若要使用電子郵件地址來註冊帳號: + 您的裝置看來無法接收推送通知。 +\n +\n現在起註冊帳號時就必須使用此功能,您無法直接於程式中註冊帳號,但還是可以在網頁中註冊: + 您的帳號尚未啟用,請點擊收到的確認信件中的連結 \ No newline at end of file From 27c2b288f6d3d3274794cf4807de743306095b60 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 May 2023 09:05:42 +0200 Subject: [PATCH 19/94] Fixed xml entity translation issue + removed translated string no longer existing --- app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-ka/strings.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index a53d1c8d8..65f1e97a5 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -419,7 +419,6 @@ Päätili Näytettävä nimi Käyttäjätunnus - Kaiunpoisto Poistaa vastaanottajan kuuleman kaiun Kaiunpoiston kalibrointi Paina ja aloit kaiunpoiston kalibrointi diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index fe8d4d42d..2ce23ece6 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -760,7 +760,7 @@ შეხვედრის რედაქტირება შეხვედრა განახლდა: შეხვედრა გაუქმდა: - &appName;-ს მეშვეობით განახლების გაგზავნა + &appName;-ს მეშვეობით განახლების გაგზავნა გსურთ თქვენი ანგარიშის წაშლა\? თქვენი ანგარიში წაიშლება მხოლოდ ლოკალურად. \nმისი მუდმივად წასაშლელად, გადადით თქვენი SIP მიმწოდებლის ვებსაიტზე. From 684f913254bf731eff2fa3b938c1590af8d03611 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 May 2023 10:40:37 +0200 Subject: [PATCH 20/94] Updated CHANGELOG from release/5.0 branch --- CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 205f132e2..81280519d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,19 @@ Group changes to describe their impact on the project, as follows: ### Fixed - Messages not marked as reply in basic chat room if sending more than 1 content -## [5.0.10] - 2023-01-04 +## [5.0.11] - 2023-05-09 + +### Fixed +- Wrong call displayed when hanging up a call while an incoming one is ringing +- Crash related to call history +- Crash due to wrongly format string +- Add/remove missing listener on FriendLists created after Core has been created + +### Changed +- Improved GSM call interruption +- Updated translations + +## [5.0.10] - 2023-04-04 ### Fixed - Plain copy of encrypted files (when VFS is enabled) not cleaned From 918b0d678d5b66ed5ab1de40122b01ade73294a1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 May 2023 11:26:08 +0200 Subject: [PATCH 21/94] Show authentication requested dialog if needed --- .../linphone/activities/main/MainActivity.kt | 48 +++++++++++++++++++ .../java/org/linphone/core/CoreContext.kt | 5 ++ app/src/main/res/values-fr/strings.xml | 3 ++ app/src/main/res/values/strings.xml | 3 ++ 4 files changed, 59 insertions(+) diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index f170c5be5..c145e8a73 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -58,6 +58,7 @@ import org.linphone.activities.main.viewmodels.SharedMainViewModel import org.linphone.activities.navigateToDialer import org.linphone.compatibility.Compatibility import org.linphone.contact.ContactsUpdatedListenerStub +import org.linphone.core.AuthInfo import org.linphone.core.CorePreferences import org.linphone.core.tools.Log import org.linphone.databinding.MainActivityBinding @@ -143,6 +144,14 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin } } + coreContext.authenticationRequestedEvent.observe( + this + ) { + it.consume { authInfo -> + showAuthenticationRequestedDialog(authInfo) + } + } + if (coreContext.core.accountList.isEmpty()) { if (corePreferences.firstStart) { startActivity(Intent(this, AssistantActivity::class.java)) @@ -630,4 +639,43 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin dialog.show() } + + private fun showAuthenticationRequestedDialog( + authInfo: AuthInfo + ) { + val identity = "${authInfo.username}@${authInfo.domain}" + Log.i("[Main Activity] Showing authentication required dialog for account [$identity]") + + val dialogViewModel = DialogViewModel( + getString(R.string.dialog_authentication_required_message, identity), + getString(R.string.dialog_authentication_required_title) + ) + dialogViewModel.showPassword = true + dialogViewModel.passwordTitle = getString( + R.string.settings_password_protection_dialog_input_hint + ) + val dialog = DialogUtils.getDialog(this, dialogViewModel) + + dialogViewModel.showCancelButton { + dialog.dismiss() + } + + dialogViewModel.showOkButton( + { + Log.i( + "[Main Activity] Updating password for account [$identity] using auth info [$authInfo]" + ) + val newPassword = dialogViewModel.password + authInfo.password = newPassword + coreContext.core.addAuthInfo(authInfo) + + coreContext.core.refreshRegisters() + + dialog.dismiss() + }, + getString(R.string.dialog_authentication_required_change_password_label) + ) + + dialog.show() + } } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index c80b6d605..202e0c181 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -117,6 +117,10 @@ class CoreContext( MutableLiveData>() } + val authenticationRequestedEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private val loggingService = Factory.instance().loggingService @@ -169,6 +173,7 @@ class CoreContext( Log.w( "[Context] Authentication requested for account [${authInfo.username}@${authInfo.domain}] with realm [${authInfo.realm}] using method [$method]" ) + authenticationRequestedEvent.value = Event(authInfo) } override fun onPushNotificationReceived(core: Core, payload: String?) { diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4ca897fd9..40f6a45c0 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -785,4 +785,7 @@ Pour créer un compte avec votre email : Votre périphérique ne semble pas supporter les notifications \'push\'.\n\nVous ne pourrez donc pas créer des comptes dans l\'application mais vous pouvez toujours le faire sur notre site internet : Votre compte n\'est pas activé, veuillez cliquer sur le lien que vous avez reçu par courriel + Authentification requise + La connexion a échouée car l\'authentification est manquante ou invalide pour le compte\n%s.\n\nVous pouvez fournir le mot de passe à nouveau ou vérifier la configuration de votre compte dans les paramètres. + Confirmer \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cc6f60741..9637f0a94 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -774,6 +774,9 @@ Would you like to try opening it as a plain text file? Do you want to download and apply configuration from this URL? Apply + Authentication needed + Connection failed because authentication is missing or invalid for account \n%s.\n\nYou can provide password again, or check your account configuration in the settings. + Confirm Add a SIP address field From 1f9a55699c4ce81e54fe1b478179c5d71adb088d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 May 2023 15:11:32 +0200 Subject: [PATCH 22/94] Fixed video preview not moving if call was started in audio only --- .../voip/fragments/GenericVideoPreviewFragment.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt index 1f7e07141..5b649fc14 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt @@ -68,11 +68,9 @@ abstract class GenericVideoPreviewFragment : GenericFragmen } protected fun setupLocalViewPreview(localVideoPreview: TextureView, switchCamera: ImageView?) { - if (coreContext.core.currentCall?.currentParams?.isVideoEnabled == true) { - videoPreviewTextureView = localVideoPreview - switchCameraImageView = switchCamera - videoPreviewTextureView.setOnTouchListener(previewTouchListener) - } + videoPreviewTextureView = localVideoPreview + switchCameraImageView = switchCamera + videoPreviewTextureView.setOnTouchListener(previewTouchListener) } override fun onResume() { From d14a62730a17e1f2625c5d5b4c9f02f9483a17b9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 11 May 2023 10:43:38 +0200 Subject: [PATCH 23/94] Bumped dependencies --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e754a8f6b..767676097 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -198,10 +198,10 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.core:core-ktx:1.10.0' + implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.core:core-splashscreen:1.0.1' - implementation 'androidx.emoji2:emoji2:1.4.0-beta02' - implementation 'androidx.emoji2:emoji2-emojipicker:1.4.0-beta02' + implementation 'androidx.emoji2:emoji2:1.4.0-beta03' + implementation 'androidx.emoji2:emoji2-emojipicker:1.4.0-beta03' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.media:media:1.6.0' implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06" From 8397debb00c05ada76a3daeeb9e744fbf2bba281 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 11 May 2023 16:55:30 +0200 Subject: [PATCH 24/94] Prevent crash if NotificationManager throws an exception --- .../java/org/linphone/notifications/NotificationsManager.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index df4a30389..80fe50ffa 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -317,7 +317,11 @@ class NotificationsManager(private val context: Context) { } Log.i("[Notifications Manager] Notifying [$id] with tag [$tag]") - notificationManager.notify(tag, id, notification) + try { + notificationManager.notify(tag, id, notification) + } catch (iae: IllegalArgumentException) { + Log.e("[Notifications Manager] Exception occurred: $iae") + } } fun cancel(id: Int, tag: String? = null) { From 76334e03e6dd1d21d72a3b095bf470ad3cddbdb5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 16 May 2023 10:01:43 +0200 Subject: [PATCH 25/94] Changes for how we handle presence in background + updated presence setting & moved it from Accounts to Contacts --- .../fragments/AccountSettingsFragment.kt | 8 ------ .../fragments/ContactsSettingsFragment.kt | 8 ++++++ .../viewmodels/AccountSettingsViewModel.kt | 15 ---------- .../viewmodels/ContactsSettingsViewModel.kt | 28 +++++++++++++++++++ .../java/org/linphone/core/CoreContext.kt | 18 +++++++----- .../java/org/linphone/core/CorePreferences.kt | 6 ++++ .../res/layout/settings_account_fragment.xml | 6 ---- .../res/layout/settings_contacts_fragment.xml | 6 ++++ 8 files changed, 59 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt b/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt index 049bdd531..b06648585 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt @@ -98,14 +98,6 @@ class AccountSettingsFragment : GenericSettingFragment>() } - val publishPresenceToggledEvent: MutableLiveData> by lazy { - MutableLiveData>() - } - val displayUsernameInsteadOfIdentity = corePreferences.replaceSipUriByUsername private var accountToDelete: Account? = null @@ -439,16 +435,6 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel( } val limeServerUrl = MutableLiveData() - val publishPresenceListener = object : SettingListenerStub() { - override fun onBoolValueChanged(newValue: Boolean) { - val params = account.params.clone() - params.isPublishEnabled = newValue - account.params = params - publishPresenceToggledEvent.value = Event(true) - } - } - val publishPresence = MutableLiveData() - val disableBundleModeListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { val params = account.params.clone() @@ -518,7 +504,6 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel( limeServerUrl.value = params.limeServerUrl hideLinkPhoneNumber.value = corePreferences.hideLinkPhoneNumber || params.identityAddress?.domain != corePreferences.defaultDomain - publishPresence.value = params.isPublishEnabled disableBundleMode.value = !params.isRtpBundleEnabled } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt index 619e15849..0806ab461 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt @@ -22,6 +22,8 @@ package org.linphone.activities.main.settings.viewmodels import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.activities.main.settings.SettingListenerStub +import org.linphone.core.ConsolidatedPresence +import org.linphone.core.tools.Log import org.linphone.utils.Event import org.linphone.utils.PermissionHelper @@ -40,6 +42,30 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() { val friendListSubscribe = MutableLiveData() val rlsAddressAvailable = MutableLiveData() + val publishPresenceListener = object : SettingListenerStub() { + override fun onBoolValueChanged(newValue: Boolean) { + prefs.publishPresence = newValue + + if (newValue) { + // Publish online presence when enabling setting + Log.i( + "[Contacts Settings] Presence has been enabled, PUBLISHING presence as Online" + ) + core.consolidatedPresence = ConsolidatedPresence.Online + } else { + // Unpublish presence when disabling setting + Log.i("[Contacts Settings] Presence has been disabled, un-PUBLISHING presence info") + core.consolidatedPresence = ConsolidatedPresence.Offline + } + + publishPresenceToggledEvent.value = Event(true) + } + } + val publishPresence = MutableLiveData() + val publishPresenceToggledEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + val showNewContactAccountDialogListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { prefs.showNewContactAccountDialog = newValue @@ -97,6 +123,8 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() { friendListSubscribe.value = core.isFriendListSubscriptionEnabled rlsAddressAvailable.value = !core.config.getString("sip", "rls_uri", "").isNullOrEmpty() + publishPresence.value = prefs.publishPresence + showNewContactAccountDialog.value = prefs.showNewContactAccountDialog nativePresence.value = prefs.storePresenceInNativeContact showOrganization.value = prefs.displayOrganization diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 202e0c181..4b38f1269 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -436,18 +436,22 @@ class CoreContext( } fun onForeground() { - // If presence publish is disabled and we call core.setConsolidatedPresence, it will enabled it! - if (core.defaultAccount?.params?.isPublishEnabled == true) { - Log.i("[Context] App is in foreground, setting consolidated presence to Online") + // We can't rely on defaultAccount?.params?.isPublishEnabled + // as it will be modified by the SDK when changing the presence status + if (corePreferences.publishPresence) { + Log.i("[Context] App is in foreground, PUBLISHING presence as Online") core.consolidatedPresence = ConsolidatedPresence.Online } } fun onBackground() { - // If presence publish is disabled and we call core.setConsolidatedPresence, it will enabled it! - if (core.defaultAccount?.params?.isPublishEnabled == true) { - Log.i("[Context] App is in background, setting consolidated presence to Busy") - core.consolidatedPresence = ConsolidatedPresence.Busy + // We can't rely on defaultAccount?.params?.isPublishEnabled + // as it will be modified by the SDK when changing the presence status + if (corePreferences.publishPresence) { + Log.i("[Context] App is in background, un-PUBLISHING presence info") + // We don't use ConsolidatedPresence.Busy but Offline to do an unsubscribe, + // Flexisip will handle the Busy status depending on other devices + core.consolidatedPresence = ConsolidatedPresence.Offline } } diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index 9d88e0a32..51c8e7f6d 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -280,6 +280,12 @@ class CorePreferences constructor(private val context: Context) { config.setBool("app", "contact_shortcuts", value) } + var publishPresence: Boolean + get() = config.getBool("app", "publish_presence", true) + set(value) { + config.setBool("app", "publish_presence", value) + } + /* Call */ var sendEarlyMedia: Boolean diff --git a/app/src/main/res/layout/settings_account_fragment.xml b/app/src/main/res/layout/settings_account_fragment.xml index af9d48967..44a9c6173 100644 --- a/app/src/main/res/layout/settings_account_fragment.xml +++ b/app/src/main/res/layout/settings_account_fragment.xml @@ -127,12 +127,6 @@ linphone:checked="@={viewModel.isDefault}" linphone:enabled="@{!viewModel.isDefault}"/> - - + + Date: Tue, 16 May 2023 09:42:11 +0200 Subject: [PATCH 26/94] Improved how TextureViews are handled in calls & confs --- app/build.gradle | 2 +- .../voip/fragments/CallsListFragment.kt | 14 ++++++++++++-- .../voip/fragments/ConferenceLayoutFragment.kt | 11 +++++++---- .../fragments/ConferenceParticipantsFragment.kt | 6 ++---- .../voip/fragments/GenericVideoPreviewFragment.kt | 15 +++++---------- .../voip/fragments/OutgoingCallFragment.kt | 13 ++++++++----- .../voip/fragments/SingleCallFragment.kt | 9 ++++++--- 7 files changed, 41 insertions(+), 29 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 767676097..f2f0e860a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -247,7 +247,7 @@ dependencies { implementation 'org.linphone:linphone-sdk-android:5.2+' // Only enable leak canary prior to release - //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4' + // debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10' } task generateContactsXml(type: Copy) { diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt index 2cd8ba9a3..d48bf8e71 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt @@ -62,8 +62,6 @@ class CallsListFragment : GenericVideoPreviewFragment @@ -90,12 +87,13 @@ class ConferenceParticipantsFragment : GenericVideoPreviewFragment : GenericFragmen private var switchY: Float = 0f private var switchCameraImageView: ImageView? = null - private lateinit var videoPreviewTextureView: TextureView private val previewTouchListener = View.OnTouchListener { view, event -> when (event.action) { @@ -67,17 +66,13 @@ abstract class GenericVideoPreviewFragment : GenericFragmen } } - protected fun setupLocalViewPreview(localVideoPreview: TextureView, switchCamera: ImageView?) { - videoPreviewTextureView = localVideoPreview + protected fun setupLocalVideoPreview(localVideoPreview: TextureView, switchCamera: ImageView?) { switchCameraImageView = switchCamera - videoPreviewTextureView.setOnTouchListener(previewTouchListener) + localVideoPreview.setOnTouchListener(previewTouchListener) + coreContext.core.nativePreviewWindowId = localVideoPreview } - override fun onResume() { - super.onResume() - - if (::videoPreviewTextureView.isInitialized) { - coreContext.core.nativePreviewWindowId = videoPreviewTextureView - } + protected fun cleanUpLocalVideoPreview(localVideoPreview: TextureView) { + localVideoPreview.setOnTouchListener(null) } } diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt index 32bc7b828..8ba1baa55 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt @@ -24,7 +24,6 @@ import android.os.SystemClock import android.view.View import android.widget.Chronometer import androidx.navigation.navGraphViewModels -import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.activities.navigateToActiveCall import org.linphone.activities.voip.viewmodels.CallsViewModel @@ -46,8 +45,6 @@ class OutgoingCallFragment : GenericVideoPreviewFragment Date: Mon, 22 May 2023 09:41:23 +0200 Subject: [PATCH 27/94] Improved error log in case it is 'expected' --- app/src/main/java/org/linphone/core/CoreService.kt | 3 ++- .../org/linphone/notifications/NotificationsManager.kt | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/linphone/core/CoreService.kt b/app/src/main/java/org/linphone/core/CoreService.kt index a8bfead64..a6d798ade 100644 --- a/app/src/main/java/org/linphone/core/CoreService.kt +++ b/app/src/main/java/org/linphone/core/CoreService.kt @@ -34,7 +34,8 @@ class CoreService : CoreService() { } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - Log.i("[Service] Ensuring Core exists") + Log.i("[Service] Starting, ensuring Core exists") + if (corePreferences.keepServiceAlive) { Log.i("[Service] Starting as foreground to keep app alive in background") if (!ensureCoreExists( diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 80fe50ffa..a265cb475 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -320,7 +320,14 @@ class NotificationsManager(private val context: Context) { try { notificationManager.notify(tag, id, notification) } catch (iae: IllegalArgumentException) { - Log.e("[Notifications Manager] Exception occurred: $iae") + if (service == null && tag == null) { + // We can't notify using CallStyle if there isn't a foreground service running + Log.w( + "[Notifications Manager] Foreground service hasn't started yet, can't display a CallStyle notification until then: $iae" + ) + } else { + Log.e("[Notifications Manager] Exception occurred: $iae") + } } } From 949d2ca917cd0bdb1270e1d3cc8a097004ea88b8 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 10 May 2023 06:22:48 +0000 Subject: [PATCH 28/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (802 of 802 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 58e722e66..d3492c188 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -799,4 +799,9 @@ \n \n現在起註冊帳號時就必須使用此功能,您無法直接於程式中註冊帳號,但還是可以在網頁中註冊: 您的帳號尚未啟用,請點擊收到的確認信件中的連結 + 需要驗證 + 由於缺少帳號 %s 的驗證資訊,或是驗證資訊無效,連線失敗。 +\n +\n您可以再次輸入密碼,或是到設定畫面中確認帳號設定。 + 確認 \ No newline at end of file From e907dbaaca523d6999dd163b687170c1e305104f Mon Sep 17 00:00:00 2001 From: NPL Date: Thu, 11 May 2023 09:09:44 +0000 Subject: [PATCH 29/94] Translated using Weblate (Japanese) Currently translated at 99.1% (795 of 802 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/ja/ --- app/src/main/res/values-ja/strings.xml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 61a1eeaee..19939bee3 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -290,7 +290,7 @@ 受信した映像のFPS: 送信側の損失率: 受信側の損失率: - Jitter buffer: + ジッターバッファー: エンコーダー: デコーダー: プレーヤーのフィルター: @@ -376,9 +376,9 @@ 映像のプリセット FPSを優先する URL - Microphone gain + マイクゲイン (デシベル) - Playback gain + プレイバックゲイン デフォルトの音声入力デバイス 利用規約 会議をキャンセルしました @@ -406,7 +406,7 @@ 前面カメラと背面カメラの切り替え マイクをミュートにする ホーム画面にチャットルームのショートカットを作成 - 削除されたプロキシ設定からチャットルームを非表示にする + 削除されたアカウントからチャットルームを非表示にする アカウントを紐付ける URLの形式が不明なため、設定をダウンロードできません… 取得して適用 @@ -788,4 +788,15 @@ 今日オンラインでした - 昨日オンラインでした - オンラインでした - + Eメールを使用してアカウントを作成: + このデバイスではプッシュ通知を受信することができません。 +\n +\nアカウント作成時にプッシュ通知の受信が必須となったため、このアプリ内ではアカウントを作成することができませんが、当社のWebサイト上で作成することができます: + 認証が必要です + 認証 + 認証の失敗、もしくは無効なアカウントのため +\n%s の接続に失敗しました。 +\n +\n再度パスワードを入力するか、設定からアカウントの構成を確認することができます。 + アカウントがアクティベートされていません。受信したEメールのリンクを開いてください \ No newline at end of file From 6dba85d41b845096b6d42fee60baf395c9fda6db Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 23 May 2023 11:44:17 +0200 Subject: [PATCH 30/94] Updated changelog with 5.0.12 release info --- CHANGELOG.md | 6 ++++++ .../activities/main/chat/data/ChatMessageContentData.kt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81280519d..2da6a127d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,12 @@ Group changes to describe their impact on the project, as follows: ### Fixed - Messages not marked as reply in basic chat room if sending more than 1 content +## [5.0.12] - 2023-05-23 + +### Fixed +- Crash if notification manager throws an exception +- Video preview not moving if call was started in audio only + ## [5.0.11] - 2023-05-09 ### Fixed diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt index d97232dc0..2ef13258b 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt @@ -182,7 +182,7 @@ class ChatMessageContentData( val content = getContent() val filePath = content.filePath if (content.isFileTransfer) { - if (filePath == null || filePath.isEmpty()) { + if (filePath.isNullOrEmpty()) { val contentName = content.name if (contentName != null) { val file = FileUtils.getFileStoragePath(contentName) From e841a8fbc8e5b73ba038e121f77cd2d2a0df040f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 23 May 2023 11:52:08 +0200 Subject: [PATCH 31/94] Fixed long-term presence icon not refreshed in contacts list --- .../main/contact/viewmodels/ContactViewModel.kt | 11 ++++++----- .../main/java/org/linphone/contact/ContactsManager.kt | 3 +-- app/src/main/res/layout/contact_list_cell.xml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt index 4489714ec..2748e395c 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt @@ -34,7 +34,7 @@ import org.linphone.activities.main.contact.data.ContactNumberOrAddressData import org.linphone.activities.main.viewmodels.MessageNotifierViewModel import org.linphone.contact.ContactDataInterface import org.linphone.contact.ContactsUpdatedListenerStub -import org.linphone.contact.hasPresence +import org.linphone.contact.hasLongTermPresence import org.linphone.core.* import org.linphone.core.tools.Log import org.linphone.utils.Event @@ -81,6 +81,8 @@ class ContactViewModel(friend: Friend, async: Boolean = false) : MessageNotifier val readOnlyNativeAddressBook = MutableLiveData() + val hasLongTermPresence = MutableLiveData() + private val chatRoomListener = object : ChatRoomListenerStub() { override fun onStateChanged(chatRoom: ChatRoom, state: ChatRoom.State) { if (state == ChatRoom.State.Created) { @@ -147,16 +149,19 @@ class ContactViewModel(friend: Friend, async: Boolean = false) : MessageNotifier isNativeContact.postValue(friend.refKey != null) presenceStatus.postValue(friend.consolidatedPresence) readOnlyNativeAddressBook.postValue(corePreferences.readOnlyNativeContacts) + hasLongTermPresence.postValue(friend.hasLongTermPresence()) } else { contact.value = friend displayName.value = friend.name isNativeContact.value = friend.refKey != null presenceStatus.value = friend.consolidatedPresence readOnlyNativeAddressBook.value = corePreferences.readOnlyNativeContacts + hasLongTermPresence.value = friend.hasLongTermPresence() } friend.addListener { presenceStatus.value = it.consolidatedPresence + hasLongTermPresence.value = it.hasLongTermPresence() } } @@ -269,8 +274,4 @@ class ContactViewModel(friend: Friend, async: Boolean = false) : MessageNotifier } numbersAndAddresses.postValue(list) } - - fun hasPresence(): Boolean { - return contact.value?.hasPresence() ?: false - } } diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index 623cc1be9..ec6be7aea 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -35,7 +35,6 @@ import androidx.core.app.Person import androidx.core.graphics.drawable.IconCompat import androidx.lifecycle.MutableLiveData import java.io.IOException -import kotlinx.coroutines.* import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R @@ -378,7 +377,7 @@ fun Friend.getContactForPhoneNumberOrAddress(value: String): String? { return null } -fun Friend.hasPresence(): Boolean { +fun Friend.hasLongTermPresence(): Boolean { for (address in addresses) { val presenceModel = getPresenceModelForUriOrTel(address.asStringUriOnly()) if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true diff --git a/app/src/main/res/layout/contact_list_cell.xml b/app/src/main/res/layout/contact_list_cell.xml index 302dc6586..731a4afa5 100644 --- a/app/src/main/res/layout/contact_list_cell.xml +++ b/app/src/main/res/layout/contact_list_cell.xml @@ -72,7 +72,7 @@ android:src="@drawable/linphone_logo_tinted" android:layout_marginRight="10dp" android:contentDescription="@string/content_description_linphone_user" - android:visibility="@{viewModel.hasPresence() ? View.VISIBLE : View.GONE}" /> + android:visibility="@{viewModel.hasLongTermPresence ? View.VISIBLE : View.GONE, default=gone}" /> Date: Tue, 23 May 2023 13:53:20 +0200 Subject: [PATCH 32/94] Fixed chat message attachment when failing to get video preview picture to display --- CHANGELOG.md | 1 + .../org/linphone/utils/DataBindingUtils.kt | 20 ++++- .../layout/chat_message_attachment_cell.xml | 75 ++++++++++--------- .../chat_message_reply_content_cell.xml | 19 +++-- ...hat_message_reply_preview_content_cell.xml | 26 +++---- .../chat_message_video_content_cell.xml | 29 ++++--- app/src/main/res/layout/video_play_button.xml | 9 +++ 7 files changed, 105 insertions(+), 74 deletions(-) create mode 100644 app/src/main/res/layout/video_play_button.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da6a127d..faa86ddf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Group changes to describe their impact on the project, as follows: ### Fixed - Messages not marked as reply in basic chat room if sending more than 1 content +- Chat message video attachment display when failing to get a preview picture ## [5.0.12] - 2023-05-23 diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 7fffb7b22..46d499e77 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -339,7 +339,7 @@ fun setImageViewScaleType(imageView: ImageView, scaleType: ImageView.ScaleType) @BindingAdapter("coilRounded") fun loadRoundImageWithCoil(imageView: ImageView, path: String?) { - if (path != null && path.isNotEmpty() && FileUtils.isExtensionImage(path)) { + if (!path.isNullOrEmpty() && FileUtils.isExtensionImage(path)) { imageView.load(path) { transformations(CircleCropTransformation()) } @@ -350,7 +350,7 @@ fun loadRoundImageWithCoil(imageView: ImageView, path: String?) { @BindingAdapter("coil") fun loadImageWithCoil(imageView: ImageView, path: String?) { - if (path != null && path.isNotEmpty() && FileUtils.isExtensionImage(path)) { + if (!path.isNullOrEmpty() && FileUtils.isExtensionImage(path)) { if (corePreferences.vfsEnabled && path.startsWith(corePreferences.vfsCachePath)) { imageView.load(path) { diskCachePolicy(CachePolicy.DISABLED) @@ -547,9 +547,23 @@ fun loadAvatarWithCoil(imageView: ImageView, path: String?) { @BindingAdapter("coilVideoPreview") fun loadVideoPreview(imageView: ImageView, path: String?) { - if (path != null && path.isNotEmpty() && FileUtils.isExtensionVideo(path)) { + if (!path.isNullOrEmpty() && FileUtils.isExtensionVideo(path)) { imageView.load(path) { videoFrameMillis(0) + listener( + onError = { _, result -> + Log.e( + "[Data Binding] [Coil] Error getting preview picture from video? [$path]: ${result.throwable}" + ) + }, + onSuccess = { _, _ -> + // Display "play" button above video preview + LayoutInflater.from(imageView.context).inflate( + R.layout.video_play_button, + imageView.parent as ViewGroup + ) + } + ) } } } diff --git a/app/src/main/res/layout/chat_message_attachment_cell.xml b/app/src/main/res/layout/chat_message_attachment_cell.xml index 0ae6f964e..e56fd6740 100644 --- a/app/src/main/res/layout/chat_message_attachment_cell.xml +++ b/app/src/main/res/layout/chat_message_attachment_cell.xml @@ -14,8 +14,15 @@ android:layout_margin="5dp" android:orientation="vertical"> + + + + - - - - - - - + android:textAlignment="center" + android:drawablePadding="5dp" + android:drawableTop="@{data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : @drawable/file), default=@drawable/file}" + android:visibility="@{data.image || data.video ? View.GONE : View.VISIBLE, default=gone}" + android:text="@{data.fileName, default=`test.txt`}"/> + + - - + + - - - + @@ -19,7 +20,22 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="@{inflatedVisibility}" - inflatedLifecycleOwner="@{true}"> + inflatedLifecycleOwner="@{true}" + android:background="?attr/backgroundColor"> + + - - \ No newline at end of file diff --git a/app/src/main/res/layout/video_play_button.xml b/app/src/main/res/layout/video_play_button.xml new file mode 100644 index 000000000..5688963d8 --- /dev/null +++ b/app/src/main/res/layout/video_play_button.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file From fc7a17d5e235989cd019b4adbb83c5427c1c0061 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 23 May 2023 16:37:28 +0200 Subject: [PATCH 33/94] Various improvements --- .../fragments/CountryPickerFragment.kt | 2 +- .../PhoneAccountValidationFragment.kt | 3 +- .../viewmodels/AbstractPhoneViewModel.kt | 1 - .../main/chat/data/ChatMessageContentData.kt | 9 +++--- .../chat/fragments/DetailChatRoomFragment.kt | 6 ++-- .../main/dialer/viewmodels/DialerViewModel.kt | 2 +- .../files/viewmodels/AudioFileViewModel.kt | 2 +- .../main/fragments/SecureFragment.kt | 2 +- .../viewmodels/AccountSettingsViewModel.kt | 2 +- .../viewmodels/AudioSettingsViewModel.kt | 4 +-- .../viewmodels/CallSettingsViewModel.kt | 6 ++-- .../viewmodels/ChatSettingsViewModel.kt | 2 +- .../viewmodels/ContactsSettingsViewModel.kt | 4 +-- .../viewmodels/NetworkSettingsViewModel.kt | 2 +- .../viewmodels/TunnelSettingsViewModel.kt | 4 +-- .../viewmodels/VideoSettingsViewModel.kt | 2 +- .../main/viewmodels/ListTopBarViewModel.kt | 2 +- .../voip/viewmodels/ControlsViewModel.kt | 2 +- .../compatibility/Api28Compatibility.kt | 32 +++++++++++++++++++ .../linphone/compatibility/Compatibility.kt | 7 ++++ .../linphone/contact/ContactDataInterface.kt | 2 +- .../org/linphone/contact/ContactsManager.kt | 10 +++--- .../org/linphone/utils/DataBindingUtils.kt | 2 +- .../java/org/linphone/utils/LinphoneUtils.kt | 4 +-- .../layout/assistant_country_picker_cell.xml | 3 +- .../layout/chat_message_attachment_cell.xml | 13 +++++--- ...message_downloadable_file_content_cell.xml | 9 ++++-- ...chat_message_generic_file_content_cell.xml | 9 ++++-- .../res/layout/chat_message_list_cell.xml | 3 +- .../layout/chat_room_creation_fragment.xml | 1 + .../layout/chat_room_devices_group_cell.xml | 6 ++-- .../chat_room_group_info_participant_cell.xml | 6 ++-- .../chat_room_imdn_participant_cell.xml | 6 ++-- .../main/res/layout/chat_room_list_cell.xml | 3 +- app/src/main/res/layout/chat_room_sending.xml | 1 + ..._scheduling_participants_list_fragment.xml | 1 + ...conference_scheduling_summary_fragment.xml | 2 ++ .../res/layout/contact_detail_fragment.xml | 3 +- app/src/main/res/layout/contact_list_cell.xml | 6 ++-- .../res/layout/contact_selection_cell.xml | 6 ++-- app/src/main/res/layout/empty_fragment.xml | 3 +- .../res/layout/history_detail_fragment.xml | 3 +- app/src/main/res/layout/history_list_cell.xml | 6 ++-- .../main/res/layout/recording_list_cell.xml | 1 + .../main/res/layout/side_menu_fragment.xml | 6 ++-- .../layout/voip_call_incoming_fragment.xml | 1 + app/src/main/res/values-cs/strings.xml | 6 ++-- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-zh-rCN/strings.xml | 13 ++------ app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/locales_config.xml | 1 + 52 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/org/linphone/compatibility/Api28Compatibility.kt diff --git a/app/src/main/java/org/linphone/activities/assistant/fragments/CountryPickerFragment.kt b/app/src/main/java/org/linphone/activities/assistant/fragments/CountryPickerFragment.kt index 9f7f10024..2e3d4dc72 100644 --- a/app/src/main/java/org/linphone/activities/assistant/fragments/CountryPickerFragment.kt +++ b/app/src/main/java/org/linphone/activities/assistant/fragments/CountryPickerFragment.kt @@ -29,7 +29,7 @@ import org.linphone.activities.assistant.adapters.CountryPickerAdapter import org.linphone.core.DialPlan import org.linphone.databinding.AssistantCountryPickerFragmentBinding -class CountryPickerFragment() : DialogFragment() { +class CountryPickerFragment : DialogFragment() { private var _binding: AssistantCountryPickerFragmentBinding? = null private val binding get() = _binding!! private lateinit var adapter: CountryPickerAdapter diff --git a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountValidationFragment.kt b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountValidationFragment.kt index 28732a224..edcf18210 100644 --- a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountValidationFragment.kt +++ b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountValidationFragment.kt @@ -34,6 +34,7 @@ import org.linphone.activities.assistant.viewmodels.PhoneAccountValidationViewMo import org.linphone.activities.assistant.viewmodels.SharedAssistantViewModel import org.linphone.activities.navigateToAccountSettings import org.linphone.activities.navigateToEchoCancellerCalibration +import org.linphone.compatibility.Compatibility import org.linphone.core.tools.Log import org.linphone.databinding.AssistantPhoneAccountValidationFragmentBinding @@ -113,7 +114,7 @@ class PhoneAccountValidationFragment : GenericFragment() val conferenceTime = MutableLiveData() val conferenceDuration = MutableLiveData() - var conferenceAddress = MutableLiveData() val showDuration = MutableLiveData() val isAlone: Boolean @@ -107,6 +106,8 @@ class ChatMessageContentData( stopVoiceRecording() } + private var conferenceAddress: String? = null + private fun getContent(): Content { return chatMessage.contents[contentIndex] } @@ -342,9 +343,9 @@ class ChatMessageContentData( val conferenceInfo = Factory.instance().createConferenceInfoFromIcalendarContent(content) val conferenceUri = conferenceInfo?.uri?.asStringUriOnly() if (conferenceInfo != null && conferenceUri != null) { - conferenceAddress.value = conferenceUri!! + conferenceAddress = conferenceUri!! Log.i( - "[Content] Created conference info from ICS with address ${conferenceAddress.value}" + "[Content] Created conference info from ICS with address $conferenceAddress" ) conferenceSubject.value = conferenceInfo.subject conferenceDescription.value = conferenceInfo.description @@ -407,7 +408,7 @@ class ChatMessageContentData( } fun callConferenceAddress() { - val address = conferenceAddress.value + val address = conferenceAddress if (address == null) { Log.e("[Content] Can't call null conference address!") return diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt index 45e0d1b02..060dc4413 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt @@ -469,7 +469,7 @@ class DetailChatRoomFragment : MasterFragment : GenericFragment() { override fun onResume() { if (isSecure) { - enableSecureMode(isSecure) + enableSecureMode(true) } else { // This is a workaround to prevent a small blink showing the previous secured screen lifecycleScope.launch { diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt index ca4d3904d..edbdffe06 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt @@ -289,7 +289,7 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel( account.params = params transportIndex.value = account.params.transport.toInt() } else { - Log.e("[Account Settings] Couldn't parse address: $address") + Log.e("[Account Settings] Couldn't parse address: $newValue") } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AudioSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AudioSettingsViewModel.kt index 192106b83..9e7bc11ce 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AudioSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AudioSettingsViewModel.kt @@ -141,7 +141,7 @@ class AudioSettingsViewModel : GenericSettingsViewModel() { override fun onTextValueChanged(newValue: String) { try { core.micGainDb = newValue.toFloat() - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } @@ -151,7 +151,7 @@ class AudioSettingsViewModel : GenericSettingsViewModel() { override fun onTextValueChanged(newValue: String) { try { core.playbackGainDb = newValue.toFloat() - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/CallSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/CallSettingsViewModel.kt index 42eab7990..45fb318f1 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/CallSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/CallSettingsViewModel.kt @@ -97,7 +97,7 @@ class CallSettingsViewModel : GenericSettingsViewModel() { Log.w("[Call Settings] Disabling Telecom Manager auto-enable") prefs.manuallyDisabledTelecomManager = true } - prefs.useTelecomManager = newValue + prefs.useTelecomManager = false } } } @@ -169,7 +169,7 @@ class CallSettingsViewModel : GenericSettingsViewModel() { override fun onTextValueChanged(newValue: String) { try { prefs.autoAnswerDelay = newValue.toInt() - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } @@ -179,7 +179,7 @@ class CallSettingsViewModel : GenericSettingsViewModel() { override fun onTextValueChanged(newValue: String) { try { core.incTimeout = newValue.toInt() - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ChatSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ChatSettingsViewModel.kt index e7a563ad0..d926b7b45 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ChatSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ChatSettingsViewModel.kt @@ -61,7 +61,7 @@ class ChatSettingsViewModel : GenericSettingsViewModel() { val maxSize = newValue.toInt() core.maxSizeForAutoDownloadIncomingFiles = maxSize updateAutoDownloadIndexFromMaxSize(maxSize) - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt index 0806ab461..68847e3fb 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/ContactsSettingsViewModel.kt @@ -77,12 +77,12 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() { override fun onBoolValueChanged(newValue: Boolean) { if (newValue) { if (PermissionHelper.get().hasWriteContactsPermission()) { - prefs.storePresenceInNativeContact = newValue + prefs.storePresenceInNativeContact = true } else { askWriteContactsPermissionForPresenceStorageEvent.value = Event(true) } } else { - prefs.storePresenceInNativeContact = newValue + prefs.storePresenceInNativeContact = false } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/NetworkSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/NetworkSettingsViewModel.kt index c282b006e..057997971 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/NetworkSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/NetworkSettingsViewModel.kt @@ -52,7 +52,7 @@ class NetworkSettingsViewModel : GenericSettingsViewModel() { try { val port = newValue.toInt() setTransportPort(port) - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/TunnelSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/TunnelSettingsViewModel.kt index 3822fe5fa..8bdcf2110 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/TunnelSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/TunnelSettingsViewModel.kt @@ -43,7 +43,7 @@ class TunnelSettingsViewModel : GenericSettingsViewModel() { val config = getTunnelConfig() config.port = newValue.toInt() updateTunnelConfig(config) - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } @@ -72,7 +72,7 @@ class TunnelSettingsViewModel : GenericSettingsViewModel() { val config = getTunnelConfig() config.port2 = newValue.toInt() updateTunnelConfig(config) - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt index 68278a2da..21ca33c22 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt @@ -106,7 +106,7 @@ class VideoSettingsViewModel : GenericSettingsViewModel() { try { core.downloadBandwidth = newValue.toInt() core.uploadBandwidth = newValue.toInt() - } catch (nfe: NumberFormatException) { + } catch (_: NumberFormatException) { } } } diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/ListTopBarViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/ListTopBarViewModel.kt index c8980f75d..0c0ffc090 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/ListTopBarViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/ListTopBarViewModel.kt @@ -63,7 +63,7 @@ class ListTopBarViewModel : ViewModel() { val list = arrayListOf() selectedItems.value = list - isSelectionNotEmpty.value = list.isNotEmpty() + isSelectionNotEmpty.value = false } fun onToggleSelect(position: Int) { diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt index 13b0f999c..f3d1cc9fd 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt @@ -536,7 +536,7 @@ class ControlsViewModel : ViewModel() { isVideoEnabled.value = enabled showTakeSnapshotButton.value = enabled && corePreferences.showScreenshotButton - var isVideoBeingSent = if (coreContext.core.currentCall?.conference != null) { + val isVideoBeingSent = if (coreContext.core.currentCall?.conference != null) { val videoDirection = coreContext.core.currentCall?.currentParams?.videoDirection videoDirection == MediaDirection.SendRecv || videoDirection == MediaDirection.SendOnly } else { diff --git a/app/src/main/java/org/linphone/compatibility/Api28Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api28Compatibility.kt new file mode 100644 index 000000000..cccd52d54 --- /dev/null +++ b/app/src/main/java/org/linphone/compatibility/Api28Compatibility.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.compatibility + +import android.annotation.TargetApi +import android.content.ClipboardManager + +@TargetApi(28) +class Api28Compatibility { + companion object { + fun clearClipboard(clipboard: ClipboardManager) { + clipboard.clearPrimaryClip() + } + } +} diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 846f0af4a..e7d940694 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -23,6 +23,7 @@ import android.app.Activity import android.app.Notification import android.app.PendingIntent import android.app.Service +import android.content.ClipboardManager import android.content.Context import android.content.Intent import android.graphics.Bitmap @@ -455,5 +456,11 @@ class Compatibility { } return false } + + fun clearClipboard(clipboard: ClipboardManager) { + if (Version.sdkAboveOrEqual(Version.API28_PIE_90)) { + Api28Compatibility.clearClipboard(clipboard) + } + } } } diff --git a/app/src/main/java/org/linphone/contact/ContactDataInterface.kt b/app/src/main/java/org/linphone/contact/ContactDataInterface.kt index fe4e1ac1b..2d346e305 100644 --- a/app/src/main/java/org/linphone/contact/ContactDataInterface.kt +++ b/app/src/main/java/org/linphone/contact/ContactDataInterface.kt @@ -88,7 +88,7 @@ abstract class GenericContactViewModel(private val sipAddress: Address) : Messag contactLookup() } - protected fun contactLookup() { + private fun contactLookup() { displayName.value = LinphoneUtils.getDisplayName(sipAddress) val friend = coreContext.contactsManager.findContactByAddress(sipAddress) if (friend != null) { diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index ec6be7aea..ecb27618c 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -410,10 +410,12 @@ fun Friend.getPictureUri(thumbnailPreferred: Boolean = false): Uri? { // Check that the URI points to a real file val contentResolver = coreContext.context.contentResolver try { - if (contentResolver.openAssetFileDescriptor(pictureUri, "r") != null) { + val fd = contentResolver.openAssetFileDescriptor(pictureUri, "r") + if (fd != null) { + fd.close() return pictureUri } - } catch (ioe: IOException) { } + } catch (_: IOException) { } } // Fallback to thumbnail if high res picture isn't available @@ -421,11 +423,11 @@ fun Friend.getPictureUri(thumbnailPreferred: Boolean = false): Uri? { lookupUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY ) - } catch (e: Exception) { } + } catch (_: Exception) { } } else if (photo != null) { try { return Uri.parse(photo) - } catch (e: Exception) { } + } catch (_: Exception) { } } return null } diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 46d499e77..74a58cdd0 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -598,7 +598,7 @@ fun addPrefixEditTextValidation(editText: EditText, enabled: Boolean) { @SuppressLint("SetTextI18n") override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - if (s == null || s.isEmpty() || !s.startsWith("+")) { + if (s.isNullOrEmpty() || !s.startsWith("+")) { editText.setText("+$s") } } diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 1d4f47857..47c095644 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -51,7 +51,7 @@ class LinphoneUtils { } val localDisplayName = account?.params?.identityAddress?.displayName // Do not return an empty local display name - if (localDisplayName != null && localDisplayName.isNotEmpty()) { + if (!localDisplayName.isNullOrEmpty()) { return localDisplayName } } @@ -179,7 +179,7 @@ class LinphoneUtils { fun deleteFilesAttachedToChatMessage(chatMessage: ChatMessage) { for (content in chatMessage.contents) { val filePath = content.filePath - if (filePath != null && filePath.isNotEmpty()) { + if (!filePath.isNullOrEmpty()) { Log.i("[Linphone Utils] Deleting file $filePath") FileUtils.deleteFile(filePath) } diff --git a/app/src/main/res/layout/assistant_country_picker_cell.xml b/app/src/main/res/layout/assistant_country_picker_cell.xml index 27a648efd..ccc3d74d9 100644 --- a/app/src/main/res/layout/assistant_country_picker_cell.xml +++ b/app/src/main/res/layout/assistant_country_picker_cell.xml @@ -4,8 +4,7 @@ android:layout_height="40dp" android:layout_gravity="center" android:orientation="horizontal" - android:padding="5dp" - android:background="?attr/backgroundColor"> + android:padding="5dp"> - + @@ -46,8 +48,8 @@ android:gravity="center" android:textAlignment="center" android:drawablePadding="5dp" - android:drawableTop="@drawable/file_video" - android:text="@{data.fileName, default=`test.mkv`}"/> + android:text="@{data.fileName, default=`test.mkv`}" + app:drawableTopCompat="@drawable/file_video" /> + android:text="@{data.fileName, default=`test.txt`}" + android:drawableTop="@{data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : @drawable/file), default=@drawable/file}" + tools:ignore="UseCompatTextViewDrawableXml" /> - + @@ -29,7 +31,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" - android:drawableTop="@{data.video ? @drawable/file_video : (data.image ? @drawable/file_picture : (data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : (data.voiceRecording ? @drawable/audio_recording_reply_preview_default : @drawable/file)))), default=@drawable/file}" android:drawablePadding="5dp" android:ellipsize="middle" android:gravity="center" @@ -37,7 +38,9 @@ android:onLongClick="@{longClickListener}" android:singleLine="true" android:text="@{data.fileName, default=`test.pdf`}" - android:textAlignment="center" /> + android:textAlignment="center" + android:drawableTop="@{data.video ? @drawable/file_video : (data.image ? @drawable/file_picture : (data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : (data.voiceRecording ? @drawable/audio_recording_reply_preview_default : @drawable/file)))), default=@drawable/file}" + tools:ignore="UseCompatTextViewDrawableXml" /> - + @@ -29,7 +31,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" - android:drawableTop="@{data.video ? @drawable/file_video : (data.image ? @drawable/file_picture : (data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : (data.voiceRecording ? @drawable/audio_recording_reply_preview_default : @drawable/file)))), default=@drawable/file}" android:drawablePadding="5dp" android:ellipsize="middle" android:gravity="center" @@ -37,7 +38,9 @@ android:onLongClick="@{longClickListener}" android:singleLine="true" android:text="@{data.fileName, default=`test.pdf`}" - android:textAlignment="center" /> + android:textAlignment="center" + android:drawableTop="@{data.video ? @drawable/file_video : (data.image ? @drawable/file_picture : (data.pdf ? @drawable/file_pdf : (data.audio ? @drawable/file_audio : (data.voiceRecording ? @drawable/audio_recording_reply_preview_default : @drawable/file)))), default=@drawable/file}" + tools:ignore="UseCompatTextViewDrawableXml" /> diff --git a/app/src/main/res/layout/chat_message_list_cell.xml b/app/src/main/res/layout/chat_message_list_cell.xml index 71b7d4b89..1892c571a 100644 --- a/app/src/main/res/layout/chat_message_list_cell.xml +++ b/app/src/main/res/layout/chat_message_list_cell.xml @@ -85,7 +85,8 @@ android:background="@drawable/led_background" android:padding="2dp" app:presenceIcon="@{data.presenceStatus}" - android:visibility="@{data.chatMessage.outgoing || selectionListViewModel.isEditionEnabled || data.hideAvatar || data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{data.chatMessage.outgoing || selectionListViewModel.isEditionEnabled || data.hideAvatar || data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -49,7 +50,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{data.presenceStatus}" - android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -50,7 +51,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" - app:presenceIcon="@{data.presenceStatus}" /> + app:presenceIcon="@{data.presenceStatus}" + tools:ignore="ContentDescription" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -37,7 +38,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{data.presenceStatus}" - android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> + app:layout_constraintBottom_toBottomOf="@id/avatar" + tools:ignore="ContentDescription"/> diff --git a/app/src/main/res/layout/conference_scheduling_summary_fragment.xml b/app/src/main/res/layout/conference_scheduling_summary_fragment.xml index 3a62d3abf..2e6fc3da4 100644 --- a/app/src/main/res/layout/conference_scheduling_summary_fragment.xml +++ b/app/src/main/res/layout/conference_scheduling_summary_fragment.xml @@ -102,6 +102,7 @@ android:layout_marginTop="5dp" android:layout_marginStart="5dp" android:layout_marginEnd="5dp" + android:inputType="textEmailSubject" style="@style/conference_scheduling_font" android:background="?attr/voipFormDisabledFieldBackgroundColor" android:text="@{viewModel.subject}" @@ -252,6 +253,7 @@ android:gravity="top" android:minLines="3" android:maxLines="5" + android:inputType="textMultiLine" style="@style/conference_scheduling_font" android:background="?attr/voipFormDisabledFieldBackgroundColor" android:hint="@string/conference_schedule_description_hint" diff --git a/app/src/main/res/layout/contact_detail_fragment.xml b/app/src/main/res/layout/contact_detail_fragment.xml index 002a24103..fe3f75ee4 100644 --- a/app/src/main/res/layout/contact_detail_fragment.xml +++ b/app/src/main/res/layout/contact_detail_fragment.xml @@ -105,7 +105,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_big_badge_padding" app:presenceIcon="@{viewModel.presenceStatus}" - android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/contact_list_cell.xml b/app/src/main/res/layout/contact_list_cell.xml index 731a4afa5..33cb88757 100644 --- a/app/src/main/res/layout/contact_list_cell.xml +++ b/app/src/main/res/layout/contact_list_cell.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -54,7 +55,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{viewModel.presenceStatus}" - android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -52,7 +53,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{data.presenceStatus}" - android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{data.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> + android:layout_height="match_parent"> \ No newline at end of file diff --git a/app/src/main/res/layout/history_detail_fragment.xml b/app/src/main/res/layout/history_detail_fragment.xml index 280854a97..ff74d4bcb 100644 --- a/app/src/main/res/layout/history_detail_fragment.xml +++ b/app/src/main/res/layout/history_detail_fragment.xml @@ -107,7 +107,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_big_badge_padding" app:presenceIcon="@{viewModel.presenceStatus}" - android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + bind:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/history_list_cell.xml b/app/src/main/res/layout/history_list_cell.xml index d25b0318b..fef2934ac 100644 --- a/app/src/main/res/layout/history_list_cell.xml +++ b/app/src/main/res/layout/history_list_cell.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -103,7 +104,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{viewModel.presenceStatus}" - android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/side_menu_fragment.xml b/app/src/main/res/layout/side_menu_fragment.xml index 528031725..ead22be46 100644 --- a/app/src/main/res/layout/side_menu_fragment.xml +++ b/app/src/main/res/layout/side_menu_fragment.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -81,7 +82,8 @@ android:background="@drawable/led_background" android:padding="@dimen/contact_presence_badge_padding" app:presenceIcon="@{viewModel.presenceStatus}" - android:visibility="@{!viewModel.defaultAccountFound || viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" /> + android:visibility="@{!viewModel.defaultAccountFound || viewModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE, default=gone}" + tools:ignore="ContentDescription" /> ]> - + Kopírovat adresu schůzky Okamžité zahájení volání Volání se spustí automaticky, pokud je spuštěno z jiné aplikace @@ -107,7 +107,7 @@ SIP adresa SIP adresy Zrušit - + den dny dní @@ -670,7 +670,7 @@ Zakázáno 1 hodina 1 týden - + %s píše… %s píší… %s píše… diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 40f6a45c0..0bda6c139 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -788,4 +788,5 @@ Authentification requise La connexion a échouée car l\'authentification est manquante ou invalide pour le compte\n%s.\n\nVous pouvez fournir le mot de passe à nouveau ou vérifier la configuration de votre compte dans les paramètres. Confirmer + Change la visibilité du selectionneur d\'emoji \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1da9bf070..fdb67c706 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -2,7 +2,7 @@ ]> - + 传输 UDP 用户数据报协议 TLS安全传输层协议 @@ -351,9 +351,6 @@ 写入联系人权限被拒绝,无法编辑联系人 您要删除这个联系人吗?\n它也将会从您的设备通讯录中删除 您确定要删除这些联系人吗?\n他们将会从您的设备通讯录中删除 - - \@string/history_delete_one_dialog - 选择保存联系人的位置 本地存储 输入电话号码或地址 @@ -503,17 +500,11 @@ 是否要在此聊天室转发信息? 短暂信息 群组创建失败 - - \@string/chat_room_delete_one_dialog - 对方要求启用视讯 \n如果将您的帐户关联您的电话号码,您的朋友们可以更容易的找到你。\n\n您在通讯录里可以查看谁在使用&appName;,他们也同样可以通过&appName;联系您。\n 请输入您的用户名与密码和您的SIP域名 您的帐户已经创建。请检查邮件以驗證您的帐户: 接收视频分辨率: - - \@string/contact_delete_one_dialog - 撤消通知后标记为已读 发送日志 重启日志 @@ -549,7 +540,7 @@ 信息 按住按钮录制语音信息 您的媒体音量很低,您可能需要提高音量 - + %1$d 未读消息 %1$d 未读消息 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d3492c188..a0366f19d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -541,7 +541,6 @@ 滑動到畫面底部或第一則未讀訊息 複製會議地址 切換顯示會議詳細資訊 - 您已開啟「閱後即焚」訊息 總是在此程式中開啟 還是可以匯出到第三方應用程式 自動下載收到的錄音檔 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9637f0a94..4cea5f544 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -920,4 +920,5 @@ User is online User is offline User is asking not to be disturbed + Toggle emoji picker visibility diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml index 01b6e9ff2..7f67f3994 100644 --- a/app/src/main/res/xml/locales_config.xml +++ b/app/src/main/res/xml/locales_config.xml @@ -11,6 +11,7 @@ + From 855f8c11c124e29b105691c11b287290efb398b0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 May 2023 10:46:00 +0200 Subject: [PATCH 34/94] Bumped dependencies --- app/build.gradle | 8 +++++--- build.gradle | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f2f0e860a..dabe70785 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -200,13 +200,15 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.core:core-splashscreen:1.0.1' - implementation 'androidx.emoji2:emoji2:1.4.0-beta03' - implementation 'androidx.emoji2:emoji2-emojipicker:1.4.0-beta03' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.media:media:1.6.0' implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06" implementation "androidx.window:window:1.0.0" + def emoji_version = "1.4.0-beta04" + implementation "androidx.emoji2:emoji2:$emoji_version" + implementation "androidx.emoji2:emoji2-emojipicker:$emoji_version" + def nav_version = "2.5.3" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" @@ -223,7 +225,7 @@ dependencies { implementation 'com.google.android.flexbox:flexbox:3.0.0' // https://github.com/coil-kt/coil/blob/main/LICENSE.txt Apache v2.0 - def coil_version = "2.3.0" + def coil_version = "2.4.0" implementation("io.coil-kt:coil:$coil_version") implementation("io.coil-kt:coil-gif:$coil_version") implementation("io.coil-kt:coil-svg:$coil_version") diff --git a/build.gradle b/build.gradle index c7c72fda8..a85419a92 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } // for com.github.chrisbanes:PhotoView } dependencies { - classpath 'com.android.tools.build:gradle:8.0.1' + classpath 'com.android.tools.build:gradle:8.0.2' classpath 'com.google.gms:google-services:4.3.15' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5' From 83dc8a7b13a70643648ab1eabe6d4571419f57ff Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 May 2023 11:10:24 +0200 Subject: [PATCH 35/94] Improved MIME type related code --- .../chat/data/ChatMessageAttachmentData.kt | 9 +-- .../main/chat/data/ChatMessageContentData.kt | 59 +++++++++++-------- .../chat/fragments/DetailChatRoomFragment.kt | 31 +++++----- .../main/files/fragments/TopBarFragment.kt | 8 +-- .../java/org/linphone/core/CoreContext.kt | 8 +-- .../org/linphone/utils/DataBindingUtils.kt | 2 +- .../main/java/org/linphone/utils/FileUtils.kt | 45 +++++++------- 7 files changed, 84 insertions(+), 78 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageAttachmentData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageAttachmentData.kt index caa0a4f5c..fc66b68a5 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageAttachmentData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageAttachmentData.kt @@ -35,10 +35,11 @@ class ChatMessageAttachmentData( init { val extension = FileUtils.getExtensionFromFileName(path) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - isImage = FileUtils.isMimeImage(mime) - isVideo = FileUtils.isMimeVideo(mime) - isAudio = FileUtils.isMimeAudio(mime) - isPdf = FileUtils.isMimePdf(mime) + val mimeType = FileUtils.getMimeType(mime) + isImage = mimeType == FileUtils.MimeType.Image + isVideo = mimeType == FileUtils.MimeType.Video + isAudio = mimeType == FileUtils.MimeType.Audio + isPdf = mimeType == FileUtils.MimeType.Pdf } fun delete() { diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt index eb028b38a..6428c7706 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt @@ -275,18 +275,26 @@ class ChatMessageContentData( filePath.value = path val extension = FileUtils.getExtensionFromFileName(path) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - isImage.value = FileUtils.isMimeImage(mime) - isVideo.value = FileUtils.isMimeVideo(mime) && !isVoiceRecord - isAudio.value = FileUtils.isMimeAudio(mime) && !isVoiceRecord - isPdf.value = FileUtils.isMimePdf(mime) - val type = when { - isImage.value == true -> "image" - isVideo.value == true -> "video" - isAudio.value == true -> "audio" - isPdf.value == true -> "pdf" - isVoiceRecord -> "voice recording" - isConferenceIcs -> "conference invitation" - else -> "unknown" + val type = when (FileUtils.getMimeType(mime)) { + FileUtils.MimeType.Image -> { + isImage.value = true + "image" + } + FileUtils.MimeType.Video -> { + isVideo.value = !isVoiceRecord + if (isVoiceRecord) "voice recording" else "video" + } + FileUtils.MimeType.Audio -> { + isAudio.value = !isVoiceRecord + if (isVoiceRecord) "voice recording" else "audio" + } + FileUtils.MimeType.Pdf -> { + isPdf.value = true + "pdf" + } + else -> { + if (isConferenceIcs) "conference invitation" else "unknown" + } } Log.i( "[Content] Extension for file [$path] is [$extension], deduced type from MIME is [$type]" @@ -311,23 +319,26 @@ class ChatMessageContentData( Log.w( "[Content] Found ${if (content.isFile) "file" else "file transfer"} content with empty path..." ) - isImage.value = false - isVideo.value = false - isAudio.value = false - isPdf.value = false - isVoiceRecording.value = false - isConferenceSchedule.value = false } } else if (content.isFileTransfer) { downloadable.value = true val extension = FileUtils.getExtensionFromFileName(fileName.value!!) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - isImage.value = FileUtils.isMimeImage(mime) - isVideo.value = FileUtils.isMimeVideo(mime) - isAudio.value = FileUtils.isMimeAudio(mime) - isPdf.value = FileUtils.isMimePdf(mime) - isVoiceRecording.value = false - isConferenceSchedule.value = false + when (FileUtils.getMimeType(mime)) { + FileUtils.MimeType.Image -> { + isImage.value = true + } + FileUtils.MimeType.Video -> { + isVideo.value = true + } + FileUtils.MimeType.Audio -> { + isAudio.value = true + } + FileUtils.MimeType.Pdf -> { + isPdf.value = true + } + else -> {} + } } else if (content.isIcalendar) { Log.i("[Content] Found content with icalendar body") isConferenceSchedule.value = true diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt index 060dc4413..76269e963 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt @@ -478,8 +478,8 @@ class DetailChatRoomFragment : MasterFragment navigateToImageFileViewer( + when (FileUtils.getMimeType(mime)) { + FileUtils.MimeType.Image -> navigateToImageFileViewer( preventScreenshots ) - FileUtils.isMimeVideo(mime) -> navigateToVideoFileViewer( + FileUtils.MimeType.Video -> navigateToVideoFileViewer( preventScreenshots ) - FileUtils.isMimeAudio(mime) -> navigateToAudioFileViewer( + FileUtils.MimeType.Audio -> navigateToAudioFileViewer( preventScreenshots ) - FileUtils.isMimePdf(mime) -> navigateToPdfFileViewer( + FileUtils.MimeType.Pdf -> navigateToPdfFileViewer( preventScreenshots ) - FileUtils.isMimePlainText(mime) -> navigateToTextFileViewer( + FileUtils.MimeType.PlainText -> navigateToTextFileViewer( preventScreenshots ) else -> { @@ -584,9 +584,9 @@ class DetailChatRoomFragment : MasterFragment - var index = 0 - var retryCount = 0 - var expectedChildCount = 0 + var index: Int + var loadSteps = 0 + var expectedChildCount: Int do { val events = listViewModel.events.value.orEmpty() expectedChildCount = events.size @@ -600,18 +600,17 @@ class DetailChatRoomFragment : MasterFragment + binding.setVoiceRecordingTouchListener { _, event -> if (corePreferences.holdToRecordVoiceMessage) { when (event.action) { MotionEvent.ACTION_DOWN -> { diff --git a/app/src/main/java/org/linphone/activities/main/files/fragments/TopBarFragment.kt b/app/src/main/java/org/linphone/activities/main/files/fragments/TopBarFragment.kt index d636d194c..e956f4654 100644 --- a/app/src/main/java/org/linphone/activities/main/files/fragments/TopBarFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/files/fragments/TopBarFragment.kt @@ -92,8 +92,8 @@ class TopBarFragment : GenericFragment() { val extension = FileUtils.getExtensionFromFileName(filePath) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - when { - FileUtils.isMimeImage(mime) -> { + when (FileUtils.getMimeType(mime)) { + FileUtils.MimeType.Image -> { val export = lifecycleScope.async { Compatibility.addImageToMediaStore(requireContext(), content) } @@ -108,7 +108,7 @@ class TopBarFragment : GenericFragment() { ) } } - FileUtils.isMimeVideo(mime) -> { + FileUtils.MimeType.Video -> { val export = lifecycleScope.async { Compatibility.addVideoToMediaStore(requireContext(), content) } @@ -123,7 +123,7 @@ class TopBarFragment : GenericFragment() { ) } } - FileUtils.isMimeAudio(mime) -> { + FileUtils.MimeType.Audio -> { val export = lifecycleScope.async { Compatibility.addAudioToMediaStore(requireContext(), content) } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 4b38f1269..007c619b3 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -1048,8 +1048,8 @@ class CoreContext( val extension = FileUtils.getExtensionFromFileName(filePath) val mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - when { - FileUtils.isMimeImage(mime) -> { + when (FileUtils.getMimeType(mime)) { + FileUtils.MimeType.Image -> { if (Compatibility.addImageToMediaStore(context, content)) { Log.i( "[Context] Successfully exported image [${content.name}] to Media Store" @@ -1060,7 +1060,7 @@ class CoreContext( ) } } - FileUtils.isMimeVideo(mime) -> { + FileUtils.MimeType.Video -> { if (Compatibility.addVideoToMediaStore(context, content)) { Log.i( "[Context] Successfully exported video [${content.name}] to Media Store" @@ -1071,7 +1071,7 @@ class CoreContext( ) } } - FileUtils.isMimeAudio(mime) -> { + FileUtils.MimeType.Audio -> { if (Compatibility.addAudioToMediaStore(context, content)) { Log.i( "[Context] Successfully exported audio [${content.name}] to Media Store" diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 74a58cdd0..0708a9658 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -547,7 +547,7 @@ fun loadAvatarWithCoil(imageView: ImageView, path: String?) { @BindingAdapter("coilVideoPreview") fun loadVideoPreview(imageView: ImageView, path: String?) { - if (!path.isNullOrEmpty() && FileUtils.isExtensionVideo(path)) { + if (!path.isNullOrEmpty()) { imageView.load(path) { videoFrameMillis(0) listener( diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index f15260a19..1035ab6f9 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -42,6 +42,15 @@ import org.linphone.R import org.linphone.core.tools.Log class FileUtils { + enum class MimeType { + PlainText, + Pdf, + Image, + Video, + Audio, + Unknown + } + companion object { fun getNameFromFilePath(filePath: String): String { var name = filePath @@ -64,36 +73,22 @@ class FileUtils { return extension.lowercase(Locale.getDefault()) } - fun isMimePlainText(type: String?): Boolean { - return type?.startsWith("text/plain") ?: false - } - - fun isMimePdf(type: String?): Boolean { - return type?.startsWith("application/pdf") ?: false - } - - fun isMimeImage(type: String?): Boolean { - return type?.startsWith("image/") ?: false - } - - fun isMimeVideo(type: String?): Boolean { - return type?.startsWith("video/") ?: false - } - - fun isMimeAudio(type: String?): Boolean { - return type?.startsWith("audio/") ?: false + fun getMimeType(type: String?): MimeType { + if (type.isNullOrEmpty()) return MimeType.Unknown + return when { + type.startsWith("image/") -> MimeType.Image + type.startsWith("text/plain") -> MimeType.PlainText + type.startsWith("video/") -> MimeType.Video + type.startsWith("audio/") -> MimeType.Audio + type.startsWith("application/pdf") -> MimeType.Pdf + else -> MimeType.Unknown + } } fun isExtensionImage(path: String): Boolean { val extension = getExtensionFromFileName(path) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - return isMimeImage(type) - } - - fun isExtensionVideo(path: String): Boolean { - val extension = getExtensionFromFileName(path) - val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) - return isMimeVideo(type) + return getMimeType(type) == MimeType.Image } fun clearExistingPlainFiles() { From 29e85428039fcc09eb6deb3a4578f291230c3c4b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 May 2023 11:14:08 +0200 Subject: [PATCH 36/94] Fixed missing click listener on video file in chat message when preview failed --- .../res/layout/chat_message_generic_file_content_cell.xml | 4 ++-- app/src/main/res/layout/chat_message_image_content_cell.xml | 4 ++-- app/src/main/res/layout/chat_message_video_content_cell.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/layout/chat_message_generic_file_content_cell.xml b/app/src/main/res/layout/chat_message_generic_file_content_cell.xml index e52d2d9e6..5fc5951c9 100644 --- a/app/src/main/res/layout/chat_message_generic_file_content_cell.xml +++ b/app/src/main/res/layout/chat_message_generic_file_content_cell.xml @@ -17,6 +17,8 @@ Date: Mon, 5 Jun 2023 15:55:27 +0200 Subject: [PATCH 37/94] Prevent play button displayed above videos to be displayed above images as well --- app/src/main/java/org/linphone/utils/DataBindingUtils.kt | 2 +- app/src/main/java/org/linphone/utils/FileUtils.kt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 0708a9658..74a58cdd0 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -547,7 +547,7 @@ fun loadAvatarWithCoil(imageView: ImageView, path: String?) { @BindingAdapter("coilVideoPreview") fun loadVideoPreview(imageView: ImageView, path: String?) { - if (!path.isNullOrEmpty()) { + if (!path.isNullOrEmpty() && FileUtils.isExtensionVideo(path)) { imageView.load(path) { videoFrameMillis(0) listener( diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index 1035ab6f9..95c338d5f 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -91,6 +91,12 @@ class FileUtils { return getMimeType(type) == MimeType.Image } + fun isExtensionVideo(path: String): Boolean { + val extension = getExtensionFromFileName(path) + val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) + return getMimeType(type) == MimeType.Video + } + fun clearExistingPlainFiles() { val dir = File(corePreferences.vfsCachePath) if (dir.exists()) { From 8df1d2218dd676f31ea5c8f682883f27c95c6dad Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 6 Jun 2023 11:47:23 +0200 Subject: [PATCH 38/94] Fixed auth info requested dialog showing up after wrong password input in assistant + fixed default account not set in same scenario --- .../viewmodels/AccountLoginViewModel.kt | 13 ++++++++++-- .../viewmodels/GenericLoginViewModel.kt | 13 ++++++++++-- .../linphone/activities/main/MainActivity.kt | 21 ++++++++++++++++++- .../java/org/linphone/core/CoreContext.kt | 11 ---------- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt index 807ed80cc..8bca89dbb 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt @@ -161,10 +161,19 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM fun removeInvalidProxyConfig() { val account = accountToCheck account ?: return + + val core = coreContext.core val authInfo = account.findAuthInfo() - if (authInfo != null) coreContext.core.removeAuthInfo(authInfo) - coreContext.core.removeAccount(account) + if (authInfo != null) core.removeAuthInfo(authInfo) + core.removeAccount(account) accountToCheck = null + + // Make sure there is a valid default account + val accounts = core.accountList + if (accounts.isNotEmpty() && core.defaultAccount == null) { + core.defaultAccount = accounts.first() + core.refreshRegisters() + } } fun continueEvenIfInvalidCredentials() { diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt index 0a6c75014..153db0671 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt @@ -108,10 +108,19 @@ class GenericLoginViewModel(private val accountCreator: AccountCreator) : ViewMo fun removeInvalidProxyConfig() { val account = accountToCheck account ?: return + + val core = coreContext.core val authInfo = account.findAuthInfo() - if (authInfo != null) coreContext.core.removeAuthInfo(authInfo) - coreContext.core.removeAccount(account) + if (authInfo != null) core.removeAuthInfo(authInfo) + core.removeAccount(account) accountToCheck = null + + // Make sure there is a valid default account + val accounts = core.accountList + if (accounts.isNotEmpty() && core.defaultAccount == null) { + core.defaultAccount = accounts.first() + core.refreshRegisters() + } } fun continueEvenIfInvalidCredentials() { diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index c145e8a73..88049ae79 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -35,6 +35,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.doOnAttach import androidx.databinding.DataBindingUtil import androidx.fragment.app.FragmentContainerView +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController @@ -59,6 +60,9 @@ import org.linphone.activities.navigateToDialer import org.linphone.compatibility.Compatibility import org.linphone.contact.ContactsUpdatedListenerStub import org.linphone.core.AuthInfo +import org.linphone.core.AuthMethod +import org.linphone.core.Core +import org.linphone.core.CoreListenerStub import org.linphone.core.CorePreferences import org.linphone.core.tools.Log import org.linphone.databinding.MainActivityBinding @@ -109,6 +113,19 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin private var shouldTabsBeVisibleDependingOnDestination = true private var shouldTabsBeVisibleDueToOrientationAndKeyboard = true + private val authenticationRequestedEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + + private val coreListener: CoreListenerStub = object : CoreListenerStub() { + override fun onAuthenticationRequested(core: Core, authInfo: AuthInfo, method: AuthMethod) { + Log.w( + "[Main Activity] Authentication requested for account [${authInfo.username}@${authInfo.domain}] with realm [${authInfo.realm}] using method [$method]" + ) + authenticationRequestedEvent.value = Event(authInfo) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -144,7 +161,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin } } - coreContext.authenticationRequestedEvent.observe( + authenticationRequestedEvent.observe( this ) { it.consume { authInfo -> @@ -183,9 +200,11 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin override fun onResume() { super.onResume() coreContext.contactsManager.addListener(listener) + coreContext.core.addListener(coreListener) } override fun onPause() { + coreContext.core.removeListener(coreListener) coreContext.contactsManager.removeListener(listener) super.onPause() } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 007c619b3..00d1fc259 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -117,10 +117,6 @@ class CoreContext( MutableLiveData>() } - val authenticationRequestedEvent: MutableLiveData> by lazy { - MutableLiveData>() - } - val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private val loggingService = Factory.instance().loggingService @@ -169,13 +165,6 @@ class CoreContext( } } - override fun onAuthenticationRequested(core: Core, authInfo: AuthInfo, method: AuthMethod) { - Log.w( - "[Context] Authentication requested for account [${authInfo.username}@${authInfo.domain}] with realm [${authInfo.realm}] using method [$method]" - ) - authenticationRequestedEvent.value = Event(authInfo) - } - override fun onPushNotificationReceived(core: Core, payload: String?) { Log.i("[Context] Push notification received: $payload") } From b0cd5524dddf56fa2893cab92d9f85a9c5bc76a0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 7 Jun 2023 10:18:32 +0200 Subject: [PATCH 39/94] Prevent null auth info request dialog --- .../main/java/org/linphone/activities/main/MainActivity.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index 88049ae79..af0786b48 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -119,6 +119,10 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin private val coreListener: CoreListenerStub = object : CoreListenerStub() { override fun onAuthenticationRequested(core: Core, authInfo: AuthInfo, method: AuthMethod) { + if (authInfo.username == null || authInfo.domain == null || authInfo.realm == null) { + return + } + Log.w( "[Main Activity] Authentication requested for account [${authInfo.username}@${authInfo.domain}] with realm [${authInfo.realm}] using method [$method]" ) From 3d5fdb66d03606bed89f2e4a7eddcd26cc547c79 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 25 May 2023 06:23:59 +0000 Subject: [PATCH 40/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 99.8% (802 of 803 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a0366f19d..9444a7065 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -803,4 +803,6 @@ \n \n您可以再次輸入密碼,或是到設定畫面中確認帳號設定。 確認 + 您開啟了「閱後即焚」訊息:%s + 切換顯示表情符號選取器 \ No newline at end of file From 49992690a0964ab06182ce56458e21c9826826a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Sun, 28 May 2023 21:46:40 +0000 Subject: [PATCH 41/94] Translated using Weblate (Czech) Currently translated at 99.8% (802 of 803 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/cs/ --- app/src/main/res/values-cs/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 7c4e37f6d..3c98c9bbe 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -799,4 +799,17 @@ Nerušit Pryč Softwarové potlačení ozvěny + Vytvoření účtu pomocí e-mailu: + Váš účet ještě nebyl aktivován, klikněte prosím na odkaz, který jste obdrželi e-mailem + Vypnout bundle režim + Zdá se, že vaše zařízení nemůže přijímat push notifikace. +\n +\nProtože je nyní vyžadujeme pro vytvoření účtu, nebudete si moci vytvořit účet v aplikaci, ale můžete si ho vytvořit na našich webových stránkách: + Připojení se nezdařilo, protože přihlašovací údaje chybí nebo jsou neplatné pro účet +\n%s. +\n +\nMůžete znovu zadat heslo nebo zkontrolovat konfiguraci účtu v nastavení. + Přepnutí viditelnosti nástroje pro výběr emoji + Vyžadováno ověření + Potvrdit \ No newline at end of file From 9294fa9b8e27f5104242da4c1ce669ccfd780500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Thu, 1 Jun 2023 11:59:54 +0000 Subject: [PATCH 42/94] Translated using Weblate (Czech) Currently translated at 100.0% (803 of 803 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/cs/ --- app/src/main/res/values-cs/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 3c98c9bbe..181f172a0 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -812,4 +812,5 @@ Přepnutí viditelnosti nástroje pro výběr emoji Vyžadováno ověření Potvrdit + " " \ No newline at end of file From f6938eba524dea20469c7c959aff849e77c3833e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 7 Jun 2023 10:37:14 +0200 Subject: [PATCH 43/94] Removed empty string --- app/src/main/res/layout/settings_account_fragment.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 4 files changed, 4 deletions(-) diff --git a/app/src/main/res/layout/settings_account_fragment.xml b/app/src/main/res/layout/settings_account_fragment.xml index 44a9c6173..7ede66f9d 100644 --- a/app/src/main/res/layout/settings_account_fragment.xml +++ b/app/src/main/res/layout/settings_account_fragment.xml @@ -262,7 +262,6 @@ diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 181f172a0..3c98c9bbe 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -812,5 +812,4 @@ Přepnutí viditelnosti nástroje pro výběr emoji Vyžadováno ověření Potvrdit - " " \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0bda6c139..44b1da943 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -781,7 +781,6 @@ Valider Le mot de passe est invalide ! Désactiver le mode bundle - Pour créer un compte avec votre email : Votre périphérique ne semble pas supporter les notifications \'push\'.\n\nVous ne pourrez donc pas créer des comptes dans l\'application mais vous pouvez toujours le faire sur notre site internet : Votre compte n\'est pas activé, veuillez cliquer sur le lien que vous avez reçu par courriel diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4cea5f544..b8ecdf5d9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -723,7 +723,6 @@ Your account will only be deleted locally.\nTo delete it permanently, go on your SIP provider website. Your account will only be deleted locally.\nTo delete it permanently, go to our account management platform: Disable bundle mode - Default layout From a19264a2bd6bbbcbfb33e426e5b845a8409388e0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Jun 2023 11:38:21 +0200 Subject: [PATCH 44/94] Bumped dependencies & targetting Android 14 (API level 34) --- app/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index dabe70785..33042a009 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,10 +83,10 @@ android { targetCompatibility = 17 } - compileSdkVersion 33 + compileSdkVersion 34 defaultConfig { minSdkVersion 23 - targetSdkVersion 33 + targetSdkVersion 34 versionCode appVersionCode versionName "${project.version}" applicationId getPackageName() @@ -203,13 +203,13 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.media:media:1.6.0' implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06" - implementation "androidx.window:window:1.0.0" + implementation "androidx.window:window:1.1.0" - def emoji_version = "1.4.0-beta04" + def emoji_version = "1.4.0-beta05" implementation "androidx.emoji2:emoji2:$emoji_version" implementation "androidx.emoji2:emoji2-emojipicker:$emoji_version" - def nav_version = "2.5.3" + def nav_version = "2.6.0" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" From 4e396e990d698ac5d6186acab24c42b813711821 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Jun 2023 13:12:15 +0200 Subject: [PATCH 45/94] Added compat methods to check & request full screen intent permission + other required changes for Android 14 --- app/src/main/AndroidManifest.xml | 5 ++ .../main/dialer/fragments/DialerFragment.kt | 18 +++++++ .../compatibility/Api34Compatibility.kt | 48 +++++++++++++++++++ .../linphone/compatibility/Compatibility.kt | 15 ++++++ app/src/main/res/values-fr/strings.xml | 2 + app/src/main/res/values/strings.xml | 3 ++ 6 files changed, 91 insertions(+) create mode 100644 app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ec17de66..951efadc0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -54,6 +54,11 @@ + + + + () { // Don't check the following the previous permissions are being asked checkTelecomManagerPermissions() } + + // See https://developer.android.com/about/versions/14/behavior-changes-14#fgs-types + if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { + val fullScreenIntentPermission = Compatibility.hasFullScreenIntentPermission( + requireContext() + ) + Log.i( + "[Dialer] Android 14 or above detected: full-screen intent permission is ${if (fullScreenIntentPermission) "granted" else "not granted"}" + ) + if (!fullScreenIntentPermission) { + (requireActivity() as MainActivity).showSnackBar( + R.string.android_14_full_screen_intent_permission_not_granted, + R.string.android_14_go_to_full_screen_intent_permission_setting + ) { + Compatibility.requestFullScreenIntentPermission(requireContext()) + } + } + } } @TargetApi(Version.API26_O_80) diff --git a/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt new file mode 100644 index 000000000..b325806a5 --- /dev/null +++ b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.compatibility + +import android.annotation.TargetApi +import android.app.NotificationManager +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.provider.Settings +import androidx.core.content.ContextCompat + +@TargetApi(34) +class Api34Compatibility { + companion object { + fun hasFullScreenIntentPermission(context: Context): Boolean { + val notificationManager = context.getSystemService(NotificationManager::class.java) as NotificationManager + // See https://developer.android.com/reference/android/app/NotificationManager#canUseFullScreenIntent%28%29 + return notificationManager.canUseFullScreenIntent() + } + + fun requestFullScreenIntentPermission(context: Context) { + val intent = Intent() + // See https://developer.android.com/reference/android/provider/Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT + intent.action = Settings.ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) + ContextCompat.startActivity(context, intent, null) + } + } +} diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index e7d940694..cab4ff7cf 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -462,5 +462,20 @@ class Compatibility { Api28Compatibility.clearClipboard(clipboard) } } + + fun hasFullScreenIntentPermission(context: Context): Boolean { + if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { + return Api34Compatibility.hasFullScreenIntentPermission(context) + } + return true + } + + fun requestFullScreenIntentPermission(context: Context): Boolean { + if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { + Api34Compatibility.requestFullScreenIntentPermission(context) + return true + } + return false + } } } diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 44b1da943..5313d2021 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -788,4 +788,6 @@ La connexion a échouée car l\'authentification est manquante ou invalide pour le compte\n%s.\n\nVous pouvez fournir le mot de passe à nouveau ou vérifier la configuration de votre compte dans les paramètres. Confirmer Change la visibilité du selectionneur d\'emoji + Permission requise pour afficher les appels entrant non accordée + Afficher \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b8ecdf5d9..5958d297f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -777,6 +777,9 @@ Connection failed because authentication is missing or invalid for account \n%s.\n\nYou can provide password again, or check your account configuration in the settings. Confirm + Permission required to show incoming calls not granted yet + Show + Add a SIP address field Add a phone number field From 32f4307674e889f07f517a34a906b0aed8711845 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Jun 2023 09:39:24 +0200 Subject: [PATCH 46/94] Using new PushService added in SDK --- app/src/main/AndroidManifest.xml | 8 ++++++++ .../org/linphone/notifications/NotificationsManager.kt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 951efadc0..9b1f7e6fc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,6 +59,7 @@ + + + diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index a265cb475..abc1e17c6 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -84,7 +84,7 @@ class NotificationsManager(private val context: Context) { const val INTENT_REMOTE_ADDRESS = "REMOTE_ADDRESS" private const val SERVICE_NOTIF_ID = 1 - private const val MISSED_CALLS_NOTIF_ID = 2 + private const val MISSED_CALLS_NOTIF_ID = 10 const val CHAT_TAG = "Chat" private const val MISSED_CALL_TAG = "Missed call" From 463ade0ade9f17b8622f89db2f59ec7c7e2d2ef7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 13 Jun 2023 10:06:47 +0200 Subject: [PATCH 47/94] Reset FPS & bandwidth limits when switching video profile from custom to another one --- .../settings/viewmodels/VideoSettingsViewModel.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt index 21ca33c22..db1db30ed 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/VideoSettingsViewModel.kt @@ -87,7 +87,17 @@ class VideoSettingsViewModel : GenericSettingsViewModel() { val videoPresetListener = object : SettingListenerStub() { override fun onListValueChanged(position: Int) { videoPresetIndex.value = position // Needed to display/hide two below settings - core.videoPreset = videoPresetLabels.value.orEmpty()[position] + val currentPreset = core.videoPreset + val newPreset = videoPresetLabels.value.orEmpty()[position] + if (newPreset != currentPreset) { + if (currentPreset == "custom") { + // Not "custom" anymore, reset FPS & bandwidth + core.preferredFramerate = 0f + core.downloadBandwidth = 0 + core.uploadBandwidth = 0 + } + core.videoPreset = newPreset + } } } val videoPresetIndex = MutableLiveData() From 7519c69de19609c2d934368ed1f137eb5e23433b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 15 Jun 2023 10:28:17 +0200 Subject: [PATCH 48/94] Fixed issue where we could return on conference waiting room after hanging up a conference call --- .../main/java/org/linphone/activities/GenericFragment.kt | 7 +++++-- .../viewmodels/ConferenceWaitingRoomViewModel.kt | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/GenericFragment.kt b/app/src/main/java/org/linphone/activities/GenericFragment.kt index 0d1f89fc0..ab8db20ef 100644 --- a/app/src/main/java/org/linphone/activities/GenericFragment.kt +++ b/app/src/main/java/org/linphone/activities/GenericFragment.kt @@ -83,7 +83,9 @@ abstract class GenericFragment : Fragment() { } } } catch (ise: IllegalStateException) { - Log.e("[Generic Fragment] ${getFragmentRealClassName()} Can't go back: $ise") + Log.e( + "[Generic Fragment] ${getFragmentRealClassName()}.handleOnBackPressed() Can't go back: $ise" + ) } } } @@ -137,7 +139,8 @@ abstract class GenericFragment : Fragment() { try { requireActivity().onBackPressedDispatcher.onBackPressed() } catch (ise: IllegalStateException) { - Log.e("[Generic Fragment] ${getFragmentRealClassName()} can't go back: $ise") + Log.w("[Generic Fragment] ${getFragmentRealClassName()}.goBack() can't go back: $ise") + onBackPressedCallback.handleOnBackPressed() } } diff --git a/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceWaitingRoomViewModel.kt b/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceWaitingRoomViewModel.kt index d1bf3de75..478329d8a 100644 --- a/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceWaitingRoomViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceWaitingRoomViewModel.kt @@ -398,13 +398,15 @@ class ConferenceWaitingRoomViewModel : MessageNotifierViewModel() { private fun onAudioDevicesListUpdated() { val bluetoothDeviceAvailable = AudioRouteUtils.isBluetoothAudioRouteAvailable() + if (!bluetoothDeviceAvailable && audioRoutesEnabled.value == true) { + Log.w( + "[Conference Waiting Room] Bluetooth device no longer available, switching back to default microphone & earpiece/speaker" + ) + } audioRoutesEnabled.value = bluetoothDeviceAvailable if (!bluetoothDeviceAvailable) { audioRoutesSelected.value = false - Log.w( - "[Conference Waiting Room] Bluetooth device no longer available, switching back to default microphone & earpiece/speaker" - ) if (isBluetoothHeadsetSelected.value == true) { for (audioDevice in coreContext.core.audioDevices) { if (isVideoEnabled.value == true) { From 747f5288b80d09959cf496cc0fbfaa067f3d460b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 15 Jun 2023 10:37:12 +0200 Subject: [PATCH 49/94] Fixed camera switch button visible in PiP --- .../org/linphone/compatibility/Api31Compatibility.kt | 4 ++++ app/src/main/res/layout/voip_single_call_fragment.xml | 10 ++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt index f225df602..457e3c60e 100644 --- a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt @@ -262,6 +262,8 @@ class Api31Compatibility { context.startForegroundService(intent) } catch (fssnae: ForegroundServiceStartNotAllowedException) { Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") + } catch (se: SecurityException) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $se") } } @@ -270,6 +272,8 @@ class Api31Compatibility { service.startForeground(notifId, notif) } catch (fssnae: ForegroundServiceStartNotAllowedException) { Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") + } catch (se: SecurityException) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $se") } } diff --git a/app/src/main/res/layout/voip_single_call_fragment.xml b/app/src/main/res/layout/voip_single_call_fragment.xml index 54aa2252e..7b088e11e 100644 --- a/app/src/main/res/layout/voip_single_call_fragment.xml +++ b/app/src/main/res/layout/voip_single_call_fragment.xml @@ -222,18 +222,12 @@ app:layout_constraintEnd_toEndOf="@id/background" app:layout_constraintTop_toTopOf="@id/background" /> - - From 53e9d92ea4d8708b4037ebab02333b5037d2cb23 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 15 Jun 2023 11:34:20 +0200 Subject: [PATCH 50/94] Hide emoji picker toggle from chat message sending bar when a non-emoji character has been typed --- .../viewmodels/ChatMessageSendingViewModel.kt | 4 +++ app/src/main/res/layout/chat_room_sending.xml | 25 +++---------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt index 2323d78f1..1c0c7d08c 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt @@ -174,6 +174,10 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel() fun onTextToSendChanged(value: String) { sendMessageEnabled.value = value.trim().isNotEmpty() || attachments.value?.isNotEmpty() == true || isPendingVoiceRecord.value == true + + val showEmojiPicker = value.isEmpty() || AppUtils.isTextOnlyContainingEmoji(value) + isEmojiPickerVisible.value = corePreferences.showEmojiPickerButton && showEmojiPicker + if (value.isNotEmpty()) { if (attachFileEnabled.value == true && !corePreferences.allowMultipleFilesAndTextInSameMessage) { attachFileEnabled.value = false diff --git a/app/src/main/res/layout/chat_room_sending.xml b/app/src/main/res/layout/chat_room_sending.xml index 72dc5d5b2..bd2893de8 100644 --- a/app/src/main/res/layout/chat_room_sending.xml +++ b/app/src/main/res/layout/chat_room_sending.xml @@ -125,7 +125,6 @@ android:layout_width="@dimen/chat_message_sending_icons_size" android:layout_height="0dp" android:layout_marginStart="@dimen/chat_message_sending_icons_margin" - android:layout_marginEnd="@dimen/chat_message_sending_icons_margin" android:contentDescription="@string/content_description_attach_file" android:enabled="@{chatSendingViewModel.attachFileEnabled && !chatSendingViewModel.attachFilePending}" android:onClick="@{attachFileClickListener}" @@ -142,7 +141,6 @@ android:layout_width="@dimen/chat_message_sending_icons_size" android:layout_height="0dp" android:layout_marginStart="@dimen/chat_message_sending_icons_margin" - android:layout_marginEnd="@dimen/chat_message_sending_icons_margin" android:contentDescription="@string/content_description_voice_recording" android:onClick="@{() -> chatSendingViewModel.toggleVoiceRecording()}" android:onTouch="@{voiceRecordingTouchListener}" @@ -162,6 +160,7 @@ android:layout_below="@id/emoji_picker" android:layout_gravity="center_vertical" android:layout_marginStart="@dimen/chat_message_sending_icons_margin" + android:layout_marginEnd="@{chatSendingViewModel.isEmojiPickerVisible ? @dimen/margin_0dp : @dimen/chat_message_sending_icons_margin}" android:layout_marginTop="10dp" android:layout_marginBottom="10dp" android:background="@color/header_background_color" @@ -174,37 +173,20 @@ android:textColor="@color/black_color" android:textCursorDrawable="@null" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/message_right_barrier" + app:layout_constraintEnd_toStartOf="@id/emoji_picker_toggle" app:layout_constraintStart_toEndOf="@id/voice_record" app:layout_constraintTop_toBottomOf="@id/emoji_picker" /> - - - - Date: Thu, 15 Jun 2023 15:52:37 +0200 Subject: [PATCH 51/94] Fixed keyboard visibility listener for Android 14 --- .../linphone/activities/main/MainActivity.kt | 16 ++++++++++- .../chat/fragments/DetailChatRoomFragment.kt | 28 +++++++++++++------ .../main/java/org/linphone/utils/AppUtils.kt | 4 +++ .../org/linphone/utils/DataBindingUtils.kt | 7 +++-- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index af0786b48..11a30793a 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -130,6 +130,8 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin } } + private val keyboardVisibilityListeners = arrayListOf() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -237,13 +239,17 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin registerComponentCallbacks(componentCallbacks) findNavController(R.id.nav_host_fragment).addOnDestinationChangedListener(this) - binding.rootCoordinatorLayout.addKeyboardInsetListener { keyboardVisible -> + binding.rootCoordinatorLayout.setKeyboardInsetListener { keyboardVisible -> val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE Log.i( "[Main Activity] Keyboard is ${if (keyboardVisible) "visible" else "invisible"}, orientation is ${if (portraitOrientation) "portrait" else "landscape"}" ) shouldTabsBeVisibleDueToOrientationAndKeyboard = !portraitOrientation || !keyboardVisible updateTabsFragmentVisibility() + + for (listener in keyboardVisibilityListeners) { + listener.onKeyboardVisibilityChanged(keyboardVisible) + } } initOverlay() @@ -278,6 +284,14 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin updateTabsFragmentVisibility() } + fun addKeyboardVisibilityListener(listener: AppUtils.KeyboardVisibilityListener) { + keyboardVisibilityListeners.add(listener) + } + + fun removeKeyboardVisibilityListener(listener: AppUtils.KeyboardVisibilityListener) { + keyboardVisibilityListeners.remove(listener) + } + fun hideKeyboard() { currentFocus?.hideKeyboard() } diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt index 76269e963..ae5905ef7 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt @@ -120,6 +120,17 @@ class DetailChatRoomFragment : MasterFragment - if (keyboardVisible && chatSendingViewModel.isEmojiPickerOpen.value == true) { - Log.d( - "[Chat Room] Emoji picker is opened, closing it because keyboard is now visible" - ) - chatSendingViewModel.isEmojiPickerOpen.value = false - } - } - Compatibility.setLocusIdInContentCaptureSession(binding.root, chatRoom) isSecure = chatRoom.currentParams.isEncryptionEnabled @@ -845,6 +847,10 @@ class DetailChatRoomFragment : MasterFragment Unit) { +fun View.setKeyboardInsetListener(lambda: (visible: Boolean) -> Unit) { doOnLayout { var isKeyboardVisible = ViewCompat.getRootWindowInsets(this)?.isVisible( WindowInsetsCompat.Type.ime() @@ -81,8 +81,9 @@ fun View.addKeyboardInsetListener(lambda: (visible: Boolean) -> Unit) { lambda(isKeyboardVisible) + // See https://issuetracker.google.com/issues/281942480 ViewCompat.setOnApplyWindowInsetsListener( - this + rootView ) { view, insets -> val keyboardVisibilityChanged = ViewCompat.getRootWindowInsets(view) ?.isVisible(WindowInsetsCompat.Type.ime()) == true @@ -90,7 +91,7 @@ fun View.addKeyboardInsetListener(lambda: (visible: Boolean) -> Unit) { isKeyboardVisible = keyboardVisibilityChanged lambda(isKeyboardVisible) } - insets + ViewCompat.onApplyWindowInsets(view, insets) } } } From 72b92408a1cda25caf2f7d4860eab7f7a6f010ac Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 16 Jun 2023 13:39:10 +0200 Subject: [PATCH 52/94] Specify service type in startForeground for Android 14 --- .../compatibility/Api34Compatibility.kt | 37 +++++++++++++++++++ .../linphone/compatibility/Compatibility.kt | 18 ++++++++- .../notifications/NotificationsManager.kt | 29 ++++++++------- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt index b325806a5..66f98c277 100644 --- a/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt @@ -20,12 +20,17 @@ package org.linphone.compatibility import android.annotation.TargetApi +import android.app.ForegroundServiceStartNotAllowedException +import android.app.Notification import android.app.NotificationManager +import android.app.Service import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.net.Uri import android.provider.Settings import androidx.core.content.ContextCompat +import org.linphone.core.tools.Log @TargetApi(34) class Api34Compatibility { @@ -44,5 +49,37 @@ class Api34Compatibility { intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) ContextCompat.startActivity(context, intent, null) } + + fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) { + try { + service.startForeground( + notifId, + notif, + ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA + ) + } catch (fssnae: ForegroundServiceStartNotAllowedException) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae") + } catch (se: SecurityException) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $se") + } catch (e: Exception) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $e") + } + } + + fun startDataSyncForegroundService(service: Service, notifId: Int, notif: Notification) { + try { + service.startForeground( + notifId, + notif, + ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC + ) + } catch (fssnae: ForegroundServiceStartNotAllowedException) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae") + } catch (se: SecurityException) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $se") + } catch (e: Exception) { + Log.e("[Api34 Compatibility] Can't start service as foreground! $e") + } + } } } diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index cab4ff7cf..c1bd96a85 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -291,7 +291,7 @@ class Compatibility { } } - fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { + private fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) { Api31Compatibility.startForegroundService(service, notifId, notif) } else { @@ -299,6 +299,22 @@ class Compatibility { } } + fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) { + if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { + Api34Compatibility.startCallForegroundService(service, notifId, notif) + } else { + startForegroundService(service, notifId, notif) + } + } + + fun startDataSyncForegroundService(service: Service, notifId: Int, notif: Notification) { + if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { + Api34Compatibility.startDataSyncForegroundService(service, notifId, notif) + } else { + startForegroundService(service, notifId, notif) + } + } + /* Call */ fun canDrawOverlay(context: Context): Boolean { diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index abc1e17c6..9fd936d14 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -407,24 +407,23 @@ class NotificationsManager(private val context: Context) { fun startForeground(coreService: CoreService, useAutoStartDescription: Boolean = true) { service = coreService - if (serviceNotification == null) { - createServiceNotification(useAutoStartDescription) - if (serviceNotification == null) { - Log.e( - "[Notifications Manager] Failed to create service notification, aborting foreground service!" - ) - return - } + val notification = serviceNotification ?: createServiceNotification(useAutoStartDescription) + if (notification == null) { + Log.e( + "[Notifications Manager] Failed to create service notification, aborting foreground service!" + ) + return } currentForegroundServiceNotificationId = SERVICE_NOTIF_ID Log.i( "[Notifications Manager] Starting service as foreground [$currentForegroundServiceNotificationId]" ) - Compatibility.startForegroundService( + + Compatibility.startDataSyncForegroundService( coreService, currentForegroundServiceNotificationId, - serviceNotification + notification ) } @@ -438,7 +437,7 @@ class NotificationsManager(private val context: Context) { val coreService = service if (coreService != null) { - Compatibility.startForegroundService( + Compatibility.startCallForegroundService( coreService, currentForegroundServiceNotificationId, callNotification @@ -499,11 +498,11 @@ class NotificationsManager(private val context: Context) { service = null } - private fun createServiceNotification(useAutoStartDescription: Boolean = false) { + private fun createServiceNotification(useAutoStartDescription: Boolean = false): Notification? { val serviceChannel = context.getString(R.string.notification_channel_service_id) if (Compatibility.getChannelImportance(notificationManager, serviceChannel) == NotificationManagerCompat.IMPORTANCE_NONE) { Log.w("[Notifications Manager] Service channel is disabled!") - return + return null } val pendingIntent = NavDeepLinkBuilder(context) @@ -535,7 +534,9 @@ class NotificationsManager(private val context: Context) { builder.setContentIntent(pendingIntent) } - serviceNotification = builder.build() + val notif = builder.build() + serviceNotification = notif + return notif } /* Call related */ From 624ebe160705136c8cad9c0e5afb4e94ca3fa295 Mon Sep 17 00:00:00 2001 From: 2dengine LLC Date: Sat, 10 Jun 2023 09:21:23 +0200 Subject: [PATCH 53/94] Added translation using Weblate (Bulgarian) --- app/src/main/res/values-bg/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-bg/strings.xml diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-bg/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From db384d9680a780960d3ab21139fd89fb656260f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Sat, 10 Jun 2023 10:31:40 +0000 Subject: [PATCH 54/94] Translated using Weblate (Czech) Currently translated at 100.0% (804 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/cs/ --- app/src/main/res/values-cs/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 3c98c9bbe..aba54c2f6 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -812,4 +812,6 @@ Přepnutí viditelnosti nástroje pro výběr emoji Vyžadováno ověření Potvrdit + Povolení vyžadované pro zobrazení příchozích hovorů zatím nebylo uděleno + Zobrazit \ No newline at end of file From 414f5451f582df8fe8e2474f79caa809bd4bed6b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 9 Jun 2023 03:07:33 +0000 Subject: [PATCH 55/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (804 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9444a7065..12472f502 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -805,4 +805,6 @@ 確認 您開啟了「閱後即焚」訊息:%s 切換顯示表情符號選取器 + 尚未授予顯示來電的必要權限 + 顯示 \ No newline at end of file From e5b00059310971ffbd338400ea1f4333c7d490a7 Mon Sep 17 00:00:00 2001 From: 2dengine LLC Date: Sat, 10 Jun 2023 08:34:01 +0000 Subject: [PATCH 56/94] Translated using Weblate (Bulgarian) Currently translated at 100.0% (804 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/bg/ --- app/src/main/res/values-bg/strings.xml | 814 ++++++++++++++++++++++++- 1 file changed, 813 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index a6b3daec9..8d90efa29 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -1,2 +1,814 @@ - \ No newline at end of file + +]> + + Премахнете контакт от разговора + Съобщенията в този разговор са краткотрайни + Към шифрован разговор + Промяна на снимката на контакта + Излезте от режима на редактиране + Гласова поща + Разговори + Към данните за контакта + Пропуснато обаждане + Изходящо обаждане + Сигурно + Ниско качество на обаждането + Обаждането не е сигурно + Приложение към среща + Отваряне на разговора в приложението + Записване на гласово съобщение + Спиране на записа на гласово съобщения + Поставяне на записа в пауза + Превъртете до долу или до първото непрочетено съобщение + Отворете контекстно меню за обаждането + Създайте нова среща + Копиране на адреса на срещата + Скриване на статистиката за обаждането + Участника си е изключил микрофона + Превключване на подробностите за срещата + Потребителя не желае да го безпокоят + Неуспешна връзка поради липсващи или неверни данни за автентикация +\n%s. +\n +\nМоля опитайте да въведете паролата отново или проверете настройките на акаута. + Изисква се за получаване на обаждания + &appName; контакти + Вижте нашата политика за поверителност + Логовете бяха изчистени + Телефонни номера + Име на държава или префикс + Потребителско име + Имейл + Домейн + SIP адреси + Отказ + Споделете връзка до логовете чрез… + Днес + Вчера + UDP + TCP + TLS + Свободния SIP клиент + Свързване в прогрес + Неуспешно свързване + За нас + Записи + Настройки + Обаждания + Няма последни обаждания + Няма групови обаждания + Желаете ли да изтриете този запис\? + Покана + Нямате контакти в адресната книга. + Нямате SIP контакти в адресната книга. + Търсене на контакти + Фамилия + Първо име + Организация + Изберете съществуващ контакт или добавете нов + Изберете къде да се съхрани този контакт + Локално съхранение + Този контакт не може да бъде изтрит + Налични са още резултати, моля редактирайте търсеното + Въведете номер или адрес + Включете логовете + Изключете логовете + Обаждането се трансферира + Не може да се трансферира обаждането + Няма разговори + Присъединихте се към група + Напуснахте група + %s се присъедини + %s напусна + ново устройство за %s + %s: + %s е администратор + %s вече не е администратор + Забелязана е MITM хакерска атака за %s + Нивото на сигурност намаля заради %s + Изключили сте краткотрайните съобщения + Включили сте краткотрайните съобщения: %s + Срок за изтичане на краткотрайните съобщения: %s + Изтегляне + Изберете източник + Информация + Участващи + Име на група + Администратор + Напускане + Вие сте администратор + Вече не сте администратор + Етап на доставка + Прочетено + Доставено + Недоставено + Изпратено + Отговорено + Препращане + Отговор + Етап на доставка + Изтриване + Добавяне към контакти + Файлът не съществува + Информация за групата + Устройства за чат + Към контакт + Краткотрайни съобщения + Изтриване на съобщения + Изключване на известия + Включване на известия + Изключено + 1 минута + 1 час + 1 ден + 3 дни + 1 седмица + + %s пише… + %s пишат… + + Неуспешно създаване на стая за чат + Неуспешно премахване на стая за чат + Сигурни ли сте, че искате да изтриете този разговор\? + <Редакция> + Няма подходящо приложение за такъв тип файл + Не може да се отвори шифрован файл в чата + Не може да покажем файла. + Експортиране + Отваряне като файл + Отговор + Съобщение + Натиснете бутона за да запишете гласово съобщение + Съобщението ще бъде изтрито + Прекъсване + Моля изчакайте да завърши първото изтегляне преди да започнете ново + Гласово съобщение + Онлайн днес в + Онлайн вчера в + Онлайн в + В отсъствие + Не безпокойте + Експортиране на запис чрез… + Среща + Насрочване на среща + Стартирайте групово обаждане + Задължително + Тема + Тема на групово обаждане + Адрес на среща + Добавете описание + Описание + Дата + Час + Часова зона + Изпратете покана чрез &appName; + Изпратете покана чрез имейл + Изпратете актуализация чрез имейл + Желаете ли да зашифровате срещата\? + Списък с участници + Организатор + Информация за срещата + Информация за груповото обаждане + Насрочване на среща + Стартирайте групово обаждане + В момента не участвате в срещата. + Натиснете бутона за да се присъедините отново. + Далечно групово обаждане + Локално групово обаждане + Покана за среща: + Срещата бе отменена: + Описание + Присъединяване + %d участника + Режим мозайка + Видеото е изключено + Няма прекратени срещи. + Организатор: + Стая за срещата + %s е администратор + Бяхте поканени на среща + покана за среща + Първи се присъединихте към груповото обаждане + Всички други участници напуснаха груповото обаждане + Входящо групово обаждане + Участници (%d) + Стартиране + Прекратяване + Насрочване + Желаете ли да изтриете тази среща\? + Желаете ли да изтриете тези срещи\? + Конференцията бе прекратена от организатора + Вие прекратихте конференцията + Входящо обаждане + Обаждането e в пауза + Изходящо обаждане + Активно обаждане + Абоната е зает + Не е открит такъв абонат + Няма достъп до мрежа + Услугата не е достъпна или грешка с мрежата + Отказ поради прекомерни заявки + Временно недостъпно + Грешка: %s + Списък с участници + Чат + Списък с обаждания + Циферблат + Промяна на оформление + Статистика за обаждания + Възобновяване на обаждането + Трансфериране на обаждането + Това обаждане се записва. + Обаждането е в пауза от ответната страна. + Обаждането е в пауза. + Записана снимка: %s + Аудио + Видео + Кодек: + IP семейство: + Ширина на качване: + Приблизителна ширина на теглене: + ICE свързаност: + Резолюция на изходящо видео: + Честота на кадрите на изходящо видео: + Загуба при изпращане: + Загуба при получаване: + Енкодер: + Декодер: + Филтър за възпроизвеждане: + Филтър за записване: + Шифроващ алгоритъм: + Алгоритъм за споразумение: + Алгоритъм за хаширане: + SAS алгоритъм: + Добре дошли + Създаване на акаунт + Използване на &appName; акаунт + Използване на SIP акаунт + Изтегляне на настройки от мрежата + Калибрира се настройката за заглушаване на ехо + общите условия + политиката за поверителност + Приемам %1$ и %2$ на Belledonne Communications + Разбрах + Откриване на нов акаунт чрез вашия имейл адрес: + Моля въведете само числа тук + Потребителското име е заето + Вече съществува акаунт със същия номер + Непозволени символи + Паролите не са еднакви + Имейл адреса не е валиден + Потребителското име е прекалено дълго + Акаунта не съществува или паролата е различна + Използвайте вашето потребителско име и парола вместо телефонен номер + Забравена парола\? + Код за потвърждение + Продължаване + Екранно име (незадължително) + Потвърдете паролата + След като сте готови, моля върнете се тази страница и натиснете бутона. + За да потвърдите вашия телефонен номер, моля въведете четири цифрения код: +\n + Пропускане + Свържете акаунт + Дистанционно изтегляне на настройки + Моля въведете URL адрес за настройки + URL + Неизвестен URL формат, неуспешно изтегляне на профил… + Неуспешно изтегляне или прилагане на профил… + Изтегляне и прилагане + QR код + SIP акаунти + Настройки + Тунел + Аудио + Видео + Обаждане + Чат + Мрежа + Контакти + Разширени + Срещи + Екранно име + Потребителско име + Парола + Валидиране + Невалидна парола! + Софтуерно анулиране на ехо + Премахва ехото което се чува от ответната страна + Калибриране за анулиране на ехо + Започва калибриране за анулиране на ехо + Калибрирано за %s милисекунди + Неуспешно калибриране + Тест за ехо + Натиснете за да започне тест за ехо + Теста за ехо е спрян + Теста за ехо се извършва + Звуково устройство по подразбиране + Изходно звуково устройство по подразбиране + Ограничение на битрейт за кодека + (в децибели) + Усилване на звука + Кодекси + Включване на видео + Показване на камерата върху циферблата + Винаги изпращайте заявки за видео + Приемане на входящи заявки за видео + Винаги приемайте заявки за видео + Камера + Предпочитана честота на кадрите + Кодекси + Мелодия + Вибрация при входящи обаждания + Шифроване на медията + Няма + Подобряване на връзката с bluetooth устройства + Наслагване на известието за обаждане + Показване на известието извън приложението + SRTP + ZRTP + Квантово устойчив ZRTP + DTLS-SRTP + Незабавно стартиране на обаждането + Автоматично отговаряне на входящи обаждания + Времетраене за автоматичен отговор + в милисекунди + Времетраене за отказ на прекомерни входящи обаждания + в секунди + URI за гласова поща + Приемане на ранна медия + Звънене по време на входяща ранна медия + Настройки на известия за Андроид + Автоматично записване на обажданията + Известие когато обаждането се записва от кореспондент + Определя дали да се изтеглят файлове прикачени към получени съобщения + Винаги + Никога + Максимален размер + в байтове + Изтеглените файлове да са публични + Скриване на съдържанието на съобщения в известията + Показва се само името на автора + Създаване на преки пътища до стаи при стартиране + Скриване на празни стаи + Скриване на стаите от премахнат акаунт + Ако ви липсват стаи, опитайте да изключите тази настройка + Винаги отваряйте файлове в това приложение + Пак ще можете да ги експортирате към други приложения + Използване само през WiFi + Използване на случайни портове + SIP порт + Информация за присъствие на контакти + Показване на данни за организация + Създаване на преки пътища до контакти при стартиране + Заменя преките пътища до стаи, ако съществуват такива + Ако се изключи, контактите ще се съхраняват локално + Нова конфигурация LDAP + Включване + Изтриване + Връзка + URL адрес на сървър + Парола + Начин за автентикация + Прост + Чрез TLS + Проверка на сертификати + Автоматично + Изключено + Включено + Търсене + Не може да е празно! + Филтър + Максимален брой резултати + Време за изчакване + Време между две заявки + В милисекунди + Минимален брой символи за търсене + Разбор + Атрибути на SIP + Домейн + LDAP + Обвързване на DN + Отстраняване на грешки + Фонов режим + Показване на известие за да не се изключи приложението + Тъмна тема + Автоматично + Не + Да + Анимации + Име на устройството + URL адрес за доставка + URL за качване на логовете + Моля не редактирате ако не сте сигурни! + Андроид + Настройки на диспечер за захранването + Настройки за Андроид приложение + Зашифроване на всичко + Изпращане на логовете + Анулиране на логовете + Настройка за отстраняване на грешки + Други настройки + Позволяване на записване на екрана когато съдържа поверителна информация + Име на хост + Порт + Двоен режим включен + Име на хост на втори сървър + Изисква се в двоен режим + Втори порт на сървър + Изисква се в двоен режим + Режим + Изключен + Автоматично + Потребителско име + Име за автентикация + Въведете име за автентикация ако се различава от потребителското име (незадължително) + Домейн + Пример: sip.example.org ако акаунта ви е john@sip.example.org + Екранно име + Управление + Деактивиране + Използване по подразбиране + Изтриване + Разширени настройки + Разрешете известия + Транспортен протокол + SIP прокси + Изходящо прокси + Насочете всички обаждания през посоченото SIP прокси + STUN/TURN сървър + Включете ICE + в секунди (между 1 и 5) + Време за изтичане + Префикс за вашата държава + без + + Добавяне на префикс при изходящи обаждания и чат + Замяна на + с 00 + Конферентен фактори URI + Адрес на сървър за E2E шифроване + Адрес на сървър за E2E шифроване + Желаете ли да изтриете вашия акаунт\? + UDP + TCP + TLS + DTLS + AVPF + Деактивирайте пакетния режим + &appName; известия за входящи обаждания + Входящо обаждане + Входящо групово обаждане + Прекратяване + Отговор + Отговор + Маркиране като прочетено + Пропуснато обаждане + %d пропуснати обаждания + Сигурност на комуникацията + По-късно + Правилно + Кажете: + Вашия кореспондент трябва да каже: + Не показвай отново + Отказ + Изтриване + Добре + Приемане + Отхвърляне + Обаждане + Операцията се извършва, моля изчакайте + Сигурни ли сте, че искате да изтриете този предмет\? + Сигурни ли сте, че искате да изтриете избраните предмети\? + Съществува актуализация + Желаете ли да го отворите като текстов файл\? + Потвърждение + Добавяне на поле за SIP адрес + Добавяне на поле за телефонен номер + Назад + Изтрийте полето до него + Сменете между предна или задна камера + Пауза на обаждането + Прекратяване на обаждането + Отговорете на обаждането + Изключване на микрофона + Включване на микрофона + Пренасочване на звука през слушалки + Назад към обаждането + Включване на видео + Изключване на видео + Използване на bluetooth слушалки за звук + Използване на слушалки за звук + Стартиране на ново обаждане + Трансфериране на обаждането до друг + Файлов трансфер в очакване + Прикачен файл + Етап на доставка + Препращане на съобщението в този разговор + Съобщението е краткотрайно + Контакта е маркиран + Шифроване от \"край до край\" е изключено + Показване на списък с всички контакти + Показване на списък само със SIP контакти + Размаркиране на контакт + Стартиране на обаждане + Показване на менюто за стая + Влезте в режим на редактиране + Прикачване на файл към съобщението + Изисква се разрешение за да се показват входящи обаждания + Покавзане + Избрано времетраене за краткотрайни съобщения + Променете времетраенето за краткотрайни съобщения + Създайте стая за чат + Добавете участници + Контакта е администратор в този разговор + Контакта не е администратор в този разговор + Известията за този разговор са изключени + Контакта може да бъде поканен в шифровани разговори + Към разговор + Редактиране на контакт + Изтриване на контакт + Отхвърлете промените + Запишете промените + Промяна на собствената снимка + Към подробности за обаждането + Маркирайте всички в листа + Размаркирайте всички + Изтрийте всички маркирани + Стартиране или прекъсване на записа + Показване или скриване на страничното меню + Последни обаждания + Контакти + Циферблат + Премахване на последния символ + Създаване на контакт + Показване на всички обаждания + Показване само на пропуснатите обаждания + Входящо обаждане + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + * + # + Създаване на нов разговор + Създаване на нов групов разговор + Несигурно + Шифровано + Много ниско качество на обаждането + Средно качество на обаждането + Добро качество на обаждането + Максимално качество на обаждането + Обаждането е сигурно + Сигурността на обаждането се определя + Приложение към видео + Записване на снимка от получен видео клип + Затваряне на известието + Отваряне на файла с друго приложение + Прекратяване на препращането + Прекратяване на споделянето + Прекратяване на отговора + Прекратяване на записа + Записване + Редактиране на среща + Изтриване на среща + Срещата ще бъде шифрована + Експортиране на събитието до календара + Показване на циферблата + Скриване на циферблата + Към списъка с участници + Показване или скриване на груповото офомление + Участника временно напусна груповото обаждане + Участници в груповото обаждане + Експортиране на запис + Потребителя е на линия + Потребителя не е на линия + Превключване на менюто с emoji + &appName; услуга + &appName; бе стартирано автоматично + Помогнете да преведем &appName; на различни езици + Неуспешно качване на логове! + Адреса на логовете бе копиран в клипборда + Телефонен номер + Изберете вашата държава + Префикс + Изберете държава + Парола + SIP адрес + + %d ден + %d дни + + Неочаквана грешка… + Транспортен протокол + Свързано + Не е свързано + Не е настроен акаунт + Асистент + Напускане + Няма изпуснати обаждания + Желаете ли да изтриете тези записи\? + Здравейте, свържете се с мен чрез &appName;! Може да изтеглите безплатното приложение от %s + Няма разрешение да се добавят или редактират контакти + Желаете ли да изтриете този контакт\? +\nСъщия ще бъде премахнат от адресната книга на вашето устройство + Желаете ли да изтриете тези контакти\? +\nСъщите ще бъде премахнати от адресната книга на вашето устройство + Отстраняване на грешки + Изпратете логовете + Вижте конфигурационния файл + Ответната страна пише… + устройството за %s беше премахнато + нова тема: %s + Смени се ключ за LIME идентичност за %s + Максималния брой участници е надвишен с %s + Устройства за чат + Напускане на група + Желаете ли да напуснете разговора\? + Пренасочено + Повторно изпращане + Копиране на текста + Желаете ли па препратите съобщението до тази стая\? + Изберете или създайте нов разговор за да препратите съобщението + Изберете или създайте нов разговор за да споделите файла/файловете + Изберете или създайте нов разговор за да споделите текста + Краткотрайни съобщения + Това съобщение ще бъде заличено от двете страни след като бъде прочетено и след като измине посочения срок. + Сигурни ли сте, че искате да изтриете тези разговори\? + Желаете ли да отворите файла като текст или да го експортирате (разшифрован) към друго приложение\? + Нивото на звук ви е ниско, моля опитайте да го увеличите + + %1$d непрочетено съобщение + %1$d непрочетени съобщения + + Вие получихте гласово съобщение + Онлайн + Няма записи + Желаете ли да насрочите среща за по-късно\? + Тема на срещата + Времетраене + Изпратете актуализация чрез &appName; + Поканата ще бъде изпратена чрез моят &appName; акаунт + Редактиране на среща + Адреса на срещата бе копиран в клипборда + Неуспешно изпращане на информация за срещата до участник + Срещата бе обновена: + Режим активен говорител + Режим само звук + Стартиране + Прекратяване + Срещи + Не може да промените оформлението на груповото обаждане защото има прекалено много участници + Има прекалено много участници за оформление в мозайка, преминаване към режим на активен говорител + (в пауза) + Няма насрочени срещи. + Неуспешно създаване на среща + %s вече не е администратор + Срещата е насрочена + Информацията за срещата е заличена + В момента сте сами в това групово обаждане + Видеото бе изключено поради ниска скорост на връзката + Групово обаждане + Желаете ли да започнете групово обаждане\? +\nВсички в тази група ще получат обаждане за да се присъединят към срещата. + Изходящо обаждане + Обаждането бе отказано + Несъвместими настройки на медия + Кореспондента желае да включи видео + Ново обаждане + Трансфериране на обаждане + Трансфериране с присъствие + Пауза на обаждането + Отговаряне на обаждането + Прекратяване на обаждането + Натиснете на бутона за да възобновите обаждането. + Ширина на теглене: + Резолюция на входящо видео: + Честота на кадрите на входящо видео: + Джитър буфер: + Шифроване на медия: + Алгоритъм за автентикация: + Този асистент ще ви помогне да настроите вашия SIP акаунт. + За какво се използва моят телефонен номер\? + " +\nВашите приятели ще ви открият по-лесно ако свържете телефонен номер с вашия акаунт +\n +\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName; +\n" + Вашите приятели ще ви открият по-лесно ако свържете телефонен номер с вашия акаунт +\n +\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName;. + Някои от опциите като групов чат и краткотрайни съобщения изискват &appName; акаунт. +\n +\nТези опции са скрити ако се регистрирате със SIP акаунт от друг доставчик. +\n +\nМоля свържете се с нас ако смятате да използвате тези опции за комерсиални цели. + Изглежда, че вашето устройство не може да получава известия. +\n +\nИзвестията са необходими за да откриете нов акаунт чрез това приложение. За да продължите, моля посетете нашата страница: + Използвайте вашия &appName; акаунт + Моля потвърдете кода на вашата държава и въведете вашия телефонен номер + Моля въведете вашето &appName; потребителско име и парола + Вписване + Завършване + Използване на SIP акаунт + Моля въведете потребителско име и парола на вашия SIP домейн + Моля въведете потребителско име, имейл адрес и парола за вашия &appName; акаунт + Вашия акаунт беше създаден успешно. Моля проверете пощенската си кутия за да потвърдите регистрацията: + Използвайте потребителско име (незадължително) + До вашия телефонен номер бе изпратен SMS с код за потвърждение: + Вие ще свържете вашия телефонен номер с следното потребителско име: + Вашия акаунт все още не е активиран, моля натиснете на връзката в съдържанието на получения от вас имейл + Акаунт по подразбиране + Основен акаунт + Моля въведете парола за достъп до настройките + Натиснете за да започне калибриране за анулиране на ехо + Не е доловено ехо + Адаптивен контрол + Промените ще се отразят при следващото обаждане + Промените ще се отразят при следващото обаждане + Насочете звука към bluetooth устройството, ако има такова + Усилване на микрофона + (в децибели) + Започване на видео обаждане + Предпочитан размер за видео + Предварително зададени настройки за видео + Ограничаване на ширината + в килобита/сек + Използвайте мелодията на устройството + Задължително шифроване на медията + Изисква някои допълнителни разрешения + Моля дайте разрешение за да се наслагват известията + Изпращане на извън обхватни DTMF (SIP INFO) + Изпращане на обхватни DTMF (RFC 2833) + Обаждането ще започне автоматично ако се стартира от друго приложение + Пренасочване на отказаните обаждания към URI за гласова поща + Поставяне на обаждането в пауза при загуба на фокус + Премахнатите известия да се маркират като прочетени + URL на сървър за споделяне + Не редактирайте ако не сте сигурни! + Автоматично изтегляне на входящи файлове + Ако са по-малки от посочения размер + Автоматичното изтегляне на входящи файлове не важи за файловете в краткотрайни съобщения + Ще се замести от преки пътища до контакти, ако е включено + Настройки за известия на Андроид + Автоматично изтегляне на входящи гласови съобщения + Позволяване на IPv6 + Абониране към списъка с приятели + Добавяне на информационни връзки от &appName; контактите към тези на Андроид + Винаги да се пита в кой акаунт да се съхраняват нови контакти + Анонимен + База на търсене + В секунди + Атрибути на име + Други + Логове за отстраняване на грешки + Стартиране заедно с устройството + Промените ще се приложат при следващото стартиране + Настройка за спестяване на батерия + Веднъж като се включи е невъзможно да се спре! + Изключване на сигурния режим за UI + Ще се използва един сървър за качване и втори за теглене + Винаги + Пример: john ако акаунта ви е john@sip.example.org + Парола + Паролата се въвежда повторно при промяна на потребителско име или домейн + Свържете вашия акаунт + Не може да се отмени регистрацията + AVPF обикновен RTCP интервал + Префикс за вашата държава + При набиране на номер, добавяне на префикс + Публикуване на данни за присъствие + Вашият акаунт ще бъде изтрит локално. +\nЗа да го заличите за постоянно, посетете страницата на вашият SIP доставчик. + Вашият акаунт ще бъде изтрит локално. +\nЗа да го заличите за постоянно, посетете нашата платформа за управление: + Оформление по подразбиране + &appName; известия за услуга + &appName; известия за пропуснати обаждания + &appName; известия за текстови съобщения + Пропуснато обаждане от %s + За да повишите нивото на сигурност, проверете следните кодове с вашия кореспондент. + Съобщенията при разговори с висока сигурност са шифровани от \"край до край\". Възможно е да се повиши нивото на сигурност на разговора когато участниците извършат автентикация. За да извършите същото, обадете се на вашия контакт и следвайте процеса за автентикация. + Няма приложение за този тип файл + Желаете ли да изтеглите и приложите конфигурация от този адрес\? + Прилагане + Изисква се автентикация + Покажете за какво се използва телефонният ви номер + Включване или изключване на записа на обаждането + Пренасочване на звука през тон колони + Показване или скриване на звуковото меню + Използване на тон колони за звук + Премахване на файловия трансфер + Контакта е потребител на &appName; + Шифроване от \"край до край\" е включено + Към крайната стъпка при създаване на стая + Изпращане на съобщение + Показване или скриване на устройствата на участниците + \ No newline at end of file From b03ef2d42f90d9c383355d6f136536fe7f63b006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Gle=C5=84?= Date: Sat, 17 Jun 2023 21:34:12 +0000 Subject: [PATCH 57/94] Translated using Weblate (Polish) Currently translated at 4.3% (35 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/pl/ --- app/src/main/res/values-pl/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a6b3daec9..4d83b60ac 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -1,2 +1,12 @@ - \ No newline at end of file + + Nieodebrane połączenie + Nieodebrane połączenie od %s + %d nieodebranych połączeń + Nie pokazuj ponownie + Anuluj + Usuń + OK + Akceptuj + Odrzuć + \ No newline at end of file From 197ceb9e69b8a0c7bfa03d379d666f2a3aae1b00 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Jun 2023 10:34:46 +0200 Subject: [PATCH 58/94] Fixed &appName; XML entity --- app/src/main/res/values-bg/strings.xml | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 8d90efa29..40a117f58 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -245,7 +245,7 @@ SAS алгоритъм: Добре дошли Създаване на акаунт - Използване на &appName; акаунт + Използване на &appName; акаунт Използване на SIP акаунт Изтегляне на настройки от мрежата Калибрира се настройката за заглушаване на ехо @@ -456,7 +456,7 @@ DTLS AVPF Деактивирайте пакетния режим - &appName; известия за входящи обаждания + &appName; известия за входящи обаждания Входящо обаждане Входящо групово обаждане Прекратяване @@ -590,9 +590,9 @@ Потребителя е на линия Потребителя не е на линия Превключване на менюто с emoji - &appName; услуга - &appName; бе стартирано автоматично - Помогнете да преведем &appName; на различни езици + &appName; услуга + &appName; бе стартирано автоматично + Помогнете да преведем &appName; на различни езици Неуспешно качване на логове! Адреса на логовете бе копиран в клипборда Телефонен номер @@ -614,7 +614,7 @@ Напускане Няма изпуснати обаждания Желаете ли да изтриете тези записи\? - Здравейте, свържете се с мен чрез &appName;! Може да изтеглите безплатното приложение от %s + Здравейте, свържете се с мен чрез &appName;! Може да изтеглите безплатното приложение от %s Няма разрешение да се добавят или редактират контакти Желаете ли да изтриете този контакт\? \nСъщия ще бъде премахнат от адресната книга на вашето устройство @@ -653,8 +653,8 @@ Желаете ли да насрочите среща за по-късно\? Тема на срещата Времетраене - Изпратете актуализация чрез &appName; - Поканата ще бъде изпратена чрез моят &appName; акаунт + Изпратете актуализация чрез &appName; + Поканата ще бъде изпратена чрез моят &appName; акаунт Редактиране на среща Адреса на срещата бе копиран в клипборда Неуспешно изпращане на информация за срещата до участник @@ -699,12 +699,12 @@ " \nВашите приятели ще ви открият по-лесно ако свържете телефонен номер с вашия акаунт \n -\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName; +\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName; \n" Вашите приятели ще ви открият по-лесно ако свържете телефонен номер с вашия акаунт \n -\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName;. - Някои от опциите като групов чат и краткотрайни съобщения изискват &appName; акаунт. +\nЩе може да видите в вашата адресна книга кой използва &appName; и вашите приятели ще узнаят, че мога да ви се обадят чрез &appName;. + Някои от опциите като групов чат и краткотрайни съобщения изискват &appName; акаунт. \n \nТези опции са скрити ако се регистрирате със SIP акаунт от друг доставчик. \n @@ -712,14 +712,14 @@ Изглежда, че вашето устройство не може да получава известия. \n \nИзвестията са необходими за да откриете нов акаунт чрез това приложение. За да продължите, моля посетете нашата страница: - Използвайте вашия &appName; акаунт + Използвайте вашия &appName; акаунт Моля потвърдете кода на вашата държава и въведете вашия телефонен номер - Моля въведете вашето &appName; потребителско име и парола + Моля въведете вашето &appName; потребителско име и парола Вписване Завършване Използване на SIP акаунт Моля въведете потребителско име и парола на вашия SIP домейн - Моля въведете потребителско име, имейл адрес и парола за вашия &appName; акаунт + Моля въведете потребителско име, имейл адрес и парола за вашия &appName; акаунт Вашия акаунт беше създаден успешно. Моля проверете пощенската си кутия за да потвърдите регистрацията: Използвайте потребителско име (незадължително) До вашия телефонен номер бе изпратен SMS с код за потвърждение: @@ -761,7 +761,7 @@ Автоматично изтегляне на входящи гласови съобщения Позволяване на IPv6 Абониране към списъка с приятели - Добавяне на информационни връзки от &appName; контактите към тези на Андроид + Добавяне на информационни връзки от &appName; контактите към тези на Андроид Винаги да се пита в кой акаунт да се съхраняват нови контакти Анонимен База на търсене @@ -790,9 +790,9 @@ Вашият акаунт ще бъде изтрит локално. \nЗа да го заличите за постоянно, посетете нашата платформа за управление: Оформление по подразбиране - &appName; известия за услуга - &appName; известия за пропуснати обаждания - &appName; известия за текстови съобщения + &appName; известия за услуга + &appName; известия за пропуснати обаждания + &appName; известия за текстови съобщения Пропуснато обаждане от %s За да повишите нивото на сигурност, проверете следните кодове с вашия кореспондент. Съобщенията при разговори с висока сигурност са шифровани от \"край до край\". Възможно е да се повиши нивото на сигурност на разговора когато участниците извършат автентикация. За да извършите същото, обадете се на вашия контакт и следвайте процеса за автентикация. @@ -806,7 +806,7 @@ Показване или скриване на звуковото меню Използване на тон колони за звук Премахване на файловия трансфер - Контакта е потребител на &appName; + Контакта е потребител на &appName; Шифроване от \"край до край\" е включено Към крайната стъпка при създаване на стая Изпращане на съобщение From 226095bec7c5907d19a2cb969a192ed8e38b9fca Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Jun 2023 15:12:12 +0200 Subject: [PATCH 59/94] Disable attach file & voice messages in chat if no file transfer server URL is set --- .../main/chat/viewmodels/ChatMessageSendingViewModel.kt | 3 +++ app/src/main/java/org/linphone/utils/LinphoneUtils.kt | 5 +++++ app/src/main/res/layout/chat_room_detail_fragment.xml | 1 + app/src/main/res/layout/chat_room_master_fragment.xml | 3 ++- app/src/main/res/layout/chat_room_sending.xml | 3 ++- app/src/main/res/layout/contact_master_fragment.xml | 1 + app/src/main/res/layout/history_master_fragment.xml | 1 + app/src/main/res/layout/settings_fragment.xml | 1 + 8 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt index 1c0c7d08c..c085805e4 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt @@ -107,6 +107,8 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel() val isEmojiPickerVisible = MutableLiveData() + val isFileTransferAvailable = MutableLiveData() + val requestKeyboardHidingEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -146,6 +148,7 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel() sendMessageEnabled.value = false isEmojiPickerOpen.value = false isEmojiPickerVisible.value = corePreferences.showEmojiPickerButton + isFileTransferAvailable.value = LinphoneUtils.isFileTransferAvailable() updateChatRoomReadOnlyState() } diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 47c095644..96ca6032d 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -288,6 +288,11 @@ class LinphoneUtils { return true } + fun isFileTransferAvailable(): Boolean { + val core = coreContext.core + return core.fileTransferServer.orEmpty().isNotEmpty() + } + fun hashPassword( userId: String, password: String, diff --git a/app/src/main/res/layout/chat_room_detail_fragment.xml b/app/src/main/res/layout/chat_room_detail_fragment.xml index 0a5dfeb6f..17f074c36 100644 --- a/app/src/main/res/layout/chat_room_detail_fragment.xml +++ b/app/src/main/res/layout/chat_room_detail_fragment.xml @@ -44,6 +44,7 @@ + android:layout_gravity="start" + android:background="?attr/backgroundColor"> Date: Mon, 26 Jun 2023 15:10:00 +0200 Subject: [PATCH 60/94] Fixed padding issue in multi line text view in chat --- .../views/MultiLineWrapContentWidthTextView.kt | 18 ++++++++++-------- .../java/org/linphone/core/CorePreferences.kt | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/chat/views/MultiLineWrapContentWidthTextView.kt b/app/src/main/java/org/linphone/activities/main/chat/views/MultiLineWrapContentWidthTextView.kt index a0b114149..fe08e43a0 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/views/MultiLineWrapContentWidthTextView.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/views/MultiLineWrapContentWidthTextView.kt @@ -25,6 +25,8 @@ import android.text.method.LinkMovementMethod import android.util.AttributeSet import androidx.appcompat.widget.AppCompatTextView import kotlin.math.ceil +import kotlin.math.max +import kotlin.math.round /** * The purpose of this class is to have a TextView declared with wrap_content as width that won't @@ -52,10 +54,12 @@ class MultiLineWrapContentWidthTextView : AppCompatTextView { if (layout != null && layout.lineCount >= 2) { val maxLineWidth = ceil(getMaxLineWidth(layout)).toInt() - val uselessPaddingWidth = layout.width - maxLineWidth - val width = measuredWidth - uselessPaddingWidth - val height = measuredHeight - setMeasuredDimension(width, height) + if (maxLineWidth < measuredWidth) { + super.onMeasure( + MeasureSpec.makeMeasureSpec(maxLineWidth, MeasureSpec.getMode(widthSpec)), + heightSpec + ) + } } } @@ -63,10 +67,8 @@ class MultiLineWrapContentWidthTextView : AppCompatTextView { var maxWidth = 0.0f val lines = layout.lineCount for (i in 0 until lines) { - if (layout.getLineWidth(i) > maxWidth) { - maxWidth = layout.getLineWidth(i) - } + maxWidth = max(maxWidth, layout.getLineWidth(i)) } - return maxWidth + return round(maxWidth) } } diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index 51c8e7f6d..9a19daf03 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -53,6 +53,7 @@ class CorePreferences constructor(private val context: Context) { context, MasterKey.DEFAULT_MASTER_KEY_ALIAS ).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build() + try { EncryptedSharedPreferences.create( context, From 04bfce04066f29fe09182642a4a7531f822f70fa Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 28 Jun 2023 14:33:18 +0200 Subject: [PATCH 61/94] Updated CHANGELOG --- CHANGELOG.md | 20 ++++++++++++++++---- build.gradle | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index faa86ddf3..9a8ec20e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,13 @@ Group changes to describe their impact on the project, as follows: - Showing short term presence for contacts whom publish it + added setting to disable it (enabled by default for sip.linphone.org accounts) - Confirmation dialog before removing account - Attended transfer instead of blind transfer if there is more than 1 call -- Added emoji picker in chat room, and increase size of text if it only contains emojis -- Added hidden setting to disable video completely -- Added hidden setting to prevent adding / editing / removing native contacts -- Added hidden setting to protect settings access using account password +- Last sent message delivery status (IMDN) icon in chat rooms list +- Emoji picker in chat room, and increase size of text if it only contains emojis +- Hidden setting to disable video completely +- Hidden setting to prevent adding / editing / removing native contacts +- Hidden setting to protect settings access using account password - SIP URI in call can be selected using long press +- Dialog showing up asking for correct account password in case of failed authentication ### Changed - Switched Account Creator backend from XMLRPC to FlexiAPI, it now requires to be able to receive a push notification @@ -35,6 +37,16 @@ Group changes to describe their impact on the project, as follows: - Messages not marked as reply in basic chat room if sending more than 1 content - Chat message video attachment display when failing to get a preview picture +## [5.0.14] - 2023-06-20 + +### Changed +- SDK update only + +## [5.0.13] - 2023-06-15 + +### Changed +- SDK update only + ## [5.0.12] - 2023-05-23 ### Fixed diff --git a/build.gradle b/build.gradle index a85419a92..be35fe70d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { classpath 'com.android.tools.build:gradle:8.0.2' classpath 'com.google.gms:google-services:4.3.15' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.6' } } From 7335360c260dedffca299916d70b6f2a5ca09036 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 28 Jun 2023 17:02:35 +0200 Subject: [PATCH 62/94] Prevent chat message notification to be updated for nothing --- .../notifications/NotificationsManager.kt | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 9fd936d14..c7a7e2366 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -179,7 +179,23 @@ class NotificationsManager(private val context: Context) { } } - val notifiable = createChatNotifiable(room, messages) + var allOutgoing = true + for (message in messages) { + if (!message.isOutgoing) { + allOutgoing = false + break + } + } + + val notifiable = getNotifiableForRoom(room) + val updated = updateChatNotifiableWithMessages(notifiable, room, messages) + if (!updated) { + Log.w( + "[Notifications Manager] No changes made to notifiable, do not display it again" + ) + return + } + if (notifiable.messages.isNotEmpty()) { displayChatNotifiable(room, notifiable) } else { @@ -794,14 +810,18 @@ class NotificationsManager(private val context: Context) { notify(notifiable.notificationId, notification, CHAT_TAG) } - private fun createChatNotifiable(room: ChatRoom, messages: Array): Notifiable { - val notifiable = getNotifiableForRoom(room) - + private fun updateChatNotifiableWithMessages( + notifiable: Notifiable, + room: ChatRoom, + messages: Array + ): Boolean { + var updated = false for (message in messages) { if (message.isRead || message.isOutgoing) continue val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress) val notifiableMessage = getNotifiableMessage(message, friend) notifiable.messages.add(notifiableMessage) + updated = true } if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { @@ -810,8 +830,7 @@ class NotificationsManager(private val context: Context) { notifiable.isGroup = true notifiable.groupTitle = room.subject } - - return notifiable + return updated } private fun getNotifiableForRoom(room: ChatRoom): Notifiable { From 6765505ff07b5607eb2bd13cfae547f0273131c7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 28 Jun 2023 17:32:18 +0200 Subject: [PATCH 63/94] Fixed ANR when opening a PDF inside linphone (VFS enabled for example) --- .../main/files/fragments/PdfViewerFragment.kt | 8 ++- .../main/files/viewmodels/PdfFileViewModel.kt | 71 +++++++++++++------ .../files/viewmodels/TextFileViewModel.kt | 9 +-- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt b/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt index 799543fc4..2e123d104 100644 --- a/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt @@ -54,7 +54,11 @@ class PdfViewerFragment : GenericViewerFragment() )[PdfFileViewModel::class.java] binding.viewModel = viewModel - adapter = PdfPagesListAdapter(viewModel) - binding.pdfViewPager.adapter = adapter + viewModel.rendererReady.observe(viewLifecycleOwner) { + it.consume { + adapter = PdfPagesListAdapter(viewModel) + binding.pdfViewPager.adapter = adapter + } + } } } diff --git a/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt b/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt index 34df29d60..259957fac 100644 --- a/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt @@ -26,10 +26,15 @@ import android.widget.ImageView import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope import java.io.File +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.Content import org.linphone.core.tools.Log +import org.linphone.utils.Event class PdfFileViewModelFactory(private val content: Content) : ViewModelProvider.NewInstanceFactory() { @@ -43,45 +48,67 @@ class PdfFileViewModelFactory(private val content: Content) : class PdfFileViewModel(content: Content) : FileViewerViewModel(content) { val operationInProgress = MutableLiveData() - private val pdfRenderer: PdfRenderer + val rendererReady = MutableLiveData>() + + private lateinit var pdfRenderer: PdfRenderer init { operationInProgress.value = false - val input = ParcelFileDescriptor.open(File(filePath), ParcelFileDescriptor.MODE_READ_ONLY) - pdfRenderer = PdfRenderer(input) - Log.i("[PDF Viewer] ${pdfRenderer.pageCount} pages in file $filePath") + viewModelScope.launch { + withContext(Dispatchers.IO) { + val input = ParcelFileDescriptor.open( + File(filePath), + ParcelFileDescriptor.MODE_READ_ONLY + ) + pdfRenderer = PdfRenderer(input) + Log.i("[PDF Viewer] ${pdfRenderer.pageCount} pages in file $filePath") + rendererReady.postValue(Event(true)) + } + } } override fun onCleared() { - pdfRenderer.close() + if (this::pdfRenderer.isInitialized) { + pdfRenderer.close() + } super.onCleared() } fun getPagesCount(): Int { - return pdfRenderer.pageCount + if (this::pdfRenderer.isInitialized) { + return pdfRenderer.pageCount + } + return 0 } fun loadPdfPageInto(index: Int, view: ImageView) { - try { - operationInProgress.value = true + viewModelScope.launch { + withContext(Dispatchers.IO) { + try { + operationInProgress.postValue(true) - val page: PdfRenderer.Page = pdfRenderer.openPage(index) - val width = if (coreContext.screenWidth <= coreContext.screenHeight) coreContext.screenWidth else coreContext.screenHeight - val bm = Bitmap.createBitmap( - width.toInt(), - (width / page.width * page.height).toInt(), - Bitmap.Config.ARGB_8888 - ) - page.render(bm, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) - page.close() + val page: PdfRenderer.Page = pdfRenderer.openPage(index) + val width = + if (coreContext.screenWidth <= coreContext.screenHeight) coreContext.screenWidth else coreContext.screenHeight + val bm = Bitmap.createBitmap( + width.toInt(), + (width / page.width * page.height).toInt(), + Bitmap.Config.ARGB_8888 + ) + page.render(bm, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) + page.close() - view.setImageBitmap(bm) + withContext(Dispatchers.Main) { + view.setImageBitmap(bm) + } - operationInProgress.value = false - } catch (e: Exception) { - Log.e("[PDF Viewer] Exception: $e") - operationInProgress.value = false + operationInProgress.postValue(false) + } catch (e: Exception) { + Log.e("[PDF Viewer] Exception: $e") + operationInProgress.postValue(false) + } + } } } } diff --git a/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt b/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt index fd79d5f6f..56aa44dbc 100644 --- a/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt @@ -47,17 +47,10 @@ class TextFileViewModel(content: Content) : FileViewerViewModel(content) { val text = MutableLiveData() init { - operationInProgress.value = false - - openFile() - } - - private fun openFile() { - operationInProgress.value = true - viewModelScope.launch { withContext(Dispatchers.IO) { try { + operationInProgress.postValue(true) val br = BufferedReader(FileReader(filePath)) var line: String? val textBuilder = StringBuilder() From 5ee917841694732242af14427ba1180533374b7b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 3 Jul 2023 18:11:01 +0200 Subject: [PATCH 64/94] Forgot to hide chat button from call menu when disable_chat is set --- .../linphone/activities/voip/viewmodels/ControlsViewModel.kt | 3 +++ app/src/main/res/layout/voip_buttons_extra.xml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt index f3d1cc9fd..9b275658f 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt @@ -81,6 +81,8 @@ class ControlsViewModel : ViewModel() { val attendedTransfer = MutableLiveData() + val chatDisabled = MutableLiveData() + val goToConferenceParticipantsListEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -206,6 +208,7 @@ class ControlsViewModel : ViewModel() { init { coreContext.core.addListener(listener) + chatDisabled.value = corePreferences.disableChat fullScreenMode.value = false extraButtonsMenuTranslateY.value = AppUtils.getDimension( R.dimen.voip_call_extra_buttons_translate_y diff --git a/app/src/main/res/layout/voip_buttons_extra.xml b/app/src/main/res/layout/voip_buttons_extra.xml index 4e22786c2..36a7cf554 100644 --- a/app/src/main/res/layout/voip_buttons_extra.xml +++ b/app/src/main/res/layout/voip_buttons_extra.xml @@ -68,6 +68,7 @@ android:layout_centerInParent="true" android:gravity="center" android:onClick="@{() -> controlsViewModel.goToChat()}" + android:visibility="@{controlsViewModel.chatDisabled ? View.INVISIBLE : View.VISIBLE}" android:text="@string/call_action_chat" app:drawableTopCompat="@drawable/icon_call_chat" app:layout_constraintBottom_toTopOf="@id/calls" @@ -86,7 +87,7 @@ android:gravity="center" android:text="@{String.valueOf(callsViewModel.currentCallUnreadChatMessageCount), default=1}" android:translationY="@{controlsViewModel.bouncyCounterTranslateY}" - android:visibility="@{callsViewModel.currentCallUnreadChatMessageCount == 0 ? View.GONE : View.VISIBLE}" + android:visibility="@{callsViewModel.currentCallUnreadChatMessageCount == 0 || controlsViewModel.chatDisabled ? View.GONE : View.VISIBLE}" app:layout_constraintEnd_toEndOf="@id/chat" app:layout_constraintStart_toStartOf="@id/chat" app:layout_constraintTop_toTopOf="@id/chat" /> From 926413992b96b02e7da4b6ad49d81b3da0b51955 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 10 Jul 2023 12:31:30 +0200 Subject: [PATCH 65/94] Fixed crash when device boots on Android 14 --- app/src/main/AndroidManifest.xml | 2 +- .../java/org/linphone/LinphoneApplication.kt | 7 ++-- .../compatibility/Api31Compatibility.kt | 4 +++ .../java/org/linphone/core/CoreService.kt | 33 +++++++++++-------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9b1f7e6fc..6a3574000 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -175,7 +175,7 @@ diff --git a/app/src/main/java/org/linphone/LinphoneApplication.kt b/app/src/main/java/org/linphone/LinphoneApplication.kt index 87e435932..2a08ce958 100644 --- a/app/src/main/java/org/linphone/LinphoneApplication.kt +++ b/app/src/main/java/org/linphone/LinphoneApplication.kt @@ -80,7 +80,8 @@ class LinphoneApplication : Application(), ImageLoaderFactory { context: Context, pushReceived: Boolean = false, service: CoreService? = null, - useAutoStartDescription: Boolean = false + useAutoStartDescription: Boolean = false, + skipCoreStart: Boolean = false ): Boolean { if (::coreContext.isInitialized && !coreContext.stopped) { Log.d("[Application] Skipping Core creation (push received? $pushReceived)") @@ -96,7 +97,9 @@ class LinphoneApplication : Application(), ImageLoaderFactory { service, useAutoStartDescription ) - coreContext.start() + if (!skipCoreStart) { + coreContext.start() + } return true } diff --git a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt index 457e3c60e..1afb8cfbf 100644 --- a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt @@ -264,6 +264,8 @@ class Api31Compatibility { Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") } catch (se: SecurityException) { Log.e("[Api31 Compatibility] Can't start service as foreground! $se") + } catch (e: Exception) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $e") } } @@ -274,6 +276,8 @@ class Api31Compatibility { Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") } catch (se: SecurityException) { Log.e("[Api31 Compatibility] Can't start service as foreground! $se") + } catch (e: Exception) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $e") } } diff --git a/app/src/main/java/org/linphone/core/CoreService.kt b/app/src/main/java/org/linphone/core/CoreService.kt index a6d798ade..5cc609cfd 100644 --- a/app/src/main/java/org/linphone/core/CoreService.kt +++ b/app/src/main/java/org/linphone/core/CoreService.kt @@ -38,24 +38,29 @@ class CoreService : CoreService() { if (corePreferences.keepServiceAlive) { Log.i("[Service] Starting as foreground to keep app alive in background") - if (!ensureCoreExists( - applicationContext, - pushReceived = false, - service = this, - useAutoStartDescription = false - ) - ) { + val contextCreated = ensureCoreExists( + applicationContext, + pushReceived = false, + service = this, + useAutoStartDescription = false + ) + if (!contextCreated) { + // Only start foreground notification if context already exists, otherwise context will do it itself coreContext.notificationsManager.startForeground(this, false) } } else if (intent?.extras?.get("StartForeground") == true) { Log.i("[Service] Starting as foreground due to device boot or app update") - if (!ensureCoreExists( - applicationContext, - pushReceived = false, - service = this, - useAutoStartDescription = true - ) - ) { + val contextCreated = ensureCoreExists( + applicationContext, + pushReceived = false, + service = this, + useAutoStartDescription = true, + skipCoreStart = true + ) + if (contextCreated) { + coreContext.start() + } else { + // Only start foreground notification if context already exists, otherwise context will do it itself coreContext.notificationsManager.startForeground(this, true) } coreContext.checkIfForegroundServiceNotificationCanBeRemovedAfterDelay(5000) From 20ac33a22e66e0d16c452e60ddc2368c15692c90 Mon Sep 17 00:00:00 2001 From: Andras Sohar Date: Fri, 30 Jun 2023 05:39:46 +0000 Subject: [PATCH 66/94] Translated using Weblate (Hungarian) Currently translated at 76.7% (617 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/hu/ --- app/src/main/res/values-hu/strings.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 7dd943381..4f1c4fb6b 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -582,4 +582,25 @@ Segítsen nekünk a &appName; fordításában Megértettem Egyes szolgáltatásokhoz egy &appName; fiók kellene, például csoportos üzeneteket vagy elmúló üzeneteket.\n\nEzek a szolgáltatások el vannak rejtve, ha külső SIP-fiókkal regisztrál.\n\nHa engedélyezni szeretné egy kereskedelmi projektben, vegye fel velünk a kapcsolatot. + Ez a Névjegy nem törölhető + A hívás továbbítva + A hívás nem átirányítható + Értesítések engedélyezése + Kérem várjon a letöltéssel amíg az előző befejeződik + A hangüzenetet rögzítettük + Hangüzenet + Elérhető + A mai napon elérhető + Tegnap elérhető + Elrhető a + Elfoglalt + Ne zavarj + A felvétel exportálása a … + Értekezlet + Értekezlet ütemezése + Csoportos hívás indítása + Nincs értekezlet hívás az ön előzményeiben + További találatok érhetők el, finomítsa a keresést + Menj a Névjegyhez + Értesítések letiltása \ No newline at end of file From 1c28b688c96dbfb6b7cd09b15f236668d138b264 Mon Sep 17 00:00:00 2001 From: Rob Vermeulen= Date: Thu, 6 Jul 2023 08:53:25 +0000 Subject: [PATCH 67/94] Translated using Weblate (Dutch) Currently translated at 20.5% (165 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/nl/ --- app/src/main/res/values-nl/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 7276f38cc..a4a628afe 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -138,7 +138,14 @@ Meer resultaten zijn beschikbaar, verfijn jouw zoekopdracht Beveiligingsniveau verminderd door %s SIP adressen - Email + E-mail UDP Hallo, doe mee met &appName;! Je kan gratis downloaden op %s + Account aanmaken + Antwoord + Doorsturen + Verwijderen + %s: + Downloaden + Gebruikersnaam (optioneel) \ No newline at end of file From 794233c25a74cdacf5f450405475ea726d6bf6de Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 10 Jul 2023 13:10:44 +0200 Subject: [PATCH 68/94] Bumped version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 33042a009..0f7d4547f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ plugins { } def appVersionName = "5.1.0" -def appVersionCode = 50090 +def appVersionCode = 50091 static def getPackageName() { return "org.linphone" From d623b597b5558b56ef7154cc810c6a7c5edb206e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 11 Jul 2023 15:09:42 +0200 Subject: [PATCH 69/94] Renamed variable to increase code readability --- .../main/contact/viewmodels/ContactsListViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt index 24f6b6e0d..b8ee133d9 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactsListViewModel.kt @@ -119,17 +119,17 @@ class ContactsListViewModel : ViewModel() { previousFilter = filterValue val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else "" - val filter = MagicSearchSource.Friends.toInt() or MagicSearchSource.LdapServers.toInt() + val sources = MagicSearchSource.Friends.toInt() or MagicSearchSource.LdapServers.toInt() val aggregation = MagicSearchAggregation.Friend searchResultsPending = true fastFetchJob?.cancel() Log.i( - "[Contacts] Asking Magic search for contacts matching filter [$filterValue], domain [$domain] and in sources [$filter]" + "[Contacts] Asking Magic search for contacts matching filter [$filterValue], domain [$domain] and in sources [$sources]" ) coreContext.contactsManager.magicSearch.getContactsListAsync( filterValue, domain, - filter, + sources, aggregation ) From 0ee446ffcef960e8c18743174aa769d749e653ed Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 17 Jul 2023 17:31:58 +0200 Subject: [PATCH 70/94] Update country name when prefix is manually changed --- .../activities/assistant/fragments/AccountLoginFragment.kt | 4 ++++ .../assistant/fragments/PhoneAccountCreationFragment.kt | 4 ++++ .../assistant/fragments/PhoneAccountLinkingFragment.kt | 4 ++++ .../activities/assistant/viewmodels/AbstractPhoneViewModel.kt | 2 +- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/activities/assistant/fragments/AccountLoginFragment.kt b/app/src/main/java/org/linphone/activities/assistant/fragments/AccountLoginFragment.kt index abee404c6..e9a35b94b 100644 --- a/app/src/main/java/org/linphone/activities/assistant/fragments/AccountLoginFragment.kt +++ b/app/src/main/java/org/linphone/activities/assistant/fragments/AccountLoginFragment.kt @@ -75,6 +75,10 @@ class AccountLoginFragment : AbstractPhoneFragment + viewModel.getCountryNameFromPrefix(internationalPrefix) + } + viewModel.goToSmsValidationEvent.observe( viewLifecycleOwner ) { diff --git a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountCreationFragment.kt b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountCreationFragment.kt index 005a8d8d1..4f285e8b5 100644 --- a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountCreationFragment.kt +++ b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountCreationFragment.kt @@ -62,6 +62,10 @@ class PhoneAccountCreationFragment : countryPickerFragment.show(childFragmentManager, "CountryPicker") } + viewModel.prefix.observe(viewLifecycleOwner) { internationalPrefix -> + viewModel.getCountryNameFromPrefix(internationalPrefix) + } + viewModel.goToSmsValidationEvent.observe( viewLifecycleOwner ) { diff --git a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountLinkingFragment.kt b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountLinkingFragment.kt index c543ebc94..d8fd87e22 100644 --- a/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountLinkingFragment.kt +++ b/app/src/main/java/org/linphone/activities/assistant/fragments/PhoneAccountLinkingFragment.kt @@ -73,6 +73,10 @@ class PhoneAccountLinkingFragment : AbstractPhoneFragment + viewModel.getCountryNameFromPrefix(internationalPrefix) + } + viewModel.goToSmsValidationEvent.observe( viewLifecycleOwner ) { diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt index f17515b04..aabbc44c9 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt @@ -69,7 +69,7 @@ abstract class AbstractPhoneViewModel(accountCreator: AccountCreator) : } } - private fun getCountryNameFromPrefix(prefix: String?) { + fun getCountryNameFromPrefix(prefix: String?) { if (!prefix.isNullOrEmpty()) { val countryCode = if (prefix.first() == '+') prefix.substring(1) else prefix val dialPlan = PhoneNumberUtils.getDialPlanFromCountryCallingPrefix(countryCode) From 8b56d6137dca2da3b696091fa9f41db1137162ed Mon Sep 17 00:00:00 2001 From: Stanislav Bukovetskiy Date: Wed, 12 Jul 2023 09:56:35 +0000 Subject: [PATCH 71/94] Translated using Weblate (Russian) Currently translated at 100.0% (804 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/ru/ --- app/src/main/res/values-ru/strings.xml | 80 +++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 081ea0ab9..55e06d474 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -608,7 +608,7 @@ Этот звонок записывается. Звонок был приостановлен удалённо. Направить звук на устройство Bluetooth, если таковое имеется - Получать уведомления, когда звонок записывается вашим корреспондентом + Получать уведомления, когда звонок записывается вашим собеседником Метод аутентификации Анонимный Авто @@ -740,4 +740,80 @@ Участники (%d) Начать групповой звонок Входящий групповой звонок - + Перейти к контакту + Отключить уведомления + Отправить обновление через &appName; + Отправить обновление по электронной почте + Шифрование медиа: + Алгоритм согласования ключей: + Ваша учетная запись еще не активирована, пожалуйста, перейдите по ссылке, которую вы получили по электронной почте + Пожалуйста, введите свой пароль ниже, чтобы получить доступ к настройкам + Неверный пароль! + URL сервера ключей шифрования E2E + Ваша учетная запись будет удалена только локально. +\nЧтобы удалить её навсегда, перейдите на веб-сайт вашего SIP-провайдера. + Вы хотите загрузить и применить конфигурацию с этого URL-адреса\? + Требуется аутентификация + Подтвердить + Разрешение, необходимое для отображения входящих вызовов, еще не предоставлено + Уведомления для этого разговора отключены + Пользователь в сети + Завершенных встреч пока нет. + Хотите начать групповой звонок\? +\nВсе участники этой группы получат приглашение присоединиться к встрече. + Похоже, ваше устройство не может получать push-уведомления. +\n +\nПоскольку теперь они требуются для процесса создания учетной записи, вы не сможете создать учетную запись внутри приложения, но вы можете создать ее на нашем веб-сайте: + Ошибка подключения, так как аутентификация отсутствует или недействительна для учетной записи +\n%s. +\n +\nВы можете ввести пароль еще раз или проверить конфигурацию своей учетной записи в настройках. + Сопровождаемый перевод + Постквантовый ZRTP + Отключить режим объединения + Чтобы создать учетную запись с помощью электронной почты: + Для повышения уровня безопасности вы можете уточнить следующие коды у своего собеседника. + This should be translatable=false . See other languages + Переключить видимость выбора эмодзи + Позже + Верно + Экспорт записи + Показать + Приложение к собранию + Пользователь не в сети + Пользователь просит не беспокоить + Непредвиденная ошибка… + Включить уведомления + Вы получили голосовое сообщение + Голосовое сообщение + Онлайн + Онлайн сегодня в + Онлайн вчера в + Онлайн в + Далеко + Не беспокоить + Экспорт записи с помощью… + Редактировать встречу + Встреча обновлена: + Встреча отменена: + Начать + Завершенный + Запланированный + Вы хотите удалить эти встречи\? + Конференция отменена организатором + Вы отменили конференцию + Групповой звонок + Снимок сделан: %s + Алгоритм шифрования: + Алгоритм хэширования: + Алгоритм аутентификации: + Алгоритм SAS: + Пароль + Программное подавление эха + Подтвердить + Вы хотите удалить свою учетную запись\? + Ваша учетная запись будет удалена только локально. +\nЧтобы удалить её навсегда, перейдите на нашу платформу управления учетными записями: + Опубликовать информацию о присутствии + Применить + \ No newline at end of file From 44ef7aa142ca7235f9804a970c81b8098547db72 Mon Sep 17 00:00:00 2001 From: Stanislav Bukovetskiy Date: Mon, 17 Jul 2023 10:07:05 +0000 Subject: [PATCH 72/94] Translated using Weblate (Russian) Currently translated at 100.0% (804 of 804 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/ru/ --- app/src/main/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 55e06d474..e5f9db4a2 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -773,7 +773,7 @@ Отключить режим объединения Чтобы создать учетную запись с помощью электронной почты: Для повышения уровня безопасности вы можете уточнить следующие коды у своего собеседника. - This should be translatable=false . See other languages + %s: Переключить видимость выбора эмодзи Позже Верно From 7e694af88f5779edd9d153dbc1537bb6ec4ea486 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 20 Jul 2023 11:41:05 +0200 Subject: [PATCH 73/94] Fixed translation issue + updated locales list --- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/xml/locales_config.xml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index e5f9db4a2..ae99b75b7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -742,7 +742,7 @@ Входящий групповой звонок Перейти к контакту Отключить уведомления - Отправить обновление через &appName; + Отправить обновление через &appName; Отправить обновление по электронной почте Шифрование медиа: Алгоритм согласования ключей: diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml index 7f67f3994..43cb1e034 100644 --- a/app/src/main/res/xml/locales_config.xml +++ b/app/src/main/res/xml/locales_config.xml @@ -1,9 +1,10 @@ - + + @@ -14,6 +15,7 @@ + From 35944bb3a1ea1fd499fb2830bf00ea2be46dcb74 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 20 Jul 2023 13:27:11 +0200 Subject: [PATCH 74/94] Improved check on prefix in assitant + fixed some logs missing assitant tag --- .../viewmodels/AbstractPhoneViewModel.kt | 6 ++- .../viewmodels/AccountLoginViewModel.kt | 6 ++- .../EchoCancellerCalibrationViewModel.kt | 8 ++-- .../EmailAccountCreationViewModel.kt | 14 +++---- .../EmailAccountValidationViewModel.kt | 2 +- .../viewmodels/GenericLoginViewModel.kt | 4 +- .../PhoneAccountCreationViewModel.kt | 40 ++++++++++++++----- .../PhoneAccountLinkingViewModel.kt | 17 ++++---- .../assistant/viewmodels/QrCodeViewModel.kt | 6 +-- .../viewmodels/RemoteProvisioningViewModel.kt | 2 +- .../org/linphone/utils/DataBindingUtils.kt | 12 +++++- .../assistant_account_login_fragment.xml | 1 + ...istant_phone_account_creation_fragment.xml | 1 + ...sistant_phone_account_linking_fragment.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 16 files changed, 84 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt index aabbc44c9..605b0c5ce 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AbstractPhoneViewModel.kt @@ -32,6 +32,7 @@ abstract class AbstractPhoneViewModel(accountCreator: AccountCreator) : CountryPickerFragment.CountryPickedListener { val prefix = MutableLiveData() + val prefixError = MutableLiveData() val phoneNumber = MutableLiveData() val phoneNumberError = MutableLiveData() @@ -48,7 +49,10 @@ abstract class AbstractPhoneViewModel(accountCreator: AccountCreator) : } fun isPhoneNumberOk(): Boolean { - return prefix.value.orEmpty().isNotEmpty() && phoneNumber.value.orEmpty().isNotEmpty() && phoneNumberError.value.orEmpty().isEmpty() + return prefix.value.orEmpty().length > 1 && // Not just '+' character + prefixError.value.orEmpty().isEmpty() && + phoneNumber.value.orEmpty().isNotEmpty() && + phoneNumberError.value.orEmpty().isEmpty() } fun updateFromPhoneNumberAndOrDialPlan(number: String?, dialPlan: DialPlan?) { diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt index 8bca89dbb..579a76eb7 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/AccountLoginViewModel.kt @@ -46,7 +46,7 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM val password = MutableLiveData() val passwordError = MutableLiveData() - val loginEnabled: MediatorLiveData = MediatorLiveData() + val loginEnabled = MediatorLiveData() val waitForServerAnswer = MutableLiveData() @@ -140,6 +140,9 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM loginEnabled.addSource(phoneNumberError) { loginEnabled.value = isLoginButtonEnabled() } + loginEnabled.addSource(prefixError) { + loginEnabled.value = isLoginButtonEnabled() + } } override fun onCleared() { @@ -149,6 +152,7 @@ class AccountLoginViewModel(accountCreator: AccountCreator) : AbstractPhoneViewM override fun onFlexiApiTokenReceived() { Log.i("[Assistant] [Account Login] Using FlexiAPI auth token [${accountCreator.token}]") + waitForServerAnswer.value = false loginWithPhoneNumber() } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EchoCancellerCalibrationViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EchoCancellerCalibrationViewModel.kt index 9b5c54df8..09d01c069 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EchoCancellerCalibrationViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EchoCancellerCalibrationViewModel.kt @@ -51,16 +51,16 @@ class EchoCancellerCalibrationViewModel : ViewModel() { coreContext.core.removeListener(listener) when (status) { EcCalibratorStatus.DoneNoEcho -> { - Log.i("[Echo Canceller Calibration] Done, no echo") + Log.i("[Assistant] [Echo Canceller Calibration] Done, no echo") } EcCalibratorStatus.Done -> { - Log.i("[Echo Canceller Calibration] Done, delay is ${delay}ms") + Log.i("[Assistant] [Echo Canceller Calibration] Done, delay is ${delay}ms") } EcCalibratorStatus.Failed -> { - Log.w("[Echo Canceller Calibration] Failed") + Log.w("[Assistant] [Echo Canceller Calibration] Failed") } EcCalibratorStatus.InProgress -> { - Log.i("[Echo Canceller Calibration] In progress") + Log.i("[Assistant] [Echo Canceller Calibration] In progress") } } echoCalibrationTerminated.value = Event(true) diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountCreationViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountCreationViewModel.kt index 08b6f4ab7..dea25074d 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountCreationViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountCreationViewModel.kt @@ -72,7 +72,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu status: AccountCreator.Status, response: String? ) { - Log.i("[Account Creation] onIsAccountExist status is $status") + Log.i("[Assistant] [Account Creation] onIsAccountExist status is $status") when (status) { AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> { waitForServerAnswer.value = false @@ -99,7 +99,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu status: AccountCreator.Status, response: String? ) { - Log.i("[Account Creation] onCreateAccount status is $status") + Log.i("[Assistant] [Account Creation] onCreateAccount status is $status") waitForServerAnswer.value = false when (status) { @@ -149,11 +149,11 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu } override fun onFlexiApiTokenReceived() { - Log.i("[Account Creation] Using FlexiAPI auth token [${accountCreator.token}]") + Log.i("[Assistant] [Account Creation] Using FlexiAPI auth token [${accountCreator.token}]") waitForServerAnswer.value = true val status = accountCreator.isAccountExist - Log.i("[Account Creation] Account exists returned $status") + Log.i("[Assistant] [Account Creation] Account exists returned $status") if (status != AccountCreator.Status.RequestOk) { waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") @@ -161,7 +161,7 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu } override fun onFlexiApiTokenRequestError() { - Log.e("[Account Creation] Failed to get an auth token from FlexiAPI") + Log.e("[Assistant] [Account Creation] Failed to get an auth token from FlexiAPI") waitForServerAnswer.value = false onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server") } @@ -175,11 +175,11 @@ class EmailAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPu val token = accountCreator.token.orEmpty() if (token.isNotEmpty()) { Log.i( - "[Account Creation] We already have an auth token from FlexiAPI [$token], continue" + "[Assistant] [Account Creation] We already have an auth token from FlexiAPI [$token], continue" ) onFlexiApiTokenReceived() } else { - Log.i("[Account Creation] Requesting an auth token from FlexiAPI") + Log.i("[Assistant] [Account Creation] Requesting an auth token from FlexiAPI") waitForServerAnswer.value = true requestFlexiApiToken() } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountValidationViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountValidationViewModel.kt index 52fffbb26..bc72fbc90 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountValidationViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/EmailAccountValidationViewModel.kt @@ -57,7 +57,7 @@ class EmailAccountValidationViewModel(val accountCreator: AccountCreator) : View status: AccountCreator.Status, response: String? ) { - Log.i("[Account Validation] onIsAccountActivated status is $status") + Log.i("[Assistant] [Account Validation] onIsAccountActivated status is $status") waitForServerAnswer.value = false when (status) { diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt index 153db0671..5e0e50dfe 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/GenericLoginViewModel.kt @@ -152,6 +152,8 @@ class GenericLoginViewModel(private val accountCreator: AccountCreator) : ViewMo } private fun isLoginButtonEnabled(): Boolean { - return username.value.orEmpty().isNotEmpty() && domain.value.orEmpty().isNotEmpty() && password.value.orEmpty().isNotEmpty() + return username.value.orEmpty().isNotEmpty() && + domain.value.orEmpty().isNotEmpty() && + password.value.orEmpty().isNotEmpty() } } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountCreationViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountCreationViewModel.kt index a857cd1c3..03b6face3 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountCreationViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountCreationViewModel.kt @@ -68,7 +68,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh status: AccountCreator.Status, response: String? ) { - Log.i("[Phone Account Creation] onIsAccountExist status is $status") + Log.i("[Assistant] [Phone Account Creation] onIsAccountExist status is $status") when (status) { AccountCreator.Status.AccountExist, AccountCreator.Status.AccountExistWithAlias -> { waitForServerAnswer.value = false @@ -92,7 +92,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh status: AccountCreator.Status, response: String? ) { - Log.i("[Phone Account Creation] onIsAliasUsed status is $status") + Log.i("[Assistant] [Phone Account Creation] onIsAliasUsed status is $status") when (status) { AccountCreator.Status.AliasExist -> { waitForServerAnswer.value = false @@ -114,7 +114,9 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh } AccountCreator.Status.AliasNotExist -> { val createAccountStatus = creator.createAccount() - Log.i("[Phone Account Creation] createAccount returned $createAccountStatus") + Log.i( + "[Assistant] [Phone Account Creation] createAccount returned $createAccountStatus" + ) if (createAccountStatus != AccountCreator.Status.RequestOk) { waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") @@ -132,7 +134,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh status: AccountCreator.Status, response: String? ) { - Log.i("[Phone Account Creation] onCreateAccount status is $status") + Log.i("[Assistant] [Phone Account Creation] onCreateAccount status is $status") waitForServerAnswer.value = false when (status) { AccountCreator.Status.AccountCreated -> { @@ -173,6 +175,9 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh createEnabled.addSource(phoneNumberError) { createEnabled.value = isCreateButtonEnabled() } + createEnabled.addSource(prefixError) { + createEnabled.value = isCreateButtonEnabled() + } } override fun onCleared() { @@ -181,9 +186,22 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh } override fun onFlexiApiTokenReceived() { - Log.i("[Phone Account Creation] Using FlexiAPI auth token [${accountCreator.token}]") + Log.i( + "[Assistant] [Phone Account Creation] Using FlexiAPI auth token [${accountCreator.token}]" + ) accountCreator.displayName = displayName.value - accountCreator.setPhoneNumber(phoneNumber.value, prefix.value) + + val result = AccountCreator.PhoneNumberStatus.fromInt( + accountCreator.setPhoneNumber(phoneNumber.value, prefix.value) + ) + if (result != AccountCreator.PhoneNumberStatus.Ok) { + Log.e( + "[Assistant] [Phone Account Creation] Error [$result] setting the phone number: ${phoneNumber.value} with prefix: ${prefix.value}" + ) + phoneNumberError.value = result.name + return + } + Log.i("[Assistant] [Phone Account Creation] Phone number is ${accountCreator.phoneNumber}") if (useUsername.value == true) { accountCreator.username = username.value @@ -199,14 +217,14 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh } override fun onFlexiApiTokenRequestError() { - Log.e("[Phone Account Creation] Failed to get an auth token from FlexiAPI") + Log.e("[Assistant] [Phone Account Creation] Failed to get an auth token from FlexiAPI") waitForServerAnswer.value = false onErrorEvent.value = Event("Error: Failed to get an auth token from account manager server") } private fun checkUsername() { val status = accountCreator.isAccountExist - Log.i("[Phone Account Creation] isAccountExist returned $status") + Log.i("[Assistant] [Phone Account Creation] isAccountExist returned $status") if (status != AccountCreator.Status.RequestOk) { waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") @@ -215,7 +233,7 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh private fun checkPhoneNumber() { val status = accountCreator.isAliasUsed - Log.i("[Phone Account Creation] isAliasUsed returned $status") + Log.i("[Assistant] [Phone Account Creation] isAliasUsed returned $status") if (status != AccountCreator.Status.RequestOk) { waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") @@ -226,11 +244,11 @@ class PhoneAccountCreationViewModel(accountCreator: AccountCreator) : AbstractPh val token = accountCreator.token.orEmpty() if (token.isNotEmpty()) { Log.i( - "[Phone Account Creation] We already have an auth token from FlexiAPI [$token], continue" + "[Assistant] [Phone Account Creation] We already have an auth token from FlexiAPI [$token], continue" ) onFlexiApiTokenReceived() } else { - Log.i("[Phone Account Creation] Requesting an auth token from FlexiAPI") + Log.i("[Assistant] [Phone Account Creation] Requesting an auth token from FlexiAPI") waitForServerAnswer.value = true requestFlexiApiToken() } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountLinkingViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountLinkingViewModel.kt index b38b8e86d..78c11c04e 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountLinkingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/PhoneAccountLinkingViewModel.kt @@ -60,12 +60,12 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho status: AccountCreator.Status, response: String? ) { - Log.i("[Phone Account Linking] onIsAliasUsed status is $status") + Log.i("[Assistant] [Phone Account Linking] onIsAliasUsed status is $status") when (status) { AccountCreator.Status.AliasNotExist -> { if (creator.linkAccount() != AccountCreator.Status.RequestOk) { - Log.e("[Phone Account Linking] linkAccount status is $status") + Log.e("[Assistant] [Phone Account Linking] linkAccount status is $status") waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") } @@ -86,7 +86,7 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho status: AccountCreator.Status, response: String? ) { - Log.i("[Phone Account Linking] onLinkAccount status is $status") + Log.i("[Assistant] [Phone Account Linking] onLinkAccount status is $status") waitForServerAnswer.value = false when (status) { @@ -113,6 +113,9 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho linkEnabled.addSource(phoneNumberError) { linkEnabled.value = isLinkButtonEnabled() } + linkEnabled.addSource(prefixError) { + linkEnabled.value = isLinkButtonEnabled() + } } override fun onCleared() { @@ -123,10 +126,10 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho override fun onFlexiApiTokenReceived() { accountCreator.setPhoneNumber(phoneNumber.value, prefix.value) accountCreator.username = username.value - Log.i("[Phone Account Linking] Phone number is ${accountCreator.phoneNumber}") + Log.i("[Assistant] [Phone Account Linking] Phone number is ${accountCreator.phoneNumber}") val status: AccountCreator.Status = accountCreator.isAliasUsed - Log.i("[Phone Account Linking] isAliasUsed returned $status") + Log.i("[Assistant] [Phone Account Linking] isAliasUsed returned $status") if (status != AccountCreator.Status.RequestOk) { waitForServerAnswer.value = false onErrorEvent.value = Event("Error: ${status.name}") @@ -134,12 +137,12 @@ class PhoneAccountLinkingViewModel(accountCreator: AccountCreator) : AbstractPho } override fun onFlexiApiTokenRequestError() { - Log.e("[Phone Account Linking] Failed to get an auth token from FlexiAPI") + Log.e("[Assistant] [Phone Account Linking] Failed to get an auth token from FlexiAPI") waitForServerAnswer.value = false } fun link() { - Log.i("[Phone Account Linking] Requesting an auth token from FlexiAPI") + Log.i("[Assistant] [Phone Account Linking] Requesting an auth token from FlexiAPI") waitForServerAnswer.value = true requestFlexiApiToken() } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/QrCodeViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/QrCodeViewModel.kt index b5daaec35..c0f988d0f 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/QrCodeViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/QrCodeViewModel.kt @@ -34,7 +34,7 @@ class QrCodeViewModel : ViewModel() { private val listener = object : CoreListenerStub() { override fun onQrcodeFound(core: Core, result: String?) { - Log.i("[QR Code] Found [$result]") + Log.i("[Assistant] [QR Code] Found [$result]") if (result != null) qrCodeFoundEvent.postValue(Event(result)) } } @@ -54,7 +54,7 @@ class QrCodeViewModel : ViewModel() { for (camera in coreContext.core.videoDevicesList) { if (camera.contains("Back")) { - Log.i("[QR Code] Found back facing camera: $camera") + Log.i("[Assistant] [QR Code] Found back facing camera: $camera") coreContext.core.videoDevice = camera return } @@ -62,7 +62,7 @@ class QrCodeViewModel : ViewModel() { val first = coreContext.core.videoDevicesList.firstOrNull() if (first != null) { - Log.i("[QR Code] Using first camera found: $first") + Log.i("[Assistant] [QR Code] Using first camera found: $first") coreContext.core.videoDevice = first } } diff --git a/app/src/main/java/org/linphone/activities/assistant/viewmodels/RemoteProvisioningViewModel.kt b/app/src/main/java/org/linphone/activities/assistant/viewmodels/RemoteProvisioningViewModel.kt index b4ec77e13..e137d975e 100644 --- a/app/src/main/java/org/linphone/activities/assistant/viewmodels/RemoteProvisioningViewModel.kt +++ b/app/src/main/java/org/linphone/activities/assistant/viewmodels/RemoteProvisioningViewModel.kt @@ -73,7 +73,7 @@ class RemoteProvisioningViewModel : ViewModel() { fun fetchAndApply() { val url = urlToFetch.value.orEmpty() coreContext.core.provisioningUri = url - Log.w("[Remote Provisioning] Url set to [$url], restarting Core") + Log.w("[Assistant] [Remote Provisioning] Url set to [$url], restarting Core") fetchInProgress.value = true coreContext.core.stop() coreContext.core.start() diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 2da1b8759..0b3f8f8b3 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -593,7 +593,17 @@ fun addPhoneNumberEditTextValidation(editText: EditText, enabled: Boolean) { fun addPrefixEditTextValidation(editText: EditText, enabled: Boolean) { if (!enabled) return editText.addTextChangedListener(object : TextWatcher { - override fun afterTextChanged(s: Editable?) {} + override fun afterTextChanged(s: Editable?) { + val dialPlan = PhoneNumberUtils.getDialPlanFromCountryCallingPrefix( + s.toString().substring(1) + ) + if (dialPlan == null) { + editText.error = + editText.context.getString( + R.string.assistant_error_invalid_international_prefix + ) + } + } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} diff --git a/app/src/main/res/layout/assistant_account_login_fragment.xml b/app/src/main/res/layout/assistant_account_login_fragment.xml index f1b69fd8f..b6051be74 100644 --- a/app/src/main/res/layout/assistant_account_login_fragment.xml +++ b/app/src/main/res/layout/assistant_account_login_fragment.xml @@ -119,6 +119,7 @@ Change la visibilité du selectionneur d\'emoji Permission requise pour afficher les appels entrant non accordée Afficher + Préfixe international inconnu \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5958d297f..b99e5e090 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -422,6 +422,7 @@ Email address is invalid Username has too many characters Account does not exist or password does not match + Wrong international prefix Use your &appName; account From 50178d40debee056769ef3e3b6d8a6a8e62cf9f4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 20 Jul 2023 13:39:29 +0200 Subject: [PATCH 75/94] Bumped version code for public beta --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0f7d4547f..76f3d2a8c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ plugins { } def appVersionName = "5.1.0" -def appVersionCode = 50091 +def appVersionCode = 50092 static def getPackageName() { return "org.linphone" From ed009c9e39300259acf0796ab5f2692f6aafaa6e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 27 Jul 2023 12:09:16 +0200 Subject: [PATCH 76/94] Fixed operation in progress infinit spinner when scheduling a conf without sending invitation by chat --- .../ConferenceSchedulingViewModel.kt | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceSchedulingViewModel.kt b/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceSchedulingViewModel.kt index 04158e19e..47744863a 100644 --- a/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceSchedulingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/conference/viewmodels/ConferenceSchedulingViewModel.kt @@ -89,13 +89,26 @@ class ConferenceSchedulingViewModel : ContactsSelectionViewModel() { address.value = conferenceAddress!! - if (scheduleForLater.value == true && sendInviteViaChat.value == true) { - // Send conference info even when conf is not scheduled for later - // as the conference server doesn't invite participants automatically - val chatRoomParams = LinphoneUtils.getConferenceInvitationsChatRoomParams() - conferenceScheduler.sendInvitations(chatRoomParams) + if (scheduleForLater.value == true) { + if (sendInviteViaChat.value == true) { + // Send conference info even when conf is not scheduled for later + // as the conference server doesn't invite participants automatically + Log.i( + "[Conference Creation] Scheduled conference is ready, sending invitations by chat" + ) + val chatRoomParams = LinphoneUtils.getConferenceInvitationsChatRoomParams() + conferenceScheduler.sendInvitations(chatRoomParams) + } else { + Log.i( + "[Conference Creation] Scheduled conference is ready, we were asked not to send invitations by chat so leaving fragment" + ) + conferenceCreationInProgress.value = false + conferenceCreationCompletedEvent.value = Event(true) + } } else { - // Will be done in coreListener + Log.i("[Conference Creation] Group call is ready, leaving fragment") + conferenceCreationInProgress.value = false + conferenceCreationCompletedEvent.value = Event(true) } } else if (state == ConferenceScheduler.State.Error) { Log.e("[Conference Creation] Failed to create conference!") @@ -134,30 +147,6 @@ class ConferenceSchedulingViewModel : ContactsSelectionViewModel() { } } - private val coreListener: CoreListenerStub = object : CoreListenerStub() { - override fun onCallStateChanged( - core: Core, - call: Call, - state: Call.State?, - message: String - ) { - when (state) { - Call.State.OutgoingProgress -> { - conferenceCreationInProgress.value = false - } - Call.State.End -> { - Log.i("[Conference Creation] Call has ended, leaving waiting room fragment") - conferenceCreationCompletedEvent.value = Event(true) - } - Call.State.Error -> { - Log.w("[Conference Creation] Call has failed, leaving waiting room fragment") - conferenceCreationCompletedEvent.value = Event(true) - } - else -> {} - } - } - } - init { sipContactsSelected.value = true @@ -191,11 +180,9 @@ class ConferenceSchedulingViewModel : ContactsSelectionViewModel() { } conferenceScheduler.addListener(listener) - coreContext.core.addListener(coreListener) } override fun onCleared() { - coreContext.core.removeListener(coreListener) conferenceScheduler.removeListener(listener) participantsData.value.orEmpty().forEach(ConferenceSchedulingParticipantData::destroy) From ed851b76ba85321b9a8a038208967166d167d2b1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 27 Jul 2023 13:28:05 +0200 Subject: [PATCH 77/94] Fixed oval background behind avatar in some phones while in landscape --- .../main/res/layout-land/voip_conference_active_speaker.xml | 4 ++-- app/src/main/res/layout/voip_call_incoming_fragment.xml | 3 ++- app/src/main/res/layout/voip_call_outgoing_fragment.xml | 3 ++- app/src/main/res/layout/voip_conference_active_speaker.xml | 4 ++-- ...conference_participant_remote_active_speaker_miniature.xml | 3 ++- .../layout/voip_conference_participant_remote_audio_only.xml | 3 ++- .../res/layout/voip_conference_participant_remote_grid.xml | 3 ++- app/src/main/res/layout/voip_single_call_fragment.xml | 3 ++- 8 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/src/main/res/layout-land/voip_conference_active_speaker.xml b/app/src/main/res/layout-land/voip_conference_active_speaker.xml index d3cdea714..8106f0a2b 100644 --- a/app/src/main/res/layout-land/voip_conference_active_speaker.xml +++ b/app/src/main/res/layout-land/voip_conference_active_speaker.xml @@ -181,13 +181,13 @@ android:contentDescription="@null" coilVoipContact="@{conferenceViewModel.speakingParticipant}" android:background="@drawable/generated_avatar_bg" - app:layout_constraintDimensionRatio="1:1" app:layout_constraintBottom_toBottomOf="@id/active_speaker_background" app:layout_constraintEnd_toEndOf="@id/active_speaker_background" app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size" app:layout_constraintStart_toStartOf="@id/active_speaker_background" app:layout_constraintTop_toTopOf="@id/active_speaker_background" - app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1" /> + app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" + app:layout_constraintDimensionRatio="1:1"/> Date: Mon, 31 Jul 2023 09:34:16 +0200 Subject: [PATCH 78/94] Bumped dependencies + updated build.gradle a bit --- app/build.gradle | 47 ++++++++++++++++++-------------- app/src/main/AndroidManifest.xml | 1 - build.gradle | 2 +- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 76f3d2a8c..4d8e9d57c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,14 +9,14 @@ plugins { def appVersionName = "5.1.0" def appVersionCode = 50092 -static def getPackageName() { - return "org.linphone" -} +def packageName = "org.linphone" def firebaseAvailable = new File(projectDir.absolutePath +'/google-services.json').exists() def crashlyticsAvailable = new File(projectDir.absolutePath +'/google-services.json').exists() && new File(LinphoneSdkBuildDir + '/libs/').exists() && new File(LinphoneSdkBuildDir + '/libs-debug/').exists() +def extractNativeLibs = false + if (firebaseAvailable) { apply plugin: 'com.google.gms.google-services' } @@ -89,7 +89,7 @@ android { targetSdkVersion 34 versionCode appVersionCode versionName "${project.version}" - applicationId getPackageName() + applicationId packageName } applicationVariants.all { variant -> @@ -101,19 +101,19 @@ android { if (firebaseAvailable) { enableFirebaseService = "true" } + // See https://developer.android.com/studio/releases/gradle-plugin#3-6-0-behavior for why extractNativeLibs is set to true in debug flavor if (variant.buildType.name == "release" || variant.buildType.name == "releaseWithCrashlytics") { - variant.getMergedFlavor().manifestPlaceholders = [linphone_address_mime_type: "vnd.android.cursor.item/vnd." + getPackageName() + ".provider.sip_address", - linphone_file_provider: getPackageName() + ".fileprovider", + variant.getMergedFlavor().manifestPlaceholders = [linphone_address_mime_type: "vnd.android.cursor.item/vnd." + packageName + ".provider.sip_address", + linphone_file_provider: packageName + ".fileprovider", appLabel: "@string/app_name", - firebaseServiceEnabled: enableFirebaseService, - extractNativeLibs: "false"] + firebaseServiceEnabled: enableFirebaseService] } else { - variant.getMergedFlavor().manifestPlaceholders = [linphone_address_mime_type: "vnd.android.cursor.item/vnd." + getPackageName() + ".provider.sip_address", - linphone_file_provider: getPackageName() + ".debug.fileprovider", + variant.getMergedFlavor().manifestPlaceholders = [linphone_address_mime_type: "vnd.android.cursor.item/vnd." + packageName + ".provider.sip_address", + linphone_file_provider: packageName + ".debug.fileprovider", appLabel: "@string/app_name_debug", - firebaseServiceEnabled: enableFirebaseService, - extractNativeLibs: "true"] + firebaseServiceEnabled: enableFirebaseService] + extractNativeLibs = true } } @@ -137,9 +137,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' resValue "string", "linphone_app_branch", gitBranch.toString().trim() - resValue "string", "sync_account_type", getPackageName() + ".sync" - resValue "string", "file_provider", getPackageName() + ".fileprovider" - resValue "string", "linphone_address_mime_type", "vnd.android.cursor.item/vnd." + getPackageName() + ".provider.sip_address" + resValue "string", "sync_account_type", packageName + ".sync" + resValue "string", "file_provider", packageName + ".fileprovider" + resValue "string", "linphone_address_mime_type", "vnd.android.cursor.item/vnd." + packageName + ".provider.sip_address" if (!firebaseAvailable) { resValue "string", "gcm_defaultSenderId", "none" @@ -169,9 +169,9 @@ android { jniDebuggable true resValue "string", "linphone_app_branch", gitBranch.toString().trim() - resValue "string", "sync_account_type", getPackageName() + ".sync" - resValue "string", "file_provider", getPackageName() + ".debug.fileprovider" - resValue "string", "linphone_address_mime_type", "vnd.android.cursor.item/vnd." + getPackageName() + ".provider.sip_address" + resValue "string", "sync_account_type", packageName + ".sync" + resValue "string", "file_provider", packageName + ".debug.fileprovider" + resValue "string", "linphone_address_mime_type", "vnd.android.cursor.item/vnd." + packageName + ".provider.sip_address" resValue "bool", "crashlytics_enabled", crashlyticsAvailable.toString() if (!firebaseAvailable) { @@ -193,6 +193,11 @@ android { } namespace 'org.linphone' + packagingOptions { + jniLibs { + useLegacyPackaging extractNativeLibs + } + } } dependencies { @@ -205,7 +210,7 @@ dependencies { implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06" implementation "androidx.window:window:1.1.0" - def emoji_version = "1.4.0-beta05" + def emoji_version = "1.4.0-rc01" implementation "androidx.emoji2:emoji2:$emoji_version" implementation "androidx.emoji2:emoji2-emojipicker:$emoji_version" @@ -216,7 +221,7 @@ dependencies { implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0" implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation "androidx.gridlayout:gridlayout:1.0.0" - implementation 'androidx.recyclerview:recyclerview:1.3.0' + implementation 'androidx.recyclerview:recyclerview:1.3.1' implementation 'androidx.drawerlayout:drawerlayout:1.2.0' // https://github.com/material-components/material-components-android/blob/master/LICENSE Apache v2.0 @@ -259,7 +264,7 @@ task generateContactsXml(type: Copy) { filter { line -> line .replaceAll('%%AUTO_GENERATED%%', 'This file has been automatically generated, do not edit or commit !') - .replaceAll('%%PACKAGE_NAME%%', getPackageName()) + .replaceAll('%%PACKAGE_NAME%%', packageName) } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6a3574000..e967630ed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -69,7 +69,6 @@ android:label="${appLabel}" android:localeConfig="@xml/locales_config" android:roundIcon="@mipmap/ic_launcher_round" - android:extractNativeLibs="${extractNativeLibs}" android:theme="@style/AppTheme" android:allowNativeHeapPointerTagging="false"> diff --git a/build.gradle b/build.gradle index be35fe70d..6568441f7 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } // for com.github.chrisbanes:PhotoView } dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' + classpath 'com.android.tools.build:gradle:8.1.0' classpath 'com.google.gms:google-services:4.3.15' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.6' From 256a3ed77a0df0307c72810dd7f946e79c058ef3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 31 Jul 2023 10:11:25 +0200 Subject: [PATCH 79/94] Showing confirmation dialog when about to create a new contact without SIP URI nor phone number (won't be displayed) --- .../fragments/ContactEditorFragment.kt | 73 ++++++++++++++++++- app/src/main/res/values-fr/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt b/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt index 94b0d81f9..31c5497ac 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/fragments/ContactEditorFragment.kt @@ -20,6 +20,7 @@ package org.linphone.activities.main.contact.fragments import android.app.Activity +import android.app.Dialog import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle @@ -38,9 +39,11 @@ import org.linphone.activities.main.MainActivity import org.linphone.activities.main.contact.data.ContactEditorData import org.linphone.activities.main.contact.data.NumberOrAddressEditorData import org.linphone.activities.main.contact.viewmodels.* +import org.linphone.activities.main.viewmodels.DialogViewModel import org.linphone.activities.navigateToContact import org.linphone.core.tools.Log import org.linphone.databinding.ContactEditorFragmentBinding +import org.linphone.utils.DialogUtils import org.linphone.utils.FileUtils import org.linphone.utils.PermissionHelper @@ -71,10 +74,38 @@ class ContactEditorFragment : GenericFragment(), S data.syncAccountName = null data.syncAccountType = null - if (data.friend == null && corePreferences.showNewContactAccountDialog) { - Log.i("[Contact Editor] New contact, ask user where to store it") - SyncAccountPickerFragment(this).show(childFragmentManager, "SyncAccountPicker") + if (data.friend == null) { + var atLeastASipAddressOrPhoneNumber = false + for (addr in data.addresses.value.orEmpty()) { + if (addr.newValue.value.orEmpty().isNotEmpty()) { + atLeastASipAddressOrPhoneNumber = true + break + } + } + if (!atLeastASipAddressOrPhoneNumber) { + for (number in data.numbers.value.orEmpty()) { + if (number.newValue.value.orEmpty().isNotEmpty()) { + atLeastASipAddressOrPhoneNumber = true + break + } + } + } + if (!atLeastASipAddressOrPhoneNumber) { + // Contact will be created without phone and SIP address + // Let's warn the user it won't be visible in Linphone app + Log.w( + "[Contact Editor] New contact without SIP address nor phone number, showing warning dialog" + ) + showInvisibleContactWarningDialog() + } else if (corePreferences.showNewContactAccountDialog) { + Log.i("[Contact Editor] New contact, ask user where to store it") + SyncAccountPickerFragment(this).show(childFragmentManager, "SyncAccountPicker") + } else { + Log.i("[Contact Editor] Saving new contact") + saveContact() + } } else { + Log.i("[Contact Editor] Saving contact changes") saveContact() } } @@ -98,7 +129,7 @@ class ContactEditorFragment : GenericFragment(), S } override fun onSyncAccountClicked(name: String?, type: String?) { - Log.i("[Contact Editor] Using account $name / $type") + Log.i("[Contact Editor] Saving new contact using account $name / $type") data.syncAccountName = name data.syncAccountType = type saveContact() @@ -146,6 +177,9 @@ class ContactEditorFragment : GenericFragment(), S Log.i("[Contact Editor] Displaying contact $savedContact") navigateToContact(id) } else { + Log.w( + "[Contact Editor] Can't display $savedContact because it doesn't have a refKey, going back" + ) goBack() } } @@ -183,4 +217,35 @@ class ContactEditorFragment : GenericFragment(), S startActivityForResult(chooserIntent, 0) } + + private fun showInvisibleContactWarningDialog() { + val dialogViewModel = + DialogViewModel(getString(R.string.contacts_new_contact_wont_be_visible_warning_dialog)) + val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel) + + dialogViewModel.showCancelButton( + { + Log.i("[Contact Editor] Aborting new contact saving") + dialog.dismiss() + }, + getString(R.string.no) + ) + + dialogViewModel.showOkButton( + { + dialog.dismiss() + + if (corePreferences.showNewContactAccountDialog) { + Log.i("[Contact Editor] New contact, ask user where to store it") + SyncAccountPickerFragment(this).show(childFragmentManager, "SyncAccountPicker") + } else { + Log.i("[Contact Editor] Saving new contact") + saveContact() + } + }, + getString(R.string.yes) + ) + + dialog.show() + } } diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index ea178ddf8..fbe4a8bfd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -791,4 +791,7 @@ Permission requise pour afficher les appels entrant non accordée Afficher Préfixe international inconnu + Vous êtes sur le point de créer un nouveau contact sans adresse SIP ni numéro de téléphone, il ne sera donc pas visible dans &appName;.\n\nVoulez-vous le créer quand même ? + Oui + Non \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b99e5e090..aa114b4da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -49,6 +49,8 @@ %d days Share logs link using… + Yes + No Unexpected error… @@ -114,6 +116,7 @@ Store locally This contact can\'t be deleted More results are available, refine your search + You are about to create a new contact without a SIP URI nor a phone number, thus it won\'t be visible in &appName;.\n\nDo you want to create it anyway? Enter a number or an address From 546db7355b48a4f9add5ca2792babb711c680e74 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 31 Jul 2023 10:22:34 +0200 Subject: [PATCH 80/94] Small change to see if it improves things on some devices --- .../java/org/linphone/notifications/NotificationsManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index c7a7e2366..6f3a0e4c6 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -285,7 +285,7 @@ class NotificationsManager(private val context: Context) { Log.w( "[Notifications Manager] Found existing call? notification [${notification.id}], cancelling it" ) - manager.cancel(notification.tag, notification.id) + manager.cancel(notification.id) } else if (notification.tag == CHAT_TAG) { Log.i( "[Notifications Manager] Found existing chat notification [${notification.id}]" From d4d95b783523de8d8b92f5fdabe913fbfb251d85 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 1 Aug 2023 17:50:54 +0200 Subject: [PATCH 81/94] Prevent malicious app that could return private file from another package when sharing file in chat --- .../linphone/activities/main/MainActivity.kt | 7 ++++++- .../main/java/org/linphone/utils/FileUtils.kt | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index 11a30793a..900bf6781 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -389,7 +389,12 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin // Prevent this intent to be processed again intent.action = null intent.data = null - intent.extras?.clear() + val extras = intent.extras + if (extras != null) { + for (key in extras.keySet()) { + intent.removeExtra(key) + } + } } private fun handleMainIntent(intent: Intent) { diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index 95c338d5f..7300364c1 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -26,7 +26,10 @@ import android.content.Intent import android.database.CursorIndexOutOfBoundsException import android.net.Uri import android.os.Environment +import android.os.ParcelFileDescriptor +import android.os.Process.myUid import android.provider.OpenableColumns +import android.system.Os.fstat import android.webkit.MimeTypeMap import androidx.core.content.FileProvider import java.io.* @@ -270,6 +273,21 @@ class FileUtils { var result: String? = null val name: String = getNameFromUri(uri, context) + try { + if (fstat( + ParcelFileDescriptor.open( + File(uri.path), + ParcelFileDescriptor.MODE_READ_ONLY + ).fileDescriptor + ).st_uid != myUid() + ) { + Log.e("[File Utils] File descriptor UID different from our, denying copy!") + return result + } + } catch (e: Exception) { + Log.e("[File Utils] Can't check file ownership: ", e) + } + try { val localFile: File = createFile(name) val remoteFile = From c7bb59d991295986022e238a6f0f01b84b4db4a2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 2 Aug 2023 09:55:54 +0200 Subject: [PATCH 82/94] Prevent some issues related to ZRTP SAS confirmation dialog --- .../voip/fragments/SingleCallFragment.kt | 2 +- .../voip/fragments/StatusFragment.kt | 31 +++++++++++++++---- .../voip/viewmodels/StatusViewModel.kt | 31 ++++++++++++++----- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt index 1477dcf92..2f90854af 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt @@ -87,7 +87,7 @@ class SingleCallFragment : GenericVideoPreviewFragment { + Call.State.OutgoingRinging, Call.State.OutgoingEarlyMedia -> { Log.i( "[Single Call] New current call is in [$callState] state, switching to OutgoingCall fragment" ) diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/StatusFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/StatusFragment.kt index 690b2972a..0536d1da6 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/StatusFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/StatusFragment.kt @@ -84,8 +84,11 @@ class StatusFragment : GenericFragment() { private fun showZrtpDialog(call: Call) { if (zrtpDialog != null && zrtpDialog?.isShowing == true) { - Log.e("[Status Fragment] ZRTP dialog already visible") - return + Log.w( + "[Status Fragment] ZRTP dialog already visible, closing it and creating a new one" + ) + zrtpDialog?.dismiss() + zrtpDialog = null } val token = call.authenticationToken @@ -125,8 +128,19 @@ class StatusFragment : GenericFragment() { viewModel.showCancelButton( { - call.authenticationTokenVerified = false - this@StatusFragment.viewModel.updateEncryptionInfo(call) + if (call.state != Call.State.End && call.state != Call.State.Released) { + if (call.authenticationTokenVerified) { + Log.w( + "[Status Fragment] Removing trust from previously verified ZRTP SAS auth token" + ) + this@StatusFragment.viewModel.previouslyDeclineToken = true + call.authenticationTokenVerified = false + } + } else { + Log.e( + "[Status Fragment] Can't decline the ZRTP SAS token, call is in state [${call.state}]" + ) + } dialog.dismiss() zrtpDialog = null }, @@ -135,8 +149,13 @@ class StatusFragment : GenericFragment() { viewModel.showOkButton( { - call.authenticationTokenVerified = true - this@StatusFragment.viewModel.updateEncryptionInfo(call) + if (call.state != Call.State.End && call.state != Call.State.Released) { + call.authenticationTokenVerified = true + } else { + Log.e( + "[Status Fragment] Can't verify the ZRTP SAS token, call is in state [${call.state}]" + ) + } dialog.dismiss() zrtpDialog = null }, diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/StatusViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/StatusViewModel.kt index ab8d3b597..ec2d25fbd 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/StatusViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/StatusViewModel.kt @@ -42,6 +42,8 @@ class StatusViewModel : StatusViewModel() { MutableLiveData>() } + var previouslyDeclineToken = false + private val listener = object : CoreListenerStub() { override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) { updateCallQualityIcon() @@ -54,8 +56,11 @@ class StatusViewModel : StatusViewModel() { authenticationToken: String? ) { updateEncryptionInfo(call) - if (call.currentParams.mediaEncryption == MediaEncryption.ZRTP && !call.authenticationTokenVerified && call.authenticationToken != null) { - showZrtpDialogEvent.value = Event(call) + // Check if we just declined a previously validated token + // In that case, don't show the ZRTP dialog again + if (!previouslyDeclineToken) { + previouslyDeclineToken = false + showZrtpDialog(call) } } @@ -79,10 +84,7 @@ class StatusViewModel : StatusViewModel() { val currentCall = coreContext.core.currentCall if (currentCall != null) { updateEncryptionInfo(currentCall) - - if (currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP && !currentCall.authenticationTokenVerified && currentCall.authenticationToken != null) { - showZrtpDialogEvent.value = Event(currentCall) - } + showZrtpDialog(currentCall) } } @@ -94,8 +96,8 @@ class StatusViewModel : StatusViewModel() { fun showZrtpDialog() { val currentCall = coreContext.core.currentCall - if (currentCall?.authenticationToken != null && currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP) { - showZrtpDialogEvent.value = Event(currentCall) + if (currentCall != null) { + showZrtpDialog(currentCall, force = true) } } @@ -112,6 +114,9 @@ class StatusViewModel : StatusViewModel() { encryptionContentDescription.value = R.string.content_description_call_secured return } + if (call.state == Call.State.End || call.state == Call.State.Released) { + return + } when (call.currentParams.mediaEncryption ?: MediaEncryption.None) { MediaEncryption.SRTP, MediaEncryption.DTLS -> { @@ -139,6 +144,16 @@ class StatusViewModel : StatusViewModel() { } } + private fun showZrtpDialog(call: Call, force: Boolean = false) { + if ( + call.currentParams.mediaEncryption == MediaEncryption.ZRTP && + call.authenticationToken != null && + (!call.authenticationTokenVerified || force) + ) { + showZrtpDialogEvent.value = Event(call) + } + } + private fun updateCallQualityIcon() { val call = coreContext.core.currentCall ?: coreContext.core.calls.firstOrNull() val quality = call?.currentQuality ?: 0f From 023f29cc599ec9a2808718f11ad850cebc695665 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Aug 2023 11:02:32 +0200 Subject: [PATCH 83/94] Fix escaped arobase when starting Linphone by clicking on google's contacts' app SIP field --- app/src/main/AndroidManifest.xml | 7 +------ .../main/java/org/linphone/activities/main/MainActivity.kt | 2 ++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e967630ed..4e6f2a244 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -126,6 +126,7 @@ + @@ -133,12 +134,6 @@ - - - - - - diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index 900bf6781..1fc446783 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -471,6 +471,8 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin } } + addressToCall = addressToCall.replace("%40", "@") + val address = coreContext.core.interpretUrl( addressToCall, LinphoneUtils.applyInternationalPrefix() From 839efbdb7ce32c6836e23ae02126db2950274714 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Aug 2023 15:28:43 +0200 Subject: [PATCH 84/94] Fixed wrong missing incoming call status --- .../activities/main/history/viewmodels/CallLogViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt index a2053cb96..151de6a26 100644 --- a/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/history/viewmodels/CallLogViewModel.kt @@ -44,7 +44,7 @@ class CallLogViewModel(val callLog: CallLog, private val isRelated: Boolean = fa val statusIconResource: Int by lazy { if (callLog.dir == Call.Dir.Incoming) { - if (callLog.status == Call.Status.Missed) { + if (LinphoneUtils.isCallLogMissed(callLog)) { R.drawable.call_status_missed } else { R.drawable.call_status_incoming @@ -56,7 +56,7 @@ class CallLogViewModel(val callLog: CallLog, private val isRelated: Boolean = fa val iconContentDescription: Int by lazy { if (callLog.dir == Call.Dir.Incoming) { - if (callLog.status == Call.Status.Missed) { + if (LinphoneUtils.isCallLogMissed(callLog)) { R.string.content_description_missed_call } else { R.string.content_description_incoming_call @@ -68,7 +68,7 @@ class CallLogViewModel(val callLog: CallLog, private val isRelated: Boolean = fa val directionIconResource: Int by lazy { if (callLog.dir == Call.Dir.Incoming) { - if (callLog.status == Call.Status.Missed) { + if (LinphoneUtils.isCallLogMissed(callLog)) { R.drawable.call_missed } else { R.drawable.call_incoming From f1cfa57f426e90b10bec80f296e06c58c33ea550 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Aug 2023 16:03:15 +0200 Subject: [PATCH 85/94] Fixed call logs details duplicated each time they are displayed --- .../main/history/fragments/DetailCallLogFragment.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/activities/main/history/fragments/DetailCallLogFragment.kt b/app/src/main/java/org/linphone/activities/main/history/fragments/DetailCallLogFragment.kt index ee2e24d1b..8bb760ec9 100644 --- a/app/src/main/java/org/linphone/activities/main/history/fragments/DetailCallLogFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/history/fragments/DetailCallLogFragment.kt @@ -53,7 +53,9 @@ class DetailCallLogFragment : GenericFragment() { viewModel = callLogGroup.lastCallLogViewModel binding.viewModel = viewModel - viewModel.addRelatedCallLogs(callLogGroup.callLogs) + if (viewModel.relatedCallLogs.value.orEmpty().isEmpty()) { + viewModel.addRelatedCallLogs(callLogGroup.callLogs) + } useMaterialSharedAxisXForwardAnimation = sharedViewModel.isSlidingPaneSlideable.value == false From 9b121a026d97def00184707c85ee2b384184b3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Fri, 21 Jul 2023 08:42:16 +0000 Subject: [PATCH 86/94] Translated using Weblate (Czech) Currently translated at 100.0% (805 of 805 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/cs/ --- app/src/main/res/values-cs/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index aba54c2f6..c0e8a1e70 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -814,4 +814,5 @@ Potvrdit Povolení vyžadované pro zobrazení příchozích hovorů zatím nebylo uděleno Zobrazit + Špatná mezinárodní předvolba \ No newline at end of file From 3c2aea7f360e509b72ad697c0ad3287922722d64 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 21 Jul 2023 03:36:37 +0000 Subject: [PATCH 87/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (805 of 805 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 12472f502..34ed9264a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -807,4 +807,5 @@ 切換顯示表情符號選取器 尚未授予顯示來電的必要權限 顯示 + 國際冠碼錯誤 \ No newline at end of file From 1ca444092137c8040131819314ed5a0d813b86d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Libor=20Fil=C3=ADpek?= Date: Tue, 1 Aug 2023 13:39:13 +0000 Subject: [PATCH 88/94] Translated using Weblate (Czech) Currently translated at 100.0% (808 of 808 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/cs/ --- app/src/main/res/values-cs/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index c0e8a1e70..ba2fa4607 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -815,4 +815,9 @@ Povolení vyžadované pro zobrazení příchozích hovorů zatím nebylo uděleno Zobrazit Špatná mezinárodní předvolba + Ano + Ne + Chystáte se vytvořit nový kontakt bez SIP URI ani telefonního čísla, a proto nebude viditelný v seznamu &appName;. +\n +\nChcete jej přesto vytvořit\? \ No newline at end of file From c187643eb13e9a7cc0fbb4bcef4ec0119e6b2de9 Mon Sep 17 00:00:00 2001 From: Stanislav Bukovetskiy Date: Mon, 31 Jul 2023 11:07:34 +0000 Subject: [PATCH 89/94] Translated using Weblate (Russian) Currently translated at 100.0% (808 of 808 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/ru/ --- app/src/main/res/values-ru/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ae99b75b7..405c22c17 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -816,4 +816,10 @@ \nЧтобы удалить её навсегда, перейдите на нашу платформу управления учетными записями: Опубликовать информацию о присутствии Применить + Неправильный международный префикс + Да + Нет + Вы собираетесь создать новый контакт без SIP URI и номера телефона, поэтому он не будет отображаться в &appName;. +\n +\nВы все равно хотите его создать\? \ No newline at end of file From ccd2ce915eebb94af00aef07ff7c5610f0795c0d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Aug 2023 03:42:42 +0000 Subject: [PATCH 90/94] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (808 of 808 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 34ed9264a..d469c3a81 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -808,4 +808,9 @@ 尚未授予顯示來電的必要權限 顯示 國際冠碼錯誤 + + + 您要建立的聯絡人不含 SIP URI 或電話號碼,不會在 &appName; 出現。 +\n +\n還是要建立這位聯絡人嗎? \ No newline at end of file From 248ae2399757c2c6d533ba5114e998f13e9233af Mon Sep 17 00:00:00 2001 From: NPL Date: Sat, 5 Aug 2023 15:12:42 +0000 Subject: [PATCH 91/94] Translated using Weblate (Japanese) Currently translated at 99.1% (801 of 808 strings) Translation: Linphone/Linphone Android (5.1 release) Translate-URL: https://weblate.linphone.org/projects/linphone/linphone-android-5-1-release/ja/ --- app/src/main/res/values-ja/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 19939bee3..e6a67407c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -799,4 +799,13 @@ \n \n再度パスワードを入力するか、設定からアカウントの構成を確認することができます。 アカウントがアクティベートされていません。受信したEメールのリンクを開いてください + 間違った国際プレフィックス + 着信を表示するために必要な権限がまだ付与されていません + 表示 + 絵文字ピッカーの表示を切り替える + Yes + No + SIP URIも電話番号もない新しい連絡先を作成しようとしており、&appName;には表示されません。 +\n +\n本当に作成しますか? \ No newline at end of file From 9e4d75f7f484e23dcc26e29b64c874e8c09ecaba Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Aug 2023 16:21:30 +0200 Subject: [PATCH 92/94] Fixed XML entities in translations --- app/src/main/res/values-cs/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index ba2fa4607..e8640b3cf 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -817,7 +817,7 @@ Špatná mezinárodní předvolba Ano Ne - Chystáte se vytvořit nový kontakt bez SIP URI ani telefonního čísla, a proto nebude viditelný v seznamu &appName;. + Chystáte se vytvořit nový kontakt bez SIP URI ani telefonního čísla, a proto nebude viditelný v seznamu &appName;. \n \nChcete jej přesto vytvořit\? \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index e6a67407c..54fc594b9 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -805,7 +805,7 @@ 絵文字ピッカーの表示を切り替える Yes No - SIP URIも電話番号もない新しい連絡先を作成しようとしており、&appName;には表示されません。 + SIP URIも電話番号もない新しい連絡先を作成しようとしており、&appName;には表示されません。 \n \n本当に作成しますか? \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 405c22c17..e509668d7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -819,7 +819,7 @@ Неправильный международный префикс Да Нет - Вы собираетесь создать новый контакт без SIP URI и номера телефона, поэтому он не будет отображаться в &appName;. + Вы собираетесь создать новый контакт без SIP URI и номера телефона, поэтому он не будет отображаться в &appName;. \n \nВы все равно хотите его создать\? \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d469c3a81..66b427403 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -810,7 +810,7 @@ 國際冠碼錯誤 - 您要建立的聯絡人不含 SIP URI 或電話號碼,不會在 &appName; 出現。 + 您要建立的聯絡人不含 SIP URI 或電話號碼,不會在 &appName; 出現。 \n \n還是要建立這位聯絡人嗎? \ No newline at end of file From 91554f99ff033838c926a3fa9a8d0a452eb0ecb1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Aug 2023 16:29:55 +0200 Subject: [PATCH 93/94] Bumped version code for public beta --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 4d8e9d57c..730cfbfca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ plugins { } def appVersionName = "5.1.0" -def appVersionCode = 50092 +def appVersionCode = 50093 def packageName = "org.linphone" From cfe04dea19e73fccfa086256e7ab2631bbe78929 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 21 Aug 2023 11:14:39 +0200 Subject: [PATCH 94/94] Set correct version code for 5.1.0 release + updated CHANGELOG --- CHANGELOG.md | 2 +- app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a8ec20e7..3d41d1369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Group changes to describe their impact on the project, as follows: Fixed for any bug fixes. Security to invite users to upgrade in case of vulnerabilities. -## [5.1.0] - Unreleased +## [5.1.0] - 2023-08-21 ### Added - Showing short term presence for contacts whom publish it + added setting to disable it (enabled by default for sip.linphone.org accounts) diff --git a/app/build.gradle b/app/build.gradle index 730cfbfca..af3d5c32d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ plugins { } def appVersionName = "5.1.0" -def appVersionCode = 50093 +def appVersionCode = 51000 def packageName = "org.linphone"