Merge tag '2.10.10'

Stephen Paul Weber created

* tag '2.10.10':
  version bump to 2.10.10 + changelog
  pulled translations from transifex
  bump guava library
  use custom libwebrtc (m104) for playstore release
  minor code clean up
  Use the same mechanism for link copying and linkification (#4357)
  Update recommendations for Gajim (#4355)
  Add fastlane changelog (#4354)

Change summary

CHANGELOG.md                                                        |  5 
README.md                                                           | 29 
build.gradle                                                        | 12 
fastlane/metadata/android/en-US/changelogs/42037.txt                | 11 
fastlane/metadata/android/en-US/changelogs/42038.txt                |  2 
src/conversations/AndroidManifest.xml                               |  9 
src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java | 14 
src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java     |  4 
src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java         | 11 
src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java | 11 
src/main/res/values-nl/strings.xml                                  | 46 
src/main/res/values-pl/strings.xml                                  |  2 
src/playstore/AndroidManifest.xml                                   | 24 
13 files changed, 104 insertions(+), 76 deletions(-)

Detailed changes

CHANGELOG.md 🔗

@@ -1,5 +1,10 @@
 # Changelog
 
+### Version 2.10.10
+
+* Minor bug fixes
+* Restore ability to call out via JMP and other services (Playstore version)
+
 ### Version 2.10.9
 
 * Ask for Bluetooth permissions when making A/V calls (You can reject this if you don’t use Bluetooth headsets)

README.md 🔗

@@ -12,32 +12,3 @@ Based on the app Conversations, but with unique features:
 * Integrates with gateways' add contact flows
 * When using a gateway to the phone network, integrate with the native Android Phone app
 * Address book integration
-
-Where to get service:
-
-Cheogram Android requires you have an account with a Jabber service.  You can run your own service, or use one provided by someone else, for example: https://snikket.org/hosting/
-
-Art in screenshots is from https://www.peppercarrot.com by David Revoy, CC-BY. Artwork has been modified to crop out sections for avatars and photos, and in some cases add transparency. Use of this artwork does not imply endorsement of this project by the artist.
-
-## Getting Help
-
-If you have any questions about this app, or wish to report a bug, please come by the chatroom [in your client](xmpp:discuss@conference.soprani.ca?join) or [on the web](https://anonymous.cheogram.com/discuss@conference.soprani.ca).
-
-## Contributing
-
-If you have code or patches you wish to contribute, the maintainer's preferred mechanism is a git pull request.  Push your changes to a git repository somewhere, for example:
-
-    git remote rename origin upstream
-    git remote add origin git@git.sr.ht:~yourname/cheogram-android
-    git push -u origin master
-
-Then generate the pull request:
-
-    git fetch upstream master
-    git request-pull -p upstream/master origin
-
-And copy-paste the result into a plain-text email to: dev@singpolyma.net
-
-You may alternately use a patch-based approach as described on https://git-send-email.io
-
-Contributions follow an inbound=outbound model -- you (or your employer) keep all copyright on your patches, but agree to license them according to this project's COPYING file.

build.gradle 🔗

@@ -6,7 +6,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.2.1'
+        classpath 'com.android.tools.build:gradle:7.2.2'
     }
 }
 
@@ -58,7 +58,7 @@ dependencies {
 
     implementation 'androidx.viewpager:viewpager:1.0.0'
 
-    playstoreImplementation('com.google.firebase:firebase-messaging:23.0.6') {
+    playstoreImplementation('com.google.firebase:firebase-messaging:23.0.7') {
         exclude group: 'com.google.firebase', module: 'firebase-core'
         exclude group: 'com.google.firebase', module: 'firebase-analytics'
         exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
@@ -68,14 +68,14 @@ dependencies {
     quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
     implementation 'org.sufficientlysecure:openpgp-api:10.0'
     implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
-    implementation 'androidx.appcompat:appcompat:1.4.2'
+    implementation 'androidx.appcompat:appcompat:1.5.0'
     implementation 'androidx.exifinterface:exifinterface:1.3.3'
     implementation 'androidx.cardview:cardview:1.0.0'
     implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
     implementation 'com.google.android.material:material:1.4.0'
 
-    implementation "androidx.emoji2:emoji2:1.1.0"
-    freeImplementation "androidx.emoji2:emoji2-bundled:1.1.0"
+    implementation "androidx.emoji2:emoji2:1.2.0"
+    freeImplementation "androidx.emoji2:emoji2-bundled:1.2.0"
 
     implementation 'org.bouncycastle:bcmail-jdk15on:1.64'
     //zxing stopped supporting Java 7 so we have to stick with 3.3.3
@@ -99,7 +99,7 @@ dependencies {
     implementation "com.squareup.retrofit2:converter-gson:2.9.0"
     implementation "com.squareup.okhttp3:okhttp:4.10.0"
 
-    implementation 'com.google.guava:guava:30.1.1-android'
+    implementation 'com.google.guava:guava:31.1-android'
     implementation 'io.michaelrocks:libphonenumber-android:8.12.49'
     implementation 'io.github.nishkarsh:android-permissions:2.1.6'
     implementation 'androidx.recyclerview:recyclerview:1.1.0'

fastlane/metadata/android/en-US/changelogs/42037.txt 🔗

@@ -0,0 +1,11 @@
+Version 2.10.9
+* Ask for Bluetooth permissions when making A/V calls (You can reject this if you don’t use Bluetooth headsets)
+* Fix bug when calling Movim
+* Fix wrong avatar being shown for group chats
+* Always ask for battery optimizations opt-out
+* Set local only flag on 'x connected accounts' notifications
+* Fix interaction with Google Maps Share Location Plugin
+* Remove footnote with regards to server fee
+* Store files in location appropriate for Android 11
+* Attempt to reconnect call after network switch
+* Show caller JID and account JID in incoming call screen

src/conversations/AndroidManifest.xml 🔗

@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <application tools:ignore="GoogleAppIndexingWarning">
+    <application android:icon="@mipmap/new_launcher">
         <activity
             android:name=".ui.ManageAccountActivity"
             android:label="@string/title_activity_manage_accounts"
@@ -25,9 +24,9 @@
             android:launchMode="singleTask" />
         <activity
             android:name=".ui.ImportBackupActivity"
+            android:exported="true"
             android:label="@string/restore_backup"
-            android:launchMode="singleTask"
-            android:exported="true">
+            android:launchMode="singleTask">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />

src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java 🔗

@@ -2,14 +2,14 @@ package eu.siacs.conversations.http;
 
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-import org.jetbrains.annotations.NotNull;
-
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
@@ -132,7 +132,7 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
         this.slotFuture = new SlotRequester(mXmppConnectionService).request(method, account, file, mime);
         Futures.addCallback(this.slotFuture, new FutureCallback<SlotRequester.Slot>() {
             @Override
-            public void onSuccess(@NullableDecl SlotRequester.Slot result) {
+            public void onSuccess(@Nullable SlotRequester.Slot result) {
                 HttpUploadConnection.this.slot = result;
                 try {
                     HttpUploadConnection.this.upload();
@@ -142,7 +142,7 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
             }
 
             @Override
-            public void onFailure(@NotNull final Throwable throwable) {
+            public void onFailure(@NonNull final Throwable throwable) {
                 Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to request slot", throwable);
                 // TODO consider fall back to jingle in 1-on-1 chats with exactly one online presence
                 fail(throwable.getMessage());
@@ -169,13 +169,13 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
         this.mostRecentCall = client.newCall(request);
         this.mostRecentCall.enqueue(new Callback() {
             @Override
-            public void onFailure(@NotNull Call call, IOException e) {
+            public void onFailure(@NonNull Call call, IOException e) {
                 Log.d(Config.LOGTAG, "http upload failed", e);
                 fail(e.getMessage());
             }
 
             @Override
-            public void onResponse(@NotNull Call call, @NotNull Response response)  {
+            public void onResponse(@NonNull Call call, @NonNull Response response)  {
                 final int code = response.code();
                 if (code == 200 || code == 201) {
                     Log.d(Config.LOGTAG, "finished uploading file");

src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java 🔗

@@ -25,6 +25,7 @@ import android.view.WindowManager;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.StringRes;
 import androidx.databinding.DataBindingUtil;
@@ -37,7 +38,6 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
 import org.jetbrains.annotations.NotNull;
 import org.webrtc.RendererCommon;
 import org.webrtc.SurfaceViewRenderer;
@@ -1031,7 +1031,7 @@ public class RtpSessionActivity extends XmppActivity
                 requireRtpConnection().switchCamera(),
                 new FutureCallback<Boolean>() {
                     @Override
-                    public void onSuccess(@NullableDecl Boolean isFrontCamera) {
+                    public void onSuccess(@Nullable Boolean isFrontCamera) {
                         binding.localVideo.setMirror(isFrontCamera);
                     }
 

src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java 🔗

@@ -108,20 +108,19 @@ public class ShareUtil {
 		}
 	}
 
-	public static void copyLinkToClipboard(XmppActivity activity, Message message) {
-		SpannableStringBuilder body = message.getMergedBody();
+	public static void copyLinkToClipboard(final XmppActivity activity, final Message message) {
+		final SpannableStringBuilder body = message.getMergedBody();
 		MyLinkify.addLinks(body, true);
 		for (final URLSpan urlspan : body.getSpans(0, body.length() - 1, URLSpan.class)) {
-			Uri uri = Uri.parse(urlspan.getURL());
+			final Uri uri = Uri.parse(urlspan.getURL());
 			if ("xmpp".equals(uri.getScheme())) {
 				try {
-					Jid jid = new XmppUri(uri).getJid();
+					final Jid jid = new XmppUri(uri).getJid();
 					if (activity.copyTextToClipboard(jid.asBareJid().toString(), R.string.account_settings_jabber_id)) {
 						Toast.makeText(activity,R.string.jabber_id_copied_to_clipboard, Toast.LENGTH_SHORT).show();
 					}
 					return;
-				} catch (Exception e) {
-					e.printStackTrace();
+				} catch (final Exception e) {
 					return;
 				}
 			} else {

src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java 🔗

@@ -1,6 +1,5 @@
 package eu.siacs.conversations.xmpp.jingle;
 
-import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.collect.Collections2;
@@ -11,8 +10,6 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
-import org.checkerframework.checker.nullness.compatqual.NullableDecl;
-
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -292,13 +289,7 @@ public class RtpContentMap {
             return ImmutableMap.copyOf(
                     Maps.transformValues(
                             contents,
-                            new Function<Content, DescriptionTransport>() {
-                                @NullableDecl
-                                @Override
-                                public DescriptionTransport apply(@NullableDecl Content content) {
-                                    return content == null ? null : of(content);
-                                }
-                            }));
+                            content -> content == null ? null : of(content)));
         }
     }
 

src/main/res/values-nl/strings.xml 🔗

@@ -97,6 +97,7 @@
     <string name="send_omemo_message">Verstuur OMEMO-versleuteld bericht</string>
     <string name="send_omemo_x509_message">Verstuur v\\OMEMO-versleuteld bericht</string>
     <string name="send_pgp_message">Verstuur OpenPGP-versleuteld bericht</string>
+    <string name="your_nick_has_been_changed">Nieuwe bijnaam in gebruik</string>
     <string name="send_unencrypted">Verstuur onversleuteld</string>
     <string name="decryption_failed">Ontsleutelen mislukt. Misschien heb je niet de juiste private sleutel.</string>
     <string name="openkeychain_required">OpenKeychain</string>
@@ -122,6 +123,7 @@
     <string name="pref_never_send_crash">Verstuur nooit crashrapportages</string>
     <string name="pref_confirm_messages">Bevestig berichten</string>
     <string name="pref_confirm_messages_summary">Laat je contacten weten wanneer je hun berichten ontvangen en gelezen hebt</string>
+    <string name="pref_prevent_screenshots">Voorkom schermafdrukken</string>
     <string name="pref_ui_options">Gebruikersomgeving</string>
     <string name="openpgp_error">OpenKeychain veroorzaakte een fout.</string>
     <string name="bad_key_for_encryption">Slechte sleutel voor versleuteling.</string>
@@ -150,7 +152,9 @@
     <string name="account_status_regis_fail">Registratie mislukt</string>
     <string name="account_status_regis_conflict">Gebruikersnaam is al in gebruik</string>
     <string name="account_status_regis_success">Registratie voltooid</string>
+    <string name="account_status_regis_invalid_token">Ongeldig registratietoken</string>
     <string name="account_status_tls_error">TLS-onderhandeling mislukt</string>
+    <string name="account_status_tls_error_domain">Domein niet verifieerbaar</string>
     <string name="account_status_policy_violation">Beleidsschending</string>
     <string name="account_status_incompatible_server">Incompatibele server</string>
     <string name="account_status_stream_error">Fout bij stream</string>
@@ -174,6 +178,7 @@
     <string name="account_settings_example_jabber_id">gebruikersnaam@voorbeeld.nl</string>
     <string name="password">Wachtwoord</string>
     <string name="invalid_jid">Dit is geen geldig XMPP-adres</string>
+    <string name="error_out_of_memory">Geen geheugen beschikbaar. Afbeelding is te groot</string>
     <string name="add_phone_book_text">Wil je %s toevoegen aan je adresboek?</string>
     <string name="server_info_show_more">Server-info</string>
     <string name="server_info_mam">XEP-0313: MAM</string>
@@ -195,9 +200,12 @@
     <string name="last_seen_hours">%d uur geleden voor het laatst gezien</string>
     <string name="last_seen_day">een dag geleden voor het laatst gezien</string>
     <string name="last_seen_days">%d dagen geleden voor het laatst gezien</string>
+    <string name="openpgp_messages_found">Nieuw OpenPGP-versleuteld bericht gevonden</string>
     <string name="openpgp_key_id">OpenPGP-sleutel-ID</string>
     <string name="omemo_fingerprint">OMEMO-vingerafdruk</string>
     <string name="omemo_fingerprint_x509">v\\OMEMO-vingerafdruk</string>
+    <string name="omemo_fingerprint_selected_message">OMEMO-vingerafdruk (herkomst bericht)</string>
+    <string name="omemo_fingerprint_x509_selected_message">v\\OMEMO-vingerafdruk (herkomst bericht)</string>
     <string name="other_devices">Andere apparaten</string>
     <string name="trust_omemo_fingerprints">Vertrouw OMEMO-vingerafdrukken</string>
     <string name="fetching_keys">Sleutels ophalen…</string>
@@ -232,13 +240,16 @@
     <string name="add_back">Ook toevoegen</string>
     <string name="contact_has_read_up_to_this_point">%s heeft tot hier gelezen</string>
     <string name="contacts_have_read_up_to_this_point">%s hebben tot hier gelezen</string>
+    <string name="contacts_and_n_more_have_read_up_to_this_point">%1$s en nog %2$d meer hebben tot hier gelezen</string>
     <string name="everyone_has_read_up_to_this_point">Iedereen heeft tot hier gelezen</string>
     <string name="publish">Publiceer</string>
     <string name="touch_to_choose_picture">Tik op avatar om een foto uit de galerij te kiezen</string>
     <string name="publishing">Publiceren…</string>
     <string name="error_publish_avatar_server_reject">De server weigerde de publicatie van je afbeelding</string>
+    <string name="error_publish_avatar_converting">Kon de afbeelding niet converteren</string>
     <string name="error_saving_avatar">Fout bij opslaan van avatar</string>
     <string name="or_long_press_for_default">(Of hou lang ingedrukt om de oorspronkelijke terug te zetten)</string>
+    <string name="error_publish_avatar_no_server_support">Je server ondersteunt de publicatie van avatars niet</string>
     <string name="private_message">gefluisterd</string>
     <string name="private_message_to">naar %s</string>
     <string name="send_private_message_to">Privébericht sturen naar %s</string>
@@ -266,6 +277,7 @@
     <string name="pref_quiet_hours_summary">Tijdens stille uren worden meldingen onderdrukt</string>
     <string name="pref_expert_options_other">Andere</string>
     <string name="pref_autojoin">Synchroniseren met bladwijzers</string>
+    <string name="toast_message_omemo_fingerprint">OMEMO-vingerafdruk gekopieerd naar klembord</string>
     <string name="conference_banned">Je bent verbannen uit dit groepsgesprek</string>
     <string name="conference_members_only">Dit groepsgesprek is enkel voor leden</string>
     <string name="conference_resource_constraint">Bronbeperking</string>
@@ -777,4 +789,38 @@
     <string name="local_server">Lokale server</string>
     <string name="category_about">Over</string>
     <string name="rtp_state_declined_or_busy">Bezig</string>
+    <string name="video_call">Videogesprek</string>
+    <string name="microphone_unavailable">Je microfoon is niet beschikbaar</string>
+    <string name="only_one_call_at_a_time">Je kunt slechts één gesprek tegelijk voeren.</string>
+    <string name="return_to_ongoing_call">Terug naar lopend gesprek</string>
+    <string name="could_not_switch_camera">Kon camera niet wisselen</string>
+    <string name="add_to_favorites">Bovenaan vastzetten</string>
+    <string name="remove_from_favorites">Bovenaan losmaken</string>
+    <string name="could_not_correct_message">Kon bericht niet corrigeren</string>
+    <string name="search_all_conversations">Alle gesprekken</string>
+    <string name="search_this_conversation">Dit gesprek</string>
+    <string name="your_avatar">Je avatar</string>
+    <string name="avatar_for_x">Avatar voor %s</string>
+    <string name="encrypted_with_omemo">Versleuteld met OMEMO</string>
+    <string name="not_encrypted">Onversleuteld</string>
+    <string name="play_audio">Speel audio</string>
+    <string name="pause_audio">Pauzeer audio</string>
+    <plurals name="view_users">
+        <item quantity="one">Bekijk %1$d deelnemer</item>
+        <item quantity="other">Bekijk %1$d deelnemers</item>
+    </plurals>
+    <plurals name="some_messages_could_not_be_delivered">
+        <item quantity="one">Een bericht kon niet worden afgeleverd</item>
+        <item quantity="other">Sommige berichten konden niet worden afgeleverd</item>
+    </plurals>
+    <string name="failed_deliveries">Mislukte afleveringen</string>
+    <string name="more_options">Meer opties</string>
+    <string name="no_application_found">Geen applicatie gevonden</string>
+    <string name="invite_to_app">Nodig uit bij Conversations</string>
+    <string name="unable_to_parse_invite">Kan uitnodiging niet verwerken</string>
+    <string name="no_active_accounts_support_this">Geen actieve accounts ondersteunen deze functie</string>
+    <string name="backup_started_message">De backup is gestart. Je krijgt een bericht als het voltooid is.</string>
+    <string name="unable_to_enable_video">Kan video niet schakelen.</string>
+    <string name="plain_text_document">Onversleuteld document</string>
+    <string name="account_registrations_are_not_supported">Accountregistraties zijn niet ondersteund</string>
     </resources>

src/main/res/values-pl/strings.xml 🔗

@@ -413,7 +413,7 @@
     <string name="until_further_notice">Ręcznie</string>
     <string name="snooze">Odłóż</string>
     <string name="reply">Odpowiedz</string>
-    <string name="mark_as_read">Oznacz jako przeczytane</string>
+    <string name="mark_as_read">Już przeczytane</string>
     <string name="pref_input_options">Ustawienia wprowadzania</string>
     <string name="pref_enter_is_send">Enter wysyła</string>
     <string name="pref_enter_is_send_summary">Użyj klawisza Enter aby wysłać wiadomość. Możesz zawsze użyć Ctrl+Enter do wysyłania wiadomości, nawet jeśli ta opcja jest wyłączona.</string>

src/playstore/AndroidManifest.xml 🔗

@@ -1,23 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:tools="http://schemas.android.com/tools"
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <application tools:ignore="GoogleAppIndexingWarning">
+    <application android:icon="@mipmap/new_launcher">
 
-        <meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
-        <meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
+        <meta-data
+            android:name="firebase_analytics_collection_deactivated"
+            android:value="true" />
+        <meta-data
+            android:name="google_analytics_adid_collection_enabled"
+            android:value="false" />
 
-        <receiver android:name=".services.MaintenanceReceiver"
-                  android:exported="true"
-                  android:permission="android.permission.CHANGE_CONFIGURATION">
+        <receiver
+            android:name=".services.MaintenanceReceiver"
+            android:exported="true"
+            android:permission="android.permission.CHANGE_CONFIGURATION">
             <intent-filter>
-                <action android:name="eu.siacs.conversations.RENEW_INSTANCE_ID"/>
+                <action android:name="eu.siacs.conversations.RENEW_INSTANCE_ID" />
             </intent-filter>
         </receiver>
 
         <service
             android:name=".services.PushMessageReceiver"
-            android:exported="false" >
+            android:exported="false">
             <intent-filter>
                 <action android:name="com.google.firebase.MESSAGING_EVENT" />
             </intent-filter>