From 68a20ecf63d2590afde9bba04c73ff0be73be227 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jul 2019 08:37:39 +0200 Subject: [PATCH 01/25] pulled translations from transifex --- src/main/res/values-it/strings.xml | 2 ++ src/quicksy/res/values-it/strings.xml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 0070b6a4d..6df9f8a09 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -17,6 +17,8 @@ Sblocca contatto Blocca dominio Sblocca dominio + Blocca partecipante + Sblocca partecipante Gestisci account Impostazioni Condividi con Conversation diff --git a/src/quicksy/res/values-it/strings.xml b/src/quicksy/res/values-it/strings.xml index 4d61c3c6b..4b663fea0 100644 --- a/src/quicksy/res/values-it/strings.xml +++ b/src/quicksy/res/values-it/strings.xml @@ -19,4 +19,5 @@ Quicksy ha bisogno di accedere al microfono Questa categoria di notifiche è usata per mostrare una notifica permanente per indicare che Quicksy è in esecuzione. Immagine profilo di Quicksy - + Quicksy non è disponibile nella tua nazione. + From 1af52a7a30b40325fe69f5fba64f5d9564a903d6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jul 2019 15:25:50 +0200 Subject: [PATCH 02/25] made some quicksy registration errors more explicit --- .../services/QuickConversationsService.java | 24 ++++++++++++++----- .../ui/util/ApiDialogHelper.java | 9 +++++++ src/quicksy/res/values/strings.xml | 3 +++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java b/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java index cfa2f7775..319f160f7 100644 --- a/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java +++ b/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java @@ -8,13 +8,17 @@ import android.preference.PreferenceManager; import android.util.Log; import java.io.BufferedWriter; +import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ConnectException; import java.net.HttpURLConnection; +import java.net.SocketTimeoutException; import java.net.URL; import java.net.UnknownHostException; +import java.security.GeneralSecurityException; import java.security.SecureRandom; +import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -29,10 +33,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLPeerUnverifiedException; import eu.siacs.conversations.Config; -import eu.siacs.conversations.android.JabberIdContact; import eu.siacs.conversations.android.PhoneNumberContact; import eu.siacs.conversations.crypto.sasl.Plain; import eu.siacs.conversations.entities.Account; @@ -44,8 +49,6 @@ import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Namespace; -import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import io.michaelrocks.libphonenumber.android.Phonenumber; import rocks.xmpp.addr.Jid; @@ -58,6 +61,9 @@ public class QuickConversationsService extends AbstractQuickConversationsService public static final int API_ERROR_CONNECT = -3; public static final int API_ERROR_SSL_HANDSHAKE = -4; public static final int API_ERROR_AIRPLANE_MODE = -5; + public static final int API_ERROR_SSL_CERTIFICATE = -6; + public static final int API_ERROR_SSL_GENERAL = -7; + public static final int API_ERROR_TIMEOUT = -8; private static final String API_DOMAIN = "api." + Config.QUICKSY_DOMAIN; @@ -135,7 +141,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService } } } - } catch (Exception e) { + } catch (IOException e) { final int code = getApiErrorCode(e); synchronized (mOnVerificationRequested) { for (OnVerificationRequested onVerificationRequested : mOnVerificationRequested) { @@ -232,7 +238,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService } } } - } catch (Exception e) { + } catch (IOException e) { final int code = getApiErrorCode(e); synchronized (mOnVerification) { for (OnVerification onVerification : mOnVerification) { @@ -265,7 +271,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService } - private int getApiErrorCode(Exception e) { + private int getApiErrorCode(final Exception e) { if (!service.hasInternetConnection()) { return API_ERROR_AIRPLANE_MODE; } else if (e instanceof UnknownHostException) { @@ -274,6 +280,12 @@ public class QuickConversationsService extends AbstractQuickConversationsService return API_ERROR_CONNECT; } else if (e instanceof SSLHandshakeException) { return API_ERROR_SSL_HANDSHAKE; + } else if (e instanceof SSLPeerUnverifiedException || e instanceof CertificateException) { + return API_ERROR_SSL_CERTIFICATE; + } else if (e instanceof SSLException || e instanceof GeneralSecurityException) { + return API_ERROR_SSL_GENERAL; + } else if (e instanceof SocketTimeoutException) { + return API_ERROR_TIMEOUT; } else { Log.d(Config.LOGTAG, e.getClass().getName()); return API_ERROR_OTHER; diff --git a/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java b/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java index d1f987bff..995fe3fca 100644 --- a/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java +++ b/src/quicksy/java/eu/siacs/conversations/ui/util/ApiDialogHelper.java @@ -33,6 +33,15 @@ public class ApiDialogHelper { case QuickConversationsService.API_ERROR_UNKNOWN_HOST: res = R.string.unable_to_find_server; break; + case QuickConversationsService.API_ERROR_SSL_CERTIFICATE: + res = R.string.unable_to_verify_server_identity; + break; + case QuickConversationsService.API_ERROR_SSL_GENERAL: + res = R.string.unknown_security_error; + break; + case QuickConversationsService.API_ERROR_TIMEOUT: + res = R.string.timeout_while_connecting_to_server; + break; case 400: res = R.string.invalid_user_input; break; diff --git a/src/quicksy/res/values/strings.xml b/src/quicksy/res/values/strings.xml index e9cfa3cae..54f7b1481 100644 --- a/src/quicksy/res/values/strings.xml +++ b/src/quicksy/res/values/strings.xml @@ -20,4 +20,7 @@ This notification category is used to display a permanent notification indicating that Quicksy is running. Quicksy profile picture Quicksy is not available in your country. + Unable to verify server identity. + Unknown security error. + Timeout while connecting to server. From f597fc46dad1eeb3afadf6c3900f487524caef7f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jul 2019 17:31:56 +0200 Subject: [PATCH 03/25] implement time out for waiting on voice recording --- .../conversations/ui/RecordingActivity.java | 309 +++++++++--------- 1 file changed, 162 insertions(+), 147 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java index 710969334..3cd5e8ed3 100644 --- a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -30,167 +32,180 @@ import eu.siacs.conversations.utils.ThemeHelper; public class RecordingActivity extends Activity implements View.OnClickListener { - public static String STORAGE_DIRECTORY_TYPE_NAME = "Recordings"; + public static String STORAGE_DIRECTORY_TYPE_NAME = "Recordings"; - private ActivityRecordingBinding binding; + private ActivityRecordingBinding binding; - private MediaRecorder mRecorder; - private long mStartTime = 0; + private MediaRecorder mRecorder; + private long mStartTime = 0; - private Handler mHandler = new Handler(); - private Runnable mTickExecutor = new Runnable() { - @Override - public void run() { - tick(); - mHandler.postDelayed(mTickExecutor, 100); - } - }; + private CountDownLatch outputFileWrittenLatch = new CountDownLatch(1); - private File mOutputFile; - private boolean mShouldFinishAfterWrite = false; + private Handler mHandler = new Handler(); + private Runnable mTickExecutor = new Runnable() { + @Override + public void run() { + tick(); + mHandler.postDelayed(mTickExecutor, 100); + } + }; - private FileObserver mFileObserver; + private File mOutputFile; - @Override - protected void onCreate(Bundle savedInstanceState) { - setTheme(ThemeHelper.findDialog(this)); - super.onCreate(savedInstanceState); - this.binding = DataBindingUtil.setContentView(this,R.layout.activity_recording); - this.binding.cancelButton.setOnClickListener(this); - this.binding.shareButton.setOnClickListener(this); - this.setFinishOnTouchOutside(false); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } + private FileObserver mFileObserver; - @Override - protected void onStart() { - super.onStart(); - if (!startRecording()) { - this.binding.shareButton.setEnabled(false); - this.binding.timer.setTextAppearance(this, R.style.TextAppearance_Conversations_Title); - this.binding.timer.setText(R.string.unable_to_start_recording); - } - } + @Override + protected void onCreate(Bundle savedInstanceState) { + setTheme(ThemeHelper.findDialog(this)); + super.onCreate(savedInstanceState); + this.binding = DataBindingUtil.setContentView(this, R.layout.activity_recording); + this.binding.cancelButton.setOnClickListener(this); + this.binding.shareButton.setOnClickListener(this); + this.setFinishOnTouchOutside(false); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } - @Override - protected void onStop() { - super.onStop(); - if (mRecorder != null) { - mHandler.removeCallbacks(mTickExecutor); - stopRecording(false); - } - if (mFileObserver != null) { - mFileObserver.stopWatching(); - } - } + @Override + protected void onStart() { + super.onStart(); + if (!startRecording()) { + this.binding.shareButton.setEnabled(false); + this.binding.timer.setTextAppearance(this, R.style.TextAppearance_Conversations_Title); + this.binding.timer.setText(R.string.unable_to_start_recording); + } + } - private boolean startRecording() { - mRecorder = new MediaRecorder(); - mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); - mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - mRecorder.setAudioEncodingBitRate(96000); - mRecorder.setAudioSamplingRate(22050); - setupOutputFile(); - mRecorder.setOutputFile(mOutputFile.getAbsolutePath()); + @Override + protected void onStop() { + super.onStop(); + if (mRecorder != null) { + mHandler.removeCallbacks(mTickExecutor); + stopRecording(false); + } + if (mFileObserver != null) { + mFileObserver.stopWatching(); + } + } - try { - mRecorder.prepare(); - mRecorder.start(); - mStartTime = SystemClock.elapsedRealtime(); - mHandler.postDelayed(mTickExecutor, 100); - Log.d("Voice Recorder", "started recording to " + mOutputFile.getAbsolutePath()); - return true; - } catch (Exception e) { - Log.e("Voice Recorder", "prepare() failed " + e.getMessage()); - return false; - } - } + private boolean startRecording() { + mRecorder = new MediaRecorder(); + mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mRecorder.setAudioEncodingBitRate(96000); + mRecorder.setAudioSamplingRate(22050); + setupOutputFile(); + mRecorder.setOutputFile(mOutputFile.getAbsolutePath()); - protected void stopRecording(boolean saveFile) { - mShouldFinishAfterWrite = saveFile; - try { - mRecorder.stop(); - mRecorder.release(); - } catch (Exception e) { - if (saveFile) { - Toast.makeText(this,R.string.unable_to_save_recording, Toast.LENGTH_SHORT).show(); - } - } finally { - mRecorder = null; - mStartTime = 0; - } - if (!saveFile && mOutputFile != null) { - if (mOutputFile.delete()) { - Log.d(Config.LOGTAG,"deleted canceled recording"); - } - } - } + try { + mRecorder.prepare(); + mRecorder.start(); + mStartTime = SystemClock.elapsedRealtime(); + mHandler.postDelayed(mTickExecutor, 100); + Log.d("Voice Recorder", "started recording to " + mOutputFile.getAbsolutePath()); + return true; + } catch (Exception e) { + Log.e("Voice Recorder", "prepare() failed " + e.getMessage()); + return false; + } + } - private static File generateOutputFilename(Context context) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); - String filename = "RECORDING_" + dateFormat.format(new Date()) + ".m4a"; - return new File(FileBackend.getConversationsDirectory(context, STORAGE_DIRECTORY_TYPE_NAME) + "/" + filename); - } + protected void stopRecording(final boolean saveFile) { + try { + mRecorder.stop(); + mRecorder.release(); + } catch (Exception e) { + if (saveFile) { + Toast.makeText(this, R.string.unable_to_save_recording, Toast.LENGTH_SHORT).show(); + return; + } + } finally { + mRecorder = null; + mStartTime = 0; + } + if (!saveFile && mOutputFile != null) { + if (mOutputFile.delete()) { + Log.d(Config.LOGTAG, "deleted canceled recording"); + } + } + if (saveFile) { + new Thread(() -> { + try { + if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) { + Log.d(Config.LOGTAG, "time out waiting for output file to be written"); + } + } catch (InterruptedException e) { + Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written" ,e); + } + runOnUiThread(() -> { + setResult(Activity.RESULT_OK, new Intent().setData(Uri.fromFile(mOutputFile))); + finish(); + }); + }).start(); + } + } - private void setupOutputFile() { - mOutputFile = generateOutputFilename(this); - File parentDirectory = mOutputFile.getParentFile(); - if (parentDirectory.mkdirs()) { - Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath()); - } - File noMedia = new File(parentDirectory, ".nomedia"); - if (!noMedia.exists()) { - try { - if (noMedia.createNewFile()) { - Log.d(Config.LOGTAG, "created nomedia file in " + parentDirectory.getAbsolutePath()); - } - } catch (IOException e) { - Log.d(Config.LOGTAG, "unable to create nomedia file in " + parentDirectory.getAbsolutePath(), e); - } - } - setupFileObserver(parentDirectory); - } + private static File generateOutputFilename(Context context) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); + String filename = "RECORDING_" + dateFormat.format(new Date()) + ".m4a"; + return new File(FileBackend.getConversationsDirectory(context, STORAGE_DIRECTORY_TYPE_NAME) + "/" + filename); + } - private void setupFileObserver(File directory) { - mFileObserver = new FileObserver(directory.getAbsolutePath()) { - @Override - public void onEvent(int event, String s) { - if (s != null && s.equals(mOutputFile.getName()) && event == FileObserver.CLOSE_WRITE) { - if (mShouldFinishAfterWrite) { - setResult(Activity.RESULT_OK, new Intent().setData(Uri.fromFile(mOutputFile))); - finish(); - } - } - } - }; - mFileObserver.startWatching(); - } + private void setupOutputFile() { + mOutputFile = generateOutputFilename(this); + File parentDirectory = mOutputFile.getParentFile(); + if (parentDirectory.mkdirs()) { + Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath()); + } + File noMedia = new File(parentDirectory, ".nomedia"); + if (!noMedia.exists()) { + try { + if (noMedia.createNewFile()) { + Log.d(Config.LOGTAG, "created nomedia file in " + parentDirectory.getAbsolutePath()); + } + } catch (IOException e) { + Log.d(Config.LOGTAG, "unable to create nomedia file in " + parentDirectory.getAbsolutePath(), e); + } + } + setupFileObserver(parentDirectory); + } - @SuppressLint("SetTextI18n") - private void tick() { - long time = (mStartTime < 0) ? 0 : (SystemClock.elapsedRealtime() - mStartTime); - int minutes = (int) (time / 60000); - int seconds = (int) (time / 1000) % 60; - int milliseconds = (int) (time / 100) % 10; - this.binding.timer.setText(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds) + "." + milliseconds); - } + private void setupFileObserver(File directory) { + mFileObserver = new FileObserver(directory.getAbsolutePath()) { + @Override + public void onEvent(int event, String s) { + if (s != null && s.equals(mOutputFile.getName()) && event == FileObserver.CLOSE_WRITE) { + outputFileWrittenLatch.countDown(); + } + } + }; + mFileObserver.startWatching(); + } - @Override - public void onClick(View view) { - switch (view.getId()) { - case R.id.cancel_button: - mHandler.removeCallbacks(mTickExecutor); - stopRecording(false); - setResult(RESULT_CANCELED); - finish(); - break; - case R.id.share_button: - this.binding.shareButton.setEnabled(false); - this.binding.shareButton.setText(R.string.please_wait); - mHandler.removeCallbacks(mTickExecutor); - mHandler.postDelayed(() -> stopRecording(true), 500); - break; - } - } + @SuppressLint("SetTextI18n") + private void tick() { + long time = (mStartTime < 0) ? 0 : (SystemClock.elapsedRealtime() - mStartTime); + int minutes = (int) (time / 60000); + int seconds = (int) (time / 1000) % 60; + int milliseconds = (int) (time / 100) % 10; + this.binding.timer.setText(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds) + "." + milliseconds); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.cancel_button: + mHandler.removeCallbacks(mTickExecutor); + stopRecording(false); + setResult(RESULT_CANCELED); + finish(); + break; + case R.id.share_button: + this.binding.shareButton.setEnabled(false); + this.binding.shareButton.setText(R.string.please_wait); + mHandler.removeCallbacks(mTickExecutor); + mHandler.postDelayed(() -> stopRecording(true), 500); + break; + } + } } From 4957e50ac4b5ad650740bc2069a9aeaae508cb30 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 23 Jul 2019 17:49:33 +0200 Subject: [PATCH 04/25] disable spell checking on country drop down field in Quicksy --- src/quicksy/res/layout/activity_enter_number.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/quicksy/res/layout/activity_enter_number.xml b/src/quicksy/res/layout/activity_enter_number.xml index 78d183dd4..ba2e3c1ff 100644 --- a/src/quicksy/res/layout/activity_enter_number.xml +++ b/src/quicksy/res/layout/activity_enter_number.xml @@ -46,7 +46,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:cursorVisible="false" + android:inputType="textNoSuggestions" android:drawableEnd="@drawable/ic_arrow_drop_down_black_18dp" + android:drawableRight="@drawable/ic_arrow_drop_down_black_18dp" android:focusable="false" android:gravity="bottom|center_horizontal" android:longClickable="false" /> From 238df77a1e4c7675857f5916e9c74f51bd50c541 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 25 Jul 2019 17:01:43 +0200 Subject: [PATCH 05/25] catch IllegalArgumentException when reading backup file --- .../eu/siacs/conversations/services/ImportBackupService.java | 2 +- .../java/eu/siacs/conversations/ui/ImportBackupActivity.java | 2 +- .../java/eu/siacs/conversations/utils/BackupFileHeader.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java b/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java index d8246a6af..66ebd7c3a 100644 --- a/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java +++ b/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java @@ -137,7 +137,7 @@ public class ImportBackupService extends Service { } else { backupFiles.add(backupFile); } - } catch (IOException e) { + } catch (IOException | IllegalArgumentException e) { Log.d(Config.LOGTAG, "unable to read backup file ", e); } } diff --git a/src/conversations/java/eu/siacs/conversations/ui/ImportBackupActivity.java b/src/conversations/java/eu/siacs/conversations/ui/ImportBackupActivity.java index d6dbfd222..da4512465 100644 --- a/src/conversations/java/eu/siacs/conversations/ui/ImportBackupActivity.java +++ b/src/conversations/java/eu/siacs/conversations/ui/ImportBackupActivity.java @@ -124,7 +124,7 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo try { final ImportBackupService.BackupFile backupFile = ImportBackupService.BackupFile.read(this, uri); showEnterPasswordDialog(backupFile, finishOnCancel); - } catch (IOException e) { + } catch (IOException | IllegalArgumentException e) { Snackbar.make(binding.coordinator, R.string.not_a_backup_file, Snackbar.LENGTH_LONG).show(); } } diff --git a/src/main/java/eu/siacs/conversations/utils/BackupFileHeader.java b/src/main/java/eu/siacs/conversations/utils/BackupFileHeader.java index bc86a5d24..5e8b80f81 100644 --- a/src/main/java/eu/siacs/conversations/utils/BackupFileHeader.java +++ b/src/main/java/eu/siacs/conversations/utils/BackupFileHeader.java @@ -49,7 +49,7 @@ public class BackupFileHeader { public static BackupFileHeader read(DataInputStream inputStream) throws IOException { final int version = inputStream.readInt(); if (version > VERSION) { - throw new IllegalArgumentException("Backup File version was "+version+" but app only supports up to version "+VERSION); + throw new IllegalArgumentException("Backup File version was " + version + " but app only supports up to version " + VERSION); } String app = inputStream.readUTF(); String jid = inputStream.readUTF(); @@ -59,7 +59,7 @@ public class BackupFileHeader { byte[] salt = new byte[16]; inputStream.readFully(salt); - return new BackupFileHeader(app,Jid.of(jid),timestamp,iv,salt); + return new BackupFileHeader(app, Jid.of(jid), timestamp, iv, salt); } From 011bdd8ef63c23f1a91f15221c33544089d781b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Aug 2019 21:32:20 +0200 Subject: [PATCH 06/25] fixed send_multiple share intent with empty extras. fixes #3512 --- .../java/eu/siacs/conversations/ui/ShareWithActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index ce64af856..83b0bebcc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -12,6 +12,7 @@ import android.view.MenuItem; import android.widget.Toast; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import eu.siacs.conversations.Config; @@ -142,7 +143,8 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer this.share.text = text; } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) { - this.share.uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + final ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + this.share.uris = uris == null ? new ArrayList<>() : uris; } if (xmppConnectionServiceBound) { xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uris.size() == 0, false); From ffc16faf7ba4ac81f33dfc9f060e6aac541bc9c2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Aug 2019 15:04:05 +0200 Subject: [PATCH 07/25] pulled translations from transifex --- src/main/res/values-de/strings.xml | 7 +++++++ src/main/res/values-es/strings.xml | 7 +++++++ src/main/res/values-eu/strings.xml | 2 ++ src/main/res/values-gl/strings.xml | 7 +++++++ src/main/res/values-hu/strings.xml | 5 +++++ src/main/res/values-nl/strings.xml | 9 +++++++++ src/main/res/values-ro-rRO/strings.xml | 6 ++++++ src/quicksy/res/values-bg/strings.xml | 2 +- src/quicksy/res/values-de/strings.xml | 3 +++ src/quicksy/res/values-es/strings.xml | 3 +++ src/quicksy/res/values-gl/strings.xml | 3 +++ src/quicksy/res/values-hu/strings.xml | 6 +++++- src/quicksy/res/values-it/strings.xml | 2 +- src/quicksy/res/values-nl/strings.xml | 6 +++++- src/quicksy/res/values-pl/strings.xml | 2 +- src/quicksy/res/values-ro-rRO/strings.xml | 3 +++ 16 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index e7eb4dabc..5c722c8d5 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -866,4 +866,11 @@ Dies sieht aus wie eine Domain-Adresse Trotzdem hinzufügen Dies sieht aus wie eine Channel-Adresse + Sicherungsdateien teilen + Sicherung für Conversations + Ereignis + Sicherung öffnen + Die von dir ausgewählte Datei ist keine Sicherungsdatei von Conversations + Dieses Konto wurde bereits eingerichtet + Bitte gib das Passwort für dieses Konto ein diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 9da8b2d72..fb4d63c9b 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -866,4 +866,11 @@ Esto parece una dirección de dominio Añadir de todas formas Esto parece una dirección de un canal + Compartir ficheros de respaldo + Respaldo de Conversations + Evento + Abrir respaldo + El fichero seleccionado no es un respaldo de Conversations + Esta cuenta ya fue configurada + Por favor ingrese la contraseña para esta cuenta diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 2edec94ae..0ac36d96a 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -17,6 +17,8 @@ Kontaktua desblokeatu Domeinua blokeatu Domeinua desblokeatu + Parte-hartzailea blokeatu + Parte-hartzaileari blokeoa kendu Kontuak kudeatu Ezarpenak Elkarrizketa batekin partekatu diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 49c326874..9265165f4 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -866,4 +866,11 @@ Esto semella un enderezo de dominio Engadir igualmente Esto semella o enderezo de un canal + Compartir ficheiros de respaldo + Respaldar Conversations + Evento + Abrir respaldo + O ficheiro seleccionado non é un ficheiro de respaldo Conversations + Esta conta xa foi configurada + Introduza o contrasinal de esta conta diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index 82e222182..6785cc49e 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -17,6 +17,8 @@ Tiltás feloldása Tartomány tiltása Tartomány feloldása + Résztvevő letiltása + Résztvevő feloldása Fiókok kezelése Beállítások Megosztás Conversation-nel @@ -864,4 +866,7 @@ Ez egy domain címnek tűnik Akkor is adja hozzá Ez egy csatorna címnek tűnik + Biztonsági mentések megosztása + Esemény + Biztonsági mentés megnyitása diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 260e656fc..7b80bc1d5 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -17,6 +17,8 @@ Contact deblokkeren Domein blokkeren Domein deblokkeren + Deelnemer blokkeren + Deelnemer deblokkeren Accounts beheren Instellingen Delen in gesprek @@ -864,4 +866,11 @@ Dit lijkt op een domeinadres Tóch toevoegen Dit lijkt op een kanaaladres + Back-upbestanden delen + Back-up van Conversations + Gebeurtenis + Back-up openen + Het geselecteerde bestand is geen Conversations-back-upbestand + Deze account is al ingesteld + Voer het wachtwoord voor deze account in diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index edb16a8af..93d28e4c6 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -876,4 +876,10 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Aceasta pare să fie o adresă de domeniu Adaugă oricum Aceasta pare o adresă de canal + Partajează fișierele copiei de siguranță + Copie de siguranță Conversations + Deschide o copie de siguranță + Fișierul selectat nu este o copie de siguranța Conversations + Acest cont a fost deja configurat + Va rugăm să introduceți parola pentru acest cont diff --git a/src/quicksy/res/values-bg/strings.xml b/src/quicksy/res/values-bg/strings.xml index 1ec1e155d..236567885 100644 --- a/src/quicksy/res/values-bg/strings.xml +++ b/src/quicksy/res/values-bg/strings.xml @@ -20,4 +20,4 @@ Тази категория известия се използва за показване на постоянно известие, което показва, че Quicksy работи. Профилна снимка за Quicksy Quicksy не може да се използва във Вашата страна. - + diff --git a/src/quicksy/res/values-de/strings.xml b/src/quicksy/res/values-de/strings.xml index 9fed2e699..2e8a87a29 100644 --- a/src/quicksy/res/values-de/strings.xml +++ b/src/quicksy/res/values-de/strings.xml @@ -20,4 +20,7 @@ Diese Benachrichtigungsart wird verwendet, um eine permanente Benachrichtigung anzuzeigen, die anzeigt, dass Quicksy gerade ausgeführt wird. Quicksy Profilbild Quicksy ist in deinem Land nicht verfügbar. + Die Überprüfung der Serveridentität ist nicht möglich. + Unbekannter Sicherheitsfehler. + Zeitüberschreitung bei der Verbindung zum Server. diff --git a/src/quicksy/res/values-es/strings.xml b/src/quicksy/res/values-es/strings.xml index 2c4a1b0b7..c00850a2d 100644 --- a/src/quicksy/res/values-es/strings.xml +++ b/src/quicksy/res/values-es/strings.xml @@ -20,4 +20,7 @@ Esta categoría de notificación se usa para mostrar una notificación permantente indicando que Quicksy está ejecutándose. Foto de perfil en Quicksy Quicksy no está disponible en tu país. + No se ha podido verificar la identidad del servidor. + Error de seguridad desconocido. + Se ha superado el tiempo máximo de espera conectando al servidor. diff --git a/src/quicksy/res/values-gl/strings.xml b/src/quicksy/res/values-gl/strings.xml index c17eb3bfc..b1675f6e0 100644 --- a/src/quicksy/res/values-gl/strings.xml +++ b/src/quicksy/res/values-gl/strings.xml @@ -20,4 +20,7 @@ Esta categoría de notificacións utilízase para mostrar unha notificación permanente que indica que Quicksy está funcionando. Imaxe de perfil Quicksy Quicksy non está dispoñible no seu país. + Non se puido validar a identidade do servidor. + Fallo de seguridade descoñecido. + Caducou a conexión mentras conectaba co servidor. diff --git a/src/quicksy/res/values-hu/strings.xml b/src/quicksy/res/values-hu/strings.xml index af2244f39..45bfbb6c0 100644 --- a/src/quicksy/res/values-hu/strings.xml +++ b/src/quicksy/res/values-hu/strings.xml @@ -19,4 +19,8 @@ A Quicksy-nek hozzáférésre lenne szüksége a mikrofonhoz Ez az értesítési kategória állandó értesítést jelenít meg arról, hogy a Quicksy fut. Quicksy profilkép - + A Quicksy nem érhető el az Ön országában. + Nem sikerült ellenőrizni a szerver azonosságát. + Ismeretlen biztonsági hiba. + Időtúllépés történt a szerverhez való csatlakozás közben. + diff --git a/src/quicksy/res/values-it/strings.xml b/src/quicksy/res/values-it/strings.xml index 4b663fea0..ff5985ec0 100644 --- a/src/quicksy/res/values-it/strings.xml +++ b/src/quicksy/res/values-it/strings.xml @@ -20,4 +20,4 @@ Questa categoria di notifiche è usata per mostrare una notifica permanente per indicare che Quicksy è in esecuzione. Immagine profilo di Quicksy Quicksy non è disponibile nella tua nazione. - + diff --git a/src/quicksy/res/values-nl/strings.xml b/src/quicksy/res/values-nl/strings.xml index a34babb9d..1c3a1c4f4 100644 --- a/src/quicksy/res/values-nl/strings.xml +++ b/src/quicksy/res/values-nl/strings.xml @@ -19,4 +19,8 @@ Quicksy heeft toegang nodig tot de microfoon Deze meldingscategorie wordt gebruikt om een permanente melding weer te geven dat Quicksy wordt uitgevoerd. Quicksy-profielafbeelding - + Quicksy is niet beschikbaar in je land. + Kan serveridentiteit niet verifiëren. + Onbekende beveiligingsfout. + Time-out bij verbinden met server. + diff --git a/src/quicksy/res/values-pl/strings.xml b/src/quicksy/res/values-pl/strings.xml index 9b9961c6e..ef7a58073 100644 --- a/src/quicksy/res/values-pl/strings.xml +++ b/src/quicksy/res/values-pl/strings.xml @@ -20,4 +20,4 @@ Ta kategoria powiadomień jest używana do wyświetlania ciągłego powiadomienia o tym, że Quicksy działa. Obrazek profilowy Quicksy Quicksy nie jest dostępne w twoim kraju - + diff --git a/src/quicksy/res/values-ro-rRO/strings.xml b/src/quicksy/res/values-ro-rRO/strings.xml index bc6ca871f..1b6504387 100644 --- a/src/quicksy/res/values-ro-rRO/strings.xml +++ b/src/quicksy/res/values-ro-rRO/strings.xml @@ -22,4 +22,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Această categorie de notificări este folosită pentru a arăta o notificare permanentă ce indică rularea Quicksy Poză profil Quicksy Quicksy nu este disponibilă în țara dumneavoastră. + Nu s-a putut verifica identitatea serverului. + Eroare de securitate necunoscută. + A expirat timpul de așteptare conexiune server. From 1ff17fc3f09d91a8a222114b5c566d427f3e6a8c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Aug 2019 15:04:59 +0200 Subject: [PATCH 08/25] catch more firebase library bugs --- .../conversations/services/PushManagementService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java b/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java index 1fc8e58fe..e99de1b14 100644 --- a/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java +++ b/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java @@ -147,7 +147,14 @@ public class PushManagementService { } private void retrieveFcmInstanceToken(final OnGcmInstanceTokenRetrieved instanceTokenRetrieved) { - FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task -> { + final FirebaseInstanceId firebaseInstanceId; + try { + firebaseInstanceId = FirebaseInstanceId.getInstance(); + } catch (IllegalStateException e) { + Log.d(Config.LOGTAG, "unable to get firebase instance token ",e); + return; + } + firebaseInstanceId.getInstanceId().addOnCompleteListener(task -> { if (!task.isSuccessful()) { Log.d(Config.LOGTAG, "unable to get Firebase instance token", task.getException()); } From 8ac042418bd30d801a191fc8239e5541f44e6d61 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 11 Aug 2019 16:54:00 +0200 Subject: [PATCH 09/25] fixes #3514 --- .../conversations/xmpp/jingle/JingleConnection.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 1ec5f2714..7751b95b1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -841,18 +841,17 @@ public class JingleConnection implements Transferable { private boolean receiveFallbackToIbb(JinglePacket packet) { Log.d(Config.LOGTAG, "receiving fallack to ibb"); - String receivedBlockSize = packet.getJingleContent().ibbTransport() - .getAttribute("block-size"); + final String receivedBlockSize = packet.getJingleContent().ibbTransport().getAttribute("block-size"); if (receivedBlockSize != null) { - int bs = Integer.parseInt(receivedBlockSize); - if (bs > this.ibbBlockSize) { + final int bs = Integer.parseInt(receivedBlockSize); + if (bs < this.ibbBlockSize) { this.ibbBlockSize = bs; } } this.transportId = packet.getJingleContent().getTransportId(); this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize); - JinglePacket answer = bootstrapPacket("transport-accept"); + final JinglePacket answer = bootstrapPacket("transport-accept"); final Content content = new Content(contentCreator, contentName); content.setFileOffer(fileOffer, ftVersion); From 0f18f16dc28a4b6f167e5d3442fa9ce9dd946461 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Aug 2019 13:08:13 +0200 Subject: [PATCH 10/25] show scrollbars in muc user screen --- src/main/res/layout/activity_muc_users.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/layout/activity_muc_users.xml b/src/main/res/layout/activity_muc_users.xml index 679c5156e..c195a0a1a 100644 --- a/src/main/res/layout/activity_muc_users.xml +++ b/src/main/res/layout/activity_muc_users.xml @@ -26,6 +26,7 @@ android:layout_height="match_parent" android:background="?attr/color_background_primary" android:orientation="vertical" + android:scrollbars="vertical" app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> From ad15fb172179f55951bce6eef25a91ece85adac8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Aug 2019 13:09:02 +0200 Subject: [PATCH 11/25] pulled translations from transifex --- src/main/res/values-hu/strings.xml | 4 ++++ src/main/res/values-pl/strings.xml | 7 +++++++ src/main/res/values-ro-rRO/strings.xml | 1 + src/quicksy/res/values-pl/strings.xml | 5 ++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index 6785cc49e..8ad9d1a45 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -867,6 +867,10 @@ Akkor is adja hozzá Ez egy csatorna címnek tűnik Biztonsági mentések megosztása + Conversations biztonsági mentés Esemény Biztonsági mentés megnyitása + A kiválasztott fájl nem a Conversations biztonsági mentése + Ez a fiók már be lett állítva + Kérem, adja meg a fiókhoz tartozó jelszót diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 4a8b94d09..2590592a6 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -884,4 +884,11 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż To wygląda jak nazwa domeny Dodaj i tak To wygląda jak adres kanału + Udostępnij pliki kopii zapasowych + Kopia zapasowa Conversations + Zdarzenie + Otwórz kopię zapasową + Plik który otworzyłeś nie jest plikiem kopii zapasowej Conversations + To konto zostało już ustawione + Proszę podać hasło dla tego konta diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 93d28e4c6..971dd4c7b 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -878,6 +878,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Aceasta pare o adresă de canal Partajează fișierele copiei de siguranță Copie de siguranță Conversations + Eveniment Deschide o copie de siguranță Fișierul selectat nu este o copie de siguranța Conversations Acest cont a fost deja configurat diff --git a/src/quicksy/res/values-pl/strings.xml b/src/quicksy/res/values-pl/strings.xml index ef7a58073..6fd3d98f7 100644 --- a/src/quicksy/res/values-pl/strings.xml +++ b/src/quicksy/res/values-pl/strings.xml @@ -20,4 +20,7 @@ Ta kategoria powiadomień jest używana do wyświetlania ciągłego powiadomienia o tym, że Quicksy działa. Obrazek profilowy Quicksy Quicksy nie jest dostępne w twoim kraju - + Nie udało się sprawdzić tożsamości serwera. + Nieznany błąd bezpieczeństwa. + Błąd czasu oczekiwania na połączenie z serwerem. + From ed95dd64ad5f1ae8dfd1a390919c68e5c1809938 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 13 Aug 2019 21:18:32 +0200 Subject: [PATCH 12/25] create empty disco result on error to fire advance stream features event --- .../entities/ServiceDiscoveryResult.java | 12 ++++++++++++ .../siacs/conversations/xmpp/XmppConnection.java | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java index 826723fb7..3e2761101 100644 --- a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java +++ b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java @@ -86,6 +86,18 @@ public class ServiceDiscoveryResult { } } } + + private ServiceDiscoveryResult() { + this.hash = "sha-1"; + this.features = Collections.emptyList(); + this.identities = Collections.emptyList(); + this.ver = null; + this.forms = Collections.emptyList(); + } + + public static ServiceDiscoveryResult empty() { + return new ServiceDiscoveryResult(); + } public ServiceDiscoveryResult(Cursor cursor) throws JSONException { this( diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 159fa4f2b..0edac8a5e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1205,8 +1205,21 @@ public class XmppConnection implements Runnable { if (advancedStreamFeaturesLoaded && (jid.equals(Jid.of(account.getServer())) || jid.equals(account.getJid().asBareJid()))) { enableAdvancedStreamFeatures(); } - } else { + } else if (packet.getType() == IqPacket.TYPE.ERROR) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not query disco info for " + jid.toString()); + final boolean serverOrAccount = jid.equals(Jid.of(account.getServer())) || jid.equals(account.getJid().asBareJid()); + final boolean advancedStreamFeaturesLoaded; + if (serverOrAccount) { + synchronized (XmppConnection.this.disco) { + disco.put(jid, ServiceDiscoveryResult.empty()); + advancedStreamFeaturesLoaded = disco.containsKey(Jid.of(account.getServer())) && disco.containsKey(account.getJid().asBareJid()); + } + } else { + advancedStreamFeaturesLoaded = false; + } + if (advancedStreamFeaturesLoaded) { + enableAdvancedStreamFeatures(); + } } if (packet.getType() != IqPacket.TYPE.TIMEOUT) { if (mPendingServiceDiscoveries.decrementAndGet() == 0 From 6e1394ab40ef4a68e56edcc76d77073b757bf5fd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Aug 2019 12:04:27 +0200 Subject: [PATCH 13/25] make config flag for leave before join --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../conversations/services/XmppConnectionService.java | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index a8ed89a0f..89883a61e 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -113,6 +113,7 @@ public final class Config { public static final boolean ONLY_INTERNAL_STORAGE = false; //use internal storage instead of sdcard to save attachments public static final boolean IGNORE_ID_REWRITE_IN_MUC = true; + public static final boolean MUC_LEAVE_BEFORE_JOIN = true; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY * 5; public static final int MAM_MAX_MESSAGES = 750; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0c6df6d74..a286bf198 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1395,7 +1395,7 @@ public class XmppConnectionService extends Service { final boolean inProgressJoin; synchronized (account.inProgressConferenceJoins) { - inProgressJoin = conversation.getMode() == Conversational.MODE_MULTI && account.inProgressConferenceJoins.contains(conversation); + inProgressJoin = conversation.getMode() == Conversational.MODE_MULTI && (account.inProgressConferenceJoins.contains(conversation) || account.pendingConferenceJoins.contains(conversation)); } if (account.isOnlineAndConnected() && !inProgressJoin) { @@ -2546,8 +2546,10 @@ public class XmppConnectionService extends Service { synchronized (account.inProgressConferenceJoins) { account.inProgressConferenceJoins.add(conversation); } - sendPresencePacket(account, mPresenceGenerator.leave(conversation.getMucOptions())); - conversation.resetMucOptions(); + if (Config.MUC_LEAVE_BEFORE_JOIN) { + sendPresencePacket(account, mPresenceGenerator.leave(conversation.getMucOptions())); + } + conversation.resetMucOptions(); if (onConferenceJoined != null) { conversation.getMucOptions().flagNoAutoPushConfiguration(); } From e735be323e8691cd09743e36a4b70336d79ff477 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Aug 2019 17:04:31 +0200 Subject: [PATCH 14/25] catch npe on participants context menu --- .../eu/siacs/conversations/ui/ConferenceDetailsActivity.java | 5 +++++ src/main/res/values/strings.xml | 1 + 2 files changed, 6 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index ee2a15379..863fd5780 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -257,6 +257,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public boolean onContextItemSelected(MenuItem item) { + final User user = mUserPreviewAdapter.getSelectedUser(); + if (user == null) { + Toast.makeText(this, R.string.unable_to_perform_this_action, Toast.LENGTH_SHORT).show(); + return true; + } if (!MucDetailsContextMenuHelper.onContextItemSelected(item, mUserPreviewAdapter.getSelectedUser(), this)) { return super.onContextItemSelected(item); } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 8a8d31757..a387e9ec5 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -875,4 +875,5 @@ The file you selected is not a Conversations backup file This account has already been setup Please enter the password for this account + Unable to perform this action From 195988398e1f8910695dc9ec545a0b7a9630166c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Aug 2019 17:04:45 +0200 Subject: [PATCH 15/25] removed dead code in location activity --- .../java/eu/siacs/conversations/ui/LocationActivity.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/LocationActivity.java b/src/main/java/eu/siacs/conversations/ui/LocationActivity.java index 2bddf5b2d..80fb8983a 100644 --- a/src/main/java/eu/siacs/conversations/ui/LocationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/LocationActivity.java @@ -24,13 +24,11 @@ import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; import org.osmdroid.config.IConfigurationProvider; import org.osmdroid.tileprovider.tilesource.TileSourceFactory; -import org.osmdroid.tileprovider.tilesource.XYTileSource; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.CustomZoomButtonsController; import org.osmdroid.views.MapView; import org.osmdroid.views.overlay.Overlay; -import java.io.File; import java.io.IOException; import eu.siacs.conversations.BuildConfig; @@ -41,7 +39,6 @@ import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.ui.util.LocationHelper; import eu.siacs.conversations.ui.widget.Marker; import eu.siacs.conversations.ui.widget.MyLocation; -import eu.siacs.conversations.utils.LocationProvider; import eu.siacs.conversations.utils.ThemeHelper; public abstract class LocationActivity extends ActionBarActivity implements LocationListener { @@ -136,7 +133,7 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca map.setTileSource(TileSourceFactory.MAPNIK); map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER); map.setMultiTouchControls(true); - map.setTilesScaledToDpi(true); + map.setTilesScaledToDpi(false); mapController = map.getController(); mapController.setZoom(Config.Map.INITIAL_ZOOM_LEVEL); mapController.setCenter(pos); From c039ffcf352b6c6f7231e74a63bd9db028b3eaf3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Aug 2019 18:44:57 +0200 Subject: [PATCH 16/25] clean up logging --- .../siacs/conversations/services/XmppConnectionService.java | 5 ++--- .../java/eu/siacs/conversations/xmpp/XmppConnection.java | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index a286bf198..ded2ab3c7 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -428,11 +428,11 @@ public class XmppConnectionService extends Service { final int next = connection.getTimeToNextAttempt(); final boolean lowPingTimeoutMode = isInLowPingTimeoutMode(account); if (next <= 0) { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": error connecting account. reconnecting now. lowPingTimeout=" + Boolean.toString(lowPingTimeoutMode)); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": error connecting account. reconnecting now. lowPingTimeout=" + lowPingTimeoutMode); reconnectAccount(account, true, false); } else { final int attempt = connection.getAttempt() + 1; - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": error connecting account. try again in " + next + "s for the " + attempt + " time. lowPingTimeout=" + Boolean.toString(lowPingTimeoutMode)); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": error connecting account. try again in " + next + "s for the " + attempt + " time. lowPingTimeout=" + lowPingTimeoutMode); scheduleWakeUpCall(next, account.getUuid().hashCode()); } } @@ -1522,7 +1522,6 @@ public class XmppConnectionService extends Service { packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); } } - Log.d(Config.LOGTAG,packet.toString()); sendMessagePacket(account, packet); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0edac8a5e..250a11d2d 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1328,11 +1328,9 @@ public class XmppConnection implements Runnable { throw new IOException(); } else if (streamError.hasChild("host-unknown")) { throw new StateChangingException(Account.State.HOST_UNKNOWN); - } else if (streamError.hasChild("policy-violation")) { ; + } else if (streamError.hasChild("policy-violation")) { final String text = streamError.findChildContent("text"); - if (text != null) { - Log.d(Config.LOGTAG,account.getJid().asBareJid()+": policy violation. "+text); - } + Log.d(Config.LOGTAG,account.getJid().asBareJid()+": policy violation. "+text); throw new StateChangingException(Account.State.POLICY_VIOLATION); } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": stream error " + streamError.toString()); From 0770914edf04ab9700a50cf3feeb3afacb335e9b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Aug 2019 14:09:42 +0200 Subject: [PATCH 17/25] refactored filename and extension parsing --- .../http/HttpDownloadConnection.java | 16 +++--- .../services/AbstractConnectionManager.java | 19 +++++++ .../xmpp/jingle/JingleConnection.java | 57 +++++++++---------- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index b5aed7212..cc77a211c 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -77,22 +77,20 @@ public class HttpDownloadConnection implements Transferable { } else { mUrl = CryptoHelper.toHttpsUrl(new URL(message.getBody().split("\n")[0])); } - String[] parts = mUrl.getPath().toLowerCase().split("\\."); - String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; - String secondToLast = parts.length >= 2 ? parts[parts.length - 2] : null; - if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { + final AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(mUrl.getPath()); + if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { this.message.setEncryption(Message.ENCRYPTION_PGP); } else if (message.getEncryption() != Message.ENCRYPTION_OTR && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { this.message.setEncryption(Message.ENCRYPTION_NONE); } - String extension; - if (VALID_CRYPTO_EXTENSIONS.contains(lastPart)) { - extension = secondToLast; + final String ext; + if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { + ext = extension.secondary; } else { - extension = lastPart; + ext = extension.main; } - message.setRelativeFilePath(message.getUuid() + (extension != null ? ("." + extension) : "")); + message.setRelativeFilePath(message.getUuid() + (ext != null ? ("." + ext) : "")); this.file = mXmppConnectionService.getFileBackend().getFile(message, false); final String reference = mUrl.getRef(); if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 294af5d15..432c70390 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -109,4 +109,23 @@ public class AbstractConnectionManager { PowerManager powerManager = (PowerManager) mXmppConnectionService.getSystemService(Context.POWER_SERVICE); return powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); } + + public static class Extension { + public final String main; + public final String secondary; + + private Extension(String main, String secondary) { + this.main = main; + this.secondary = secondary; + } + + public static Extension of(String path) { + final int pos = path.lastIndexOf('/'); + final String filename = path.substring(pos + 1).toLowerCase(); + final String[] parts = filename.split("\\."); + final String main = parts.length >= 2 ? parts[parts.length - 1] : null; + final String secondary = parts.length >= 3 ? parts[parts.length - 2] : null; + return new Extension(main, secondary); + } + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 7751b95b1..45411ef62 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -414,41 +414,26 @@ public class JingleConnection implements Transferable { this.mXmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, packet.getFrom().asBareJid()); } Element fileSize = fileOffer.findChild("size"); - Element fileNameElement = fileOffer.findChild("name"); - if (fileNameElement != null) { - String[] filename = fileNameElement.getContent() - .toLowerCase(Locale.US).toLowerCase().split("\\."); - String extension = filename[filename.length - 1]; - if (VALID_IMAGE_EXTENSIONS.contains(extension)) { + final String path = fileOffer.findChildContent("name"); + if (path != null) { + AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(path); + if (VALID_IMAGE_EXTENSIONS.contains(extension.main)) { message.setType(Message.TYPE_IMAGE); - message.setRelativeFilePath(message.getUuid() + "." + extension); - } else if (VALID_CRYPTO_EXTENSIONS.contains( - filename[filename.length - 1])) { - if (filename.length == 3) { - extension = filename[filename.length - 2]; - if (VALID_IMAGE_EXTENSIONS.contains(extension)) { - message.setType(Message.TYPE_IMAGE); - message.setRelativeFilePath(message.getUuid() + "." + extension); - } else { - message.setType(Message.TYPE_FILE); - } - message.setEncryption(Message.ENCRYPTION_PGP); + message.setRelativeFilePath(message.getUuid() + "." + extension.main); + } else if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { + if (VALID_IMAGE_EXTENSIONS.contains(extension.secondary)) { + message.setType(Message.TYPE_IMAGE); + message.setRelativeFilePath(message.getUuid() + "." + extension.main); + } else { + message.setType(Message.TYPE_FILE); + message.setRelativeFilePath(message.getUuid() + (extension.secondary != null ? ("." + extension.secondary) : "")); } + message.setEncryption(Message.ENCRYPTION_PGP); } else { message.setType(Message.TYPE_FILE); + message.setRelativeFilePath(message.getUuid() + (extension.main != null ? ("." + extension.main) : "")); } - if (message.getType() == Message.TYPE_FILE) { - String suffix = ""; - if (!fileNameElement.getContent().isEmpty()) { - String parts[] = fileNameElement.getContent().split("/"); - suffix = parts[parts.length - 1]; - if (message.getEncryption() == Message.ENCRYPTION_PGP && (suffix.endsWith(".pgp") || suffix.endsWith(".gpg"))) { - suffix = suffix.substring(0, suffix.length() - 4); - } - } - message.setRelativeFilePath(message.getUuid() + "_" + suffix); - } - long size = Long.parseLong(fileSize.getContent()); + long size = parseLong(fileSize, 0); message.setBody(Long.toString(size)); conversation.add(message); mJingleConnectionManager.updateConversationUi(true); @@ -493,6 +478,18 @@ public class JingleConnection implements Transferable { } } + private static long parseLong(final Element element, final long l) { + final String input = element == null ? null : element.getContent(); + if (input == null) { + return l; + } + try { + return Long.parseLong(input); + } catch (Exception e) { + return l; + } + } + private void sendInitRequest() { JinglePacket packet = this.bootstrapPacket("session-initiate"); Content content = new Content(this.contentCreator, this.contentName); From 9ea4f1534b2a4c0edf666f81d83b2f1eb9f064f2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Aug 2019 14:12:13 +0200 Subject: [PATCH 18/25] pulled translations from transifex --- src/main/res/values-de/strings.xml | 1 + src/main/res/values-eu/strings.xml | 7 +++++++ src/main/res/values-gl/strings.xml | 1 + 3 files changed, 9 insertions(+) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 5c722c8d5..42a9ab49c 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -873,4 +873,5 @@ Die von dir ausgewählte Datei ist keine Sicherungsdatei von Conversations Dieses Konto wurde bereits eingerichtet Bitte gib das Passwort für dieses Konto ein + Diese Aktion kann nicht ausgeführt werden diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 0ac36d96a..cf5279270 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -864,4 +864,11 @@ Honek domeinu helbide baten itxura dauka Gehitu hala ere Honek kanal helbide baten itxura dauka + Babes-kopia fitxategiak partekatu + Conversations babes-kopia + Gertaera + Babes-kopia ireki + Hautatu duzun fitxategia ez da Conversations babes-kopia bat + Kontu hau konfiguratuta dago jada + Mesedez idatzi ezazu kontu honetarako pasahitza diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 9265165f4..35e58dad6 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -873,4 +873,5 @@ O ficheiro seleccionado non é un ficheiro de respaldo Conversations Esta conta xa foi configurada Introduza o contrasinal de esta conta + Non se puido completar a acción From d3ccba445af2425476f65b098d80338c5d2a2008 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Aug 2019 15:00:26 +0200 Subject: [PATCH 19/25] increased reconnection interval after policy violation --- .../eu/siacs/conversations/http/HttpDownloadConnection.java | 1 - src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index cc77a211c..8c366558d 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -22,7 +22,6 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Transferable; -import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 250a11d2d..23bb3cf6e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1329,6 +1329,7 @@ public class XmppConnection implements Runnable { } else if (streamError.hasChild("host-unknown")) { throw new StateChangingException(Account.State.HOST_UNKNOWN); } else if (streamError.hasChild("policy-violation")) { + this.lastConnect = SystemClock.elapsedRealtime(); final String text = streamError.findChildContent("text"); Log.d(Config.LOGTAG,account.getJid().asBareJid()+": policy violation. "+text); throw new StateChangingException(Account.State.POLICY_VIOLATION); @@ -1577,7 +1578,8 @@ public class XmppConnection implements Runnable { } public int getTimeToNextAttempt() { - final int interval = Math.min((int) (25 * Math.pow(1.3, attempt)), 300); + final int additionalTime = account.getLastErrorStatus() == Account.State.POLICY_VIOLATION ? 3 : 0; + final int interval = Math.min((int) (25 * Math.pow(1.3, (additionalTime + attempt))), 300); final int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000); return interval - secondsSinceLast; } From daf7e6224f5d54d58ec6f254d6e42995366259e5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Aug 2019 15:29:58 +0200 Subject: [PATCH 20/25] fixed pgp decryption of automatically accepted jingle ft --- .../eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 45411ef62..e44d85056 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -119,6 +119,8 @@ public class JingleConnection implements Transferable { } Log.d(Config.LOGTAG, "successfully transmitted file:" + file.getAbsolutePath() + " (" + CryptoHelper.bytesToHex(file.getSha1Sum()) + ")"); return; + } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { + account.getPgpDecryptionService().decrypt(message, true); } } else { if (ftVersion == Content.Version.FT_5) { //older Conversations will break when receiving a session-info @@ -423,7 +425,7 @@ public class JingleConnection implements Transferable { } else if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) { if (VALID_IMAGE_EXTENSIONS.contains(extension.secondary)) { message.setType(Message.TYPE_IMAGE); - message.setRelativeFilePath(message.getUuid() + "." + extension.main); + message.setRelativeFilePath(message.getUuid() + "." + extension.secondary); } else { message.setType(Message.TYPE_FILE); message.setRelativeFilePath(message.getUuid() + (extension.secondary != null ? ("." + extension.secondary) : "")); From fddd974412fccecbd88e1302afe77d31ab8329aa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 18 Aug 2019 13:03:43 +0200 Subject: [PATCH 21/25] do not put version info into disco This will reduce traffic by limiting the variety of different caps version hashes. It might also improve privacy by not leaking fdroid vs playstore vs self build information --- .../eu/siacs/conversations/generator/AbstractGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index dc47fc4ed..1270c1019 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -68,8 +68,8 @@ public abstract class AbstractGenerator { return this.mVersion; } - public String getIdentityName() { - return mXmppConnectionService.getString(R.string.app_name) + ' ' + getIdentityVersion(); + String getIdentityName() { + return mXmppConnectionService.getString(R.string.app_name); } public String getUserAgent() { From 8574bea280dbec11372e67e946f7c1ae44279cb7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 18 Aug 2019 13:12:02 +0200 Subject: [PATCH 22/25] pulled translations from transifex --- src/main/res/values-nl/strings.xml | 1 + src/main/res/values-pl/strings.xml | 1 + src/main/res/values-ro-rRO/strings.xml | 1 + 3 files changed, 3 insertions(+) diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 7b80bc1d5..9d65de57a 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -873,4 +873,5 @@ Het geselecteerde bestand is geen Conversations-back-upbestand Deze account is al ingesteld Voer het wachtwoord voor deze account in + Kan deze actie niet uitvoeren diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 2590592a6..1c7014337 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -891,4 +891,5 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Plik który otworzyłeś nie jest plikiem kopii zapasowej Conversations To konto zostało już ustawione Proszę podać hasło dla tego konta + Nie można wykonać tej akcji diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 971dd4c7b..668b2e60b 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -883,4 +883,5 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Fișierul selectat nu este o copie de siguranța Conversations Acest cont a fost deja configurat Va rugăm să introduceți parola pentru acest cont + Nu se poate realiza această acțiune From f11adf4c0204653e35d098e148034923f4308f6f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 Aug 2019 13:55:52 +0200 Subject: [PATCH 23/25] do not put default nick into bookmark if none has been set before --- .../conversations/entities/MucOptions.java | 16 ++++++++++------ .../services/XmppConnectionService.java | 19 +++++++++++++------ .../ui/StartConversationActivity.java | 5 +++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 62777f194..a70c67198 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -426,12 +426,16 @@ public class MucOptions { } else if (!conversation.getJid().isBareJid()) { return conversation.getJid().getResource(); } else { - final String displayName = normalize(account.getJid(), account.getDisplayName()); - if (displayName == null) { - return JidHelper.localPartOrFallback(account.getJid()); - } else { - return displayName; - } + return defaultNick(account); + } + } + + public static String defaultNick(final Account account) { + final String displayName = normalize(account.getJid(), account.getDisplayName()); + if (displayName == null) { + return JidHelper.localPartOrFallback(account.getJid()); + } else { + return displayName; } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ded2ab3c7..e18ae32fb 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2801,7 +2801,13 @@ public class XmppConnectionService extends Service { final Bookmark bookmark = conversation.getBookmark(); final String bookmarkedNick = bookmark == null ? null : bookmark.getNick(); if (bookmark != null && (tookProposedNickFromBookmark || TextUtils.isEmpty(bookmarkedNick)) && !full.getResource().equals(bookmarkedNick)) { - Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": persist nick '" + full.getResource() + "' into bookmark for " + conversation.getJid().asBareJid()); + final Account account = conversation.getAccount(); + final String defaultNick = MucOptions.defaultNick(account); + if (TextUtils.isEmpty(bookmarkedNick) && full.getResource().equals(defaultNick)) { + Log.d(Config.LOGTAG,account.getJid().asBareJid()+": do not overwrite empty bookmark nick with default nick for "+conversation.getJid().asBareJid()); + return; + } + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": persist nick '" + full.getResource() + "' into bookmark for " + conversation.getJid().asBareJid()); bookmark.setNick(full.getResource()); pushBookmarks(bookmark.getAccount()); } @@ -4420,11 +4426,12 @@ public class XmppConnectionService extends Service { } public void saveConversationAsBookmark(Conversation conversation, String name) { - Account account = conversation.getAccount(); - Bookmark bookmark = new Bookmark(account, conversation.getJid().asBareJid()); - if (!conversation.getJid().isBareJid()) { - bookmark.setNick(conversation.getJid().getResource()); - } + final Account account = conversation.getAccount(); + final Bookmark bookmark = new Bookmark(account, conversation.getJid().asBareJid()); + final String nick = conversation.getJid().getResource(); + if (nick != null && !nick.isEmpty() && !nick.equals(MucOptions.defaultNick(account))) { + bookmark.setNick(nick); + } if (!TextUtils.isEmpty(name)) { bookmark.setBookmarkName(name); } diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index a48dd230b..4de40206c 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -62,6 +62,7 @@ import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.services.XmppConnectionService; @@ -1021,8 +1022,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne } else { final Bookmark bookmark = new Bookmark(account, conferenceJid.asBareJid()); bookmark.setAutojoin(getBooleanPreference("autojoin", R.bool.autojoin)); - String nick = conferenceJid.getResource(); - if (nick != null && !nick.isEmpty()) { + final String nick = conferenceJid.getResource(); + if (nick != null && !nick.isEmpty() && !nick.equals(MucOptions.defaultNick(account))) { bookmark.setNick(nick); } account.getBookmarks().add(bookmark); From c84a89924e65544b25719e1f5855f5bfec17da55 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 Aug 2019 14:27:11 +0200 Subject: [PATCH 24/25] include pgp sig and status in presence to non anon muc --- .../generator/PresenceGenerator.java | 23 ++++++++------ .../services/XmppConnectionService.java | 31 +++---------------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java index df6b9eaca..d3143f01e 100644 --- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java @@ -50,15 +50,20 @@ public class PresenceGenerator extends AbstractGenerator { return selfPresence(account, status, true); } - public PresencePacket selfPresence(Account account, Presence.Status status, boolean includePgpAnnouncement) { - PresencePacket packet = new PresencePacket(); - if(status.toShowString() != null) { - packet.addChild("show").setContent(status.toShowString()); - } - packet.setFrom(account.getJid()); - final String sig = account.getPgpSignature(); - if (includePgpAnnouncement && sig != null && mXmppConnectionService.getPgpEngine() != null) { - packet.addChild("x", "jabber:x:signed").setContent(sig); + public PresencePacket selfPresence(final Account account, final Presence.Status status, final boolean personal) { + final PresencePacket packet = new PresencePacket(); + if (personal) { + final String sig = account.getPgpSignature(); + final String message = account.getPresenceStatusMessage(); + if(status.toShowString() != null) { + packet.addChild("show").setContent(status.toShowString()); + } + if (!TextUtils.isEmpty(message)) { + packet.addChild(new Element("status").setContent(message)); + } + if (sig != null && mXmppConnectionService.getPgpEngine() != null) { + packet.addChild("x", "jabber:x:signed").setContent(sig); + } } final String capHash = getCapHash(account); if (capHash != null) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e18ae32fb..d40a3ccd5 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -68,13 +68,9 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; - import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.android.JabberIdContact; @@ -101,9 +97,8 @@ import eu.siacs.conversations.generator.AbstractGenerator; import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.generator.MessageGenerator; import eu.siacs.conversations.generator.PresenceGenerator; -import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.http.CustomURLStreamHandlerFactory; -import eu.siacs.conversations.http.services.MuclumbusService; +import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.parser.AbstractParser; import eu.siacs.conversations.parser.IqParser; import eu.siacs.conversations.parser.MessageParser; @@ -129,9 +124,9 @@ import eu.siacs.conversations.utils.Resolver; import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.utils.StringUtils; import eu.siacs.conversations.utils.WakeLockHelper; -import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.OnBindListener; import eu.siacs.conversations.xmpp.OnContactStatusChanged; import eu.siacs.conversations.xmpp.OnIqPacketReceived; @@ -155,11 +150,6 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; import me.leolin.shortcutbadger.ShortcutBadger; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; -import retrofit2.converter.gson.GsonConverterFactory; import rocks.xmpp.addr.Jid; public class XmppConnectionService extends Service { @@ -2834,15 +2824,8 @@ public class XmppConnectionService extends Service { } }); - PresencePacket packet = new PresencePacket(); - packet.setTo(joinJid); - packet.setFrom(conversation.getAccount().getJid()); - - String sig = account.getPgpSignature(); - if (sig != null) { - packet.addChild("status").setContent("online"); - packet.addChild("x", "jabber:x:signed").setContent(sig); - } + final PresencePacket packet = mPresenceGenerator.selfPresence(account, Presence.Status.ONLINE, options.nonanonymous()); + packet.setTo(joinJid); sendPresencePacket(account, packet); } else { conversation.setContactJid(joinJid); @@ -4112,11 +4095,7 @@ public class XmppConnectionService extends Service { } else { status = getTargetPresence(); } - PresencePacket packet = mPresenceGenerator.selfPresence(account, status); - String message = account.getPresenceStatusMessage(); - if (message != null && !message.isEmpty()) { - packet.addChild(new Element("status").setContent(message)); - } + final PresencePacket packet = mPresenceGenerator.selfPresence(account, status); if (mLastActivity > 0 && includeIdleTimestamp) { long since = Math.min(mLastActivity, System.currentTimeMillis()); //don't send future dates packet.addChild("idle", Namespace.IDLE).setAttribute("since", AbstractGenerator.getTimestamp(since)); From c92cc5f5b7fb17989f2bf0d82b777e93905f236e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 Aug 2019 14:48:10 +0200 Subject: [PATCH 25/25] version bump to 2.5.6 + changelog --- CHANGELOG.md | 4 ++++ build.gradle | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c57da8926..6f484990f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### Version 2.5.6 +* fixes for Jingle file transfer +* fixed some rare crashes + ### Version 2.5.5 * allow backups to be restored from anywhere * bug fixes diff --git a/build.gradle b/build.gradle index 23058b43c..99c1ebfaa 100644 --- a/build.gradle +++ b/build.gradle @@ -81,8 +81,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 334 - versionName "2.5.5" + versionCode 336 + versionName "2.5.6" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId