diff --git a/CHANGELOG.md b/CHANGELOG.md index 14dbf7755..091e36daf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +### Version 2.7.1 + +* Fix avatar selection on some Android 10 devices +* Fix file transfer for larger files + ### Version 2.7.0 * Provide PDF preview on Android 5+ diff --git a/README.md b/README.md index 5db157c98..b2808a279 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ FCM (Google Push) allows an app to wake up from *Doze* which is (as the name sug #### Conversations doesn’t work for me. Where can I get help? -You can join our conference room on `support@conference.chat.sum7.eu`. +You can join our conference room on [`support@conference.chat.sum7.eu`](https://conversations.im/j/support@conference.chat.sum7.eu). A lot of people in there are able to answer basic questions about the usage of Conversations or can provide you with tips on running your own XMPP server. If you found a bug or your app crashes please read the Developer / Report Bugs @@ -265,7 +265,7 @@ and introduce yourself to `iNPUTmice` so he can approve your join request. #### How do I backup / move Conversations to a new device? On the one hand Conversations supports Message Archive Management to keep a server side history of your messages so when migrating to a new device that device can display your entire history. However that does not work if you enable OMEMO due to its forward secrecy. (Read [The State of Mobile XMPP in 2016](https://gultsch.de/xmpp_2016.html) especially the section on encryption.) -As of version 2.4.0 an integrated Backup & Restore function will help with this, go to Settings → Expert settings → Create backup. A notification will pop-up during the creation process that will announce you when it's ready. After the files, one for each account, are created, you can move the **Conversations** folder *(if you want your old media files too)* or only the **Conversations/Backup** folder *(for OMEMO keys and history only)* to your new device (or to a storage place) where a freshly installed Conversations can restore each account. Don't forget to enable the accounts after a succesful restore. +As of version 2.4.0 an integrated Backup & Restore function will help with this, go to Settings and you’ll find a setting called Create backup. A notification will pop-up during the creation process that will announce you when it's ready. After the files, one for each account, are created, you can move the **Conversations** folder *(if you want your old media files too)* or only the **Conversations/Backup** folder *(for OMEMO keys and history only)* to your new device (or to a storage place) where a freshly installed Conversations can restore each account. Don't forget to enable the accounts after a succesful restore. This backup method will include your OMEMO keys. Due to forward secrecy you will not be able to recover messages sent and received between creating the backup and restoring it. If you have a server side archive (MAM) those messages will be retrieved but displayed as *unable to decrypt*. For technical reasons you might also lose the first message you either sent or receive after the restore; for each conversation you have. This message will then also show up as *unable to decrypt*, but this will automatically recover itself as long as both participants are on Conversations 2.3.11+. Note that this doesn’t happen if you just transfer to a new phone and no messages have been exchanged between backup and restore. diff --git a/build.gradle b/build.gradle index e9906e95f..8367d7a1b 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ dependencies { compatImplementation "com.android.support:support-emoji-appcompat:$supportLibVersion" conversationsFreeCompatImplementation "com.android.support:support-emoji-bundled:$supportLibVersion" quicksyFreeCompatImplementation "com.android.support:support-emoji-bundled:$supportLibVersion" - implementation 'org.bouncycastle:bcmail-jdk15on:1.58' + implementation 'org.bouncycastle:bcmail-jdk15on:1.64' //zxing stopped supporting Java 7 so we have to stick with 3.3.3 //https://github.com/zxing/zxing/issues/1170 implementation 'com.google.zxing:core:3.3.3' @@ -90,8 +90,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 25 - versionCode 364 - versionName "2.7.0" + versionCode 367 + versionName "2.7.1" archivesBaseName += "-$versionName" applicationId "eu.sum7.conversations" resValue "string", "applicationId", applicationId diff --git a/metadata/en-US/changelogs/367.txt b/metadata/en-US/changelogs/367.txt new file mode 100644 index 000000000..a882ff386 --- /dev/null +++ b/metadata/en-US/changelogs/367.txt @@ -0,0 +1,2 @@ +• Fix avatar selection on some Android 10 devices +• Fix file transfer for larger files diff --git a/src/conversations/res/values-gl/strings.xml b/src/conversations/res/values-gl/strings.xml index 25a40a42a..5401a977d 100644 --- a/src/conversations/res/values-gl/strings.xml +++ b/src/conversations/res/values-gl/strings.xml @@ -1,10 +1,10 @@ - Escolla o seu provedor XMPP + Escolle o teu provedor XMPP Utilizar chat.sum7.eu Crear nova conta - Xa posúe unha conta XMPP? Este pode ser o caso se xa está a utilizar outro cliente XMPP ou utilizou Conversations previamente. Se non é así pode crear unha nova conta agora mesmo.\nTruco: Algúns provedores de correo tamén proporcionan contas XMPP. - XMPP é unha rede de mensaxería independente do provedor. Pode utilizar este cliente con calquer provedor XMPP da súa elección.\nMais para a súa conveniencia fixemos que fose doado crear unha conta en chat.sum7.eu; un provedor especialmente axeitado para utilizar con Conversations. + Xa posúes unha conta XMPP? Este pode ser o caso se xa estás a utilizar outro cliente XMPP ou utilizaches Conversations previamente. Se non é así podes crear unha nova conta agora mesmo.\nTruco: Algúns provedores de correo tamén proporcionan contas XMPP. + XMPP é unha rede de mensaxería independente do provedor. Podes utilizar este cliente con calquera provedor XMPP da túa elección.\nMais para a tua conveniencia fixemos que fose doado crear unha conta en chat.sum7.eu; un provedor especialmente axeitado para utilizar con Conversations. Convidáronte a %1$s. Guiarémoste no proceso para crear unha conta.\nAo escoller %1$s como provedor poderás comunicarte con usuarias de outros provedores cando lles deas o teu enderezo XMPP completo. Convidáronte a %1$s. Escollemos un nome de usuaria por ti. Guiarémoste no proceso de crear unha conta.\nPoderás comunicarte con usuarias de outros provedores cando lles digas o teu enderezo XMPP completo. O convite do teu servidor diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index d58bd2e21..750029931 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -100,7 +100,6 @@ public final class Config { public static final boolean REMOVE_BROKEN_DEVICES = false; public static final boolean OMEMO_PADDING = false; public static final boolean PUT_AUTH_TAG_INTO_KEY = true; - public static final boolean TWELVE_BYTE_IV = true; public static final boolean USE_BOOKMARKS2 = false; diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 018a86b5d..e67755586 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -651,7 +651,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { final boolean wipe, final boolean firstAttempt) { final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null; - IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles( + final IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles( signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(), preKeyRecords, getOwnDeviceId(), publishOptions); Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing..."); diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java index 13082deac..bec0ff9e2 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java @@ -115,14 +115,13 @@ public class XmppAxolotlMessage { generator.init(128); return generator.generateKey().getEncoded(); } catch (NoSuchAlgorithmException e) { - Log.e(Config.LOGTAG, e.getMessage()); - return null; + throw new IllegalStateException(e); } } private static byte[] generateIv() { final SecureRandom random = new SecureRandom(); - byte[] iv = new byte[Config.TWELVE_BYTE_IV ? 12 : 16]; + final byte[] iv = new byte[12]; random.nextBytes(iv); return iv; } diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java index c88af6f95..c0b3512a3 100644 --- a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java +++ b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java @@ -1,7 +1,10 @@ package eu.siacs.conversations.entities; +import android.util.Log; + import java.io.File; +import eu.siacs.conversations.Config; import eu.siacs.conversations.utils.MimeUtils; public class DownloadableFile extends File { @@ -66,6 +69,7 @@ public class DownloadableFile extends File { this.iv = new byte[]{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf }; System.arraycopy(keyIvCombo, 0, aeskey, 0, 32); } + Log.d(Config.LOGTAG,"using "+this.iv.length+"-byte IV for file transmission"); } public void setKey(byte[] key) { diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 360103aa0..e44d2a2c0 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -613,6 +613,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS && !message.isGeoUri() && !this.isGeoUri() && + !message.isOOb() && + !this.isOOb() && !message.treatAsDownloadable() && !this.treatAsDownloadable() && !message.getBody().startsWith(ME_COMMAND) && diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 08fae1bc5..430c7532b 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -105,11 +105,12 @@ public class HttpUploadConnection implements Transferable { } else { this.mime = this.file.getMimeType(); } + final long originalFileSize = file.getSize(); this.delayed = delay; if (Config.ENCRYPT_ON_HTTP_UPLOADED || message.getEncryption() == Message.ENCRYPTION_AXOLOTL || message.getEncryption() == Message.ENCRYPTION_OTR) { - this.key = new byte[Config.TWELVE_BYTE_IV ? 44 : 48]; + this.key = new byte[44]; mXmppConnectionService.getRNG().nextBytes(this.key); this.file.setKeyAndIv(this.key); } @@ -128,7 +129,7 @@ public class HttpUploadConnection implements Transferable { md5 = null; } - this.file.setExpectedSize(file.getSize() + (file.getKey() != null ? 16 : 0)); + this.file.setExpectedSize(originalFileSize + (file.getKey() != null ? 16 : 0)); message.resetFileParams(); this.mSlotRequester.request(method, account, file, mime, md5, new SlotRequester.OnSlotRequested() { @Override diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 81f3f80bc..98721aaf4 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -5,6 +5,14 @@ import android.os.PowerManager; import android.os.SystemClock; import android.util.Log; +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.io.CipherInputStream; +import org.bouncycastle.crypto.io.CipherOutputStream; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; + import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; @@ -15,24 +23,15 @@ import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.util.concurrent.atomic.AtomicLong; -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.utils.Compatibility; -import eu.siacs.conversations.utils.CryptoHelper; public class AbstractConnectionManager { - private static final String KEYTYPE = "AES"; - private static final String CIPHERMODE = "AES/GCM/NoPadding"; - private static final String PROVIDER = "BC"; private static final int UI_REFRESH_THRESHOLD = 250; private static final AtomicLong LAST_UI_UPDATE_CALL = new AtomicLong(0); protected XmppConnectionService mXmppConnectionService; @@ -43,10 +42,8 @@ public class AbstractConnectionManager { public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException { if (file.getKey() != null && file.getIv() != null) { - final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER); - SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE); - IvParameterSpec ivSpec = new IvParameterSpec(file.getIv()); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); + cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv())); return new CipherInputStream(is, cipher); } else { return is; @@ -61,17 +58,15 @@ public class AbstractConnectionManager { return os; } } catch (FileNotFoundException e) { - Log.d(Config.LOGTAG,"unable to create output stream", e); + Log.d(Config.LOGTAG, "unable to create output stream", e); return null; } try { - final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER); - SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE); - IvParameterSpec ivSpec = new IvParameterSpec(file.getIv()); - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); + cipher.init(false, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv())); return new CipherOutputStream(os, cipher); } catch (Exception e) { - Log.d(Config.LOGTAG,"unable to create cipher output stream", e); + Log.d(Config.LOGTAG, "unable to create cipher output stream", e); return null; } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4280e6f00..63d6a1911 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1838,7 +1838,7 @@ public class XmppConnectionService extends Service { private void markFileDeleted(final String path) { synchronized (FILENAMES_TO_IGNORE_DELETION) { if (FILENAMES_TO_IGNORE_DELETION.remove(path)) { - Log.d(Config.LOGTAG,"ignored deletion of "+path); + Log.d(Config.LOGTAG, "ignored deletion of " + path); return; } } @@ -1854,7 +1854,7 @@ public class XmppConnectionService extends Service { for (Conversation conversation : getConversations()) { deleted |= conversation.markAsDeleted(uuids); } - for(final String uuid : uuids) { + for (final String uuid : uuids) { evictPreview(uuid); } if (deleted) { @@ -3172,16 +3172,20 @@ public class XmppConnectionService extends Service { conversation.setAttribute("accept_non_anonymous", true); updateConversation(conversation); } - IqPacket request = new IqPacket(IqPacket.TYPE.GET); + if (options.containsKey("muc#roomconfig_moderatedroom")) { + final boolean moderated = "1".equals(options.getString("muc#roomconfig_moderatedroom")); + options.putString("members_by_default", moderated ? "0" : "1"); + } + final IqPacket request = new IqPacket(IqPacket.TYPE.GET); request.setTo(conversation.getJid().asBareJid()); request.query("http://jabber.org/protocol/muc#owner"); sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() == IqPacket.TYPE.RESULT) { - Data data = Data.parse(packet.query().findChild("x", Namespace.DATA)); + final Data data = Data.parse(packet.query().findChild("x", Namespace.DATA)); data.submit(options); - IqPacket set = new IqPacket(IqPacket.TYPE.SET); + final IqPacket set = new IqPacket(IqPacket.TYPE.SET); set.setTo(conversation.getJid().asBareJid()); set.query("http://jabber.org/protocol/muc#owner").addChild(data); sendIqPacket(account, set, new OnIqPacketReceived() { @@ -4580,7 +4584,7 @@ public class XmppConnectionService extends Service { public void evictPreview(String uuid) { if (mBitmapCache.remove(uuid) != null) { - Log.d(Config.LOGTAG,"deleted cached preview"); + Log.d(Config.LOGTAG, "deleted cached preview"); } } diff --git a/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java index 4c7b77276..898f607c4 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java @@ -49,6 +49,8 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.ui.interfaces.OnAvatarPublication; import eu.siacs.conversations.ui.util.PendingItem; +import static eu.siacs.conversations.ui.PublishProfilePictureActivity.REQUEST_CHOOSE_PICTURE; + public class PublishGroupChatProfilePictureActivity extends XmppActivity implements OnAvatarPublication { private final PendingItem pendingConversationUuid = new PendingItem<>(); private ActivityPublishProfilePictureBinding binding; @@ -93,7 +95,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme configureActionBar(getSupportActionBar()); this.binding.cancelButton.setOnClickListener((v) -> this.finish()); this.binding.secondaryHint.setVisibility(View.GONE); - this.binding.accountImage.setOnClickListener((v) -> this.chooseAvatar()); + this.binding.accountImage.setOnClickListener((v) -> PublishProfilePictureActivity.chooseAvatar(this)); Intent intent = getIntent(); String uuid = intent == null ? null : intent.getStringExtra("uuid"); if (uuid != null) { @@ -113,7 +115,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) { - CropImage.ActivityResult result = CropImage.getActivityResult(data); + final CropImage.ActivityResult result = CropImage.getActivityResult(data); if (resultCode == RESULT_OK) { this.uri = result.getUri(); if (xmppConnectionServiceBound) { @@ -125,17 +127,13 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show(); } } + } else if (requestCode == REQUEST_CHOOSE_PICTURE) { + if (resultCode == RESULT_OK) { + PublishProfilePictureActivity.cropUri(this, data.getData()); + } } } - private void chooseAvatar() { - CropImage.activity() - .setOutputCompressFormat(Bitmap.CompressFormat.PNG) - .setAspectRatio(1, 1) - .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE) - .start(this); - } - @Override public void onAvatarPublicationSucceeded() { runOnUiThread(() -> { diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 8f91ffdc1..db05cc8bf 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -1,8 +1,10 @@ package eu.siacs.conversations.ui; +import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.support.annotation.StringRes; import android.util.Log; @@ -26,6 +28,8 @@ import eu.siacs.conversations.utils.PhoneHelper; public class PublishProfilePictureActivity extends XmppActivity implements XmppConnectionService.OnAccountUpdate, OnAvatarPublication { + public static final int REQUEST_CHOOSE_PICTURE = 0x1337; + private ImageView avatar; private TextView hintOrWarning; private TextView secondaryHint; @@ -106,7 +110,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC } finish(); }); - this.avatar.setOnClickListener(v -> chooseAvatar()); + this.avatar.setOnClickListener(v -> chooseAvatar(this)); this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext()); if (savedInstanceState != null) { this.avatarUri = savedInstanceState.getParcelable("uri"); @@ -139,15 +143,28 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show(); } } + } else if (requestCode == REQUEST_CHOOSE_PICTURE) { + if (resultCode == RESULT_OK) { + cropUri(this, data.getData()); + } } } - private void chooseAvatar() { - CropImage.activity() - .setOutputCompressFormat(Bitmap.CompressFormat.PNG) - .setAspectRatio(1, 1) - .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE) - .start(this); + public static void chooseAvatar(final Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("image/*"); + activity.startActivityForResult( + Intent.createChooser(intent, activity.getString(R.string.attach_choose_picture)), + REQUEST_CHOOSE_PICTURE + ); + } else { + CropImage.activity() + .setOutputCompressFormat(Bitmap.CompressFormat.PNG) + .setAspectRatio(1, 1) + .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE) + .start(activity); + } } @Override @@ -181,10 +198,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC final Uri uri = intent != null ? intent.getData() : null; if (uri != null && handledExternalUri.compareAndSet(false,true)) { - CropImage.activity(uri).setOutputCompressFormat(Bitmap.CompressFormat.PNG) - .setAspectRatio(1, 1) - .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE) - .start(this); + cropUri(this, uri); return; } @@ -194,6 +208,13 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC configureActionBar(getSupportActionBar(), !this.mInitialAccountSetup && !handledExternalUri.get()); } + public static void cropUri(final Activity activity, final Uri uri) { + CropImage.activity(uri).setOutputCompressFormat(Bitmap.CompressFormat.PNG) + .setAspectRatio(1, 1) + .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE) + .start(activity); + } + protected void loadImageIntoPreview(Uri uri) { Bitmap bm = null; diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index fe117fb55..7c1ff5837 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -251,7 +251,7 @@ public class Resolver { ResolverResult results = resolveWithFallback(hostname, type, authenticated); for (D record : results.getAnswersOrEmptySet()) { Result resolverResult = Result.fromRecord(srv, directTls); - resolverResult.authenticated = results.isAuthenticData() && authenticated; + resolverResult.authenticated = results.isAuthenticData() && authenticated; //TODO technically it doesn’t matter if the IP was authenticated resolverResult.ip = record.getInetAddress(); list.add(resolverResult); } diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index edbe10a9b..b7d629de3 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -292,6 +292,7 @@ A csoportos csevegés le lett állítva Többé már nincs ebben a csoportos csevegésben használt fiók: %s + kiszolgálva itt: %s %s ellenőrzése a HTTP gépen Nincs kapcsolódva. Próbálja meg később újra %s méretének ellenőrzése @@ -556,6 +557,7 @@ Adatvédelem Téma Színpaletta kiválasztása + Automatikus Világos téma Sötét téma Nem sikerült kapcsolódni a OpenKeychain alkalmazáshoz diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 5b0b549c3..5c276ef16 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -292,6 +292,7 @@ La chat di gruppo è stata chiusa Non sei più in questa chat di gruppo usando l’account %s + ospitato su %s Controllo %s su host HTTP Non sei connesso. Riprova più tardi Controlla dimensione %s diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 8c1e45e05..746e8022e 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -292,6 +292,7 @@ Konferencja została zamknięta Nie uczestniczysz już w tej konferencji używając konta %s + udostępnione na %s Sprawdzanie %s na hoście HTTP Brak połączenia. Spróbuj ponownie później Sprawdź rozmiar %s diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index bb842740f..f43629a83 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -151,6 +151,7 @@ Användarnamn används redan Registrering klar Servern stödjer inte registrering + TLS-förhandling misslyckades Kränkning av policy Inkompatibel server Strömningsfel @@ -322,6 +323,7 @@ Regenerera OMEMO-nyckel Rensa enheter Är du säker på att du vill rensa alla andra enheter från OMEMO-annonsering? Nästa gång dina enheter ansluter kommer de att återannonsera sig, men de kanske inte tar emot enheter under tiden. + Något gick fel Hämtar historik från server Ingen mer historik på server Uppdaterar… @@ -350,6 +352,7 @@ Du deltar ej Aldrig Tills vidare + Läsmarkera Input Skicka med enter Använd enter-knappen för att skicka meddelande @@ -493,6 +496,7 @@ Privatliv Tema Välj färgschema + Automatisk Ljust tema Mörkt tema Kan inte ansluta till OpenKeychain @@ -543,6 +547,8 @@ Jag följde denna länk från en trovärdig källa Du håller på att verifiera OMEMO-nyckeln för %1$s efter att du följt en länk. Detta är endast säkert om du följde länken från en trovärdig källa där endast %2$s kan ha publiserat denna länk. Verifiera OMEMO-nycklar + Visa inaktiva + Dölj inaktiva Lita ej på enhet Är du säker på att du vill ta bort verifieringen av denna enhet?\nDenna enhet och meddelanden som kommer från enheten kommer att markeras som ej pålitliga. @@ -586,27 +592,74 @@ Sessionsfel Idag Igår + Bekräfta värdnamn med DNSSEC Certifikatet innehåller ej en XMPP-adress Spela in video Meddelande Godkänn okänt certifikat? + Servercertifikatet är inte signerat av en känd certifikatutfärdare. + Vill du ansluta ändå? + Certifikatdetaljer: Utkast: + Skapa genväg + Liten + Mellan + Stor + Kopiera plats + Dela plats Dela plats Visa plats Dela + Var god dröj... + Conversations behöver tillgång till mikrofonen + GIF Kopiera XMPP-adress + Smeknamn + Namn + Att ange ett namn är valfritt Gruppchattens namn + Kan inte spara inspelning Deltagare + Mellan (360p) + Hög (720p) Välj ett land telefonnummer Bekräfta ditt telefonnummer + Ja + Nej + Bekräftar... + Okänt nätverksfel. + För många försök + Du använder en föråldrad version av denna app. + Ditt namn + Skriv in ditt namn + Avslå begäran + Installera Orbot + Starta Orbot + e-bok + Öppna med... + Välj konto Skapa gruppchatt Skapa sluten gruppchatt Kanalnamn + XMPP-adress Vänligen ange ett namn på kanalen + Ange en XMPP-adress + Detta är en XMPP-adress. Ange ett namn. Denna kanal finns redan Du har gått med i en befintlig kanal + XMPP-adresser är synliga för administratörer. + XMPP-adresser är synliga för alla. Denna slutna gruppchatt har inga deltagare. + Hantera rättigheter + För stor fil + Bifoga Upptäck kanaler + Jag har redan ett konto + Lägg till befintligt konto + Skapa nytt konto + Detta verkar vara ett domännamn + Lägg till ändå Detta ser ut som en kanaladress + Om diff --git a/src/quicksy/res/values-gl/strings.xml b/src/quicksy/res/values-gl/strings.xml index b1675f6e0..9641086fe 100644 --- a/src/quicksy/res/values-gl/strings.xml +++ b/src/quicksy/res/values-gl/strings.xml @@ -1,26 +1,26 @@ Quicksy fallou - Ao enviar lotes de rexistro está a axudar no desenvolvemento de Quicksy\nAviso: vai utilizar a súa conta XMPP para enviar o rexistro ao equipo de desenvolvemento. - Quicksy utiliza unha app de terceiros chamada OpenKeychain para cifrar e descifrar as mensaxes e xestionar a súas chaves públicas.\n\nOpenKeychain en licenza GPLv3 e está dispoñible en F-Droid e Google Play.\n\n(Por favor, reinicie Quicksy ao rematar). - Quicksy non pode cifrar as súas mensaxes porque os seu contacto non publicou as sua chave pública.\n\nPor favor, solicite ao contacto configure OpenPGP. - Quicksy non pode cifrar as súas mensaxes porque os seus contactos non están a publicar a súa chave pública.\n\nPor favor, pídalle aos seus contactos que configuren OpenPGP. + Ao enviar lotes de rexistro estás a axudar no desenvolvemento de Quicksy\nAviso: vas utilizar a tua conta XMPP para enviar o rexistro ao equipo de desenvolvemento. + Quicksy utiliza unha app de terceiros chamada OpenKeychain para cifrar e descifrar as mensaxes e xestionar a tuas chaves públicas.\n\nOpenKeychain ten licenza GPLv3 e está dispoñible en F-Droid e Google Play.\n\n(Por favor, reinicia Quicksy ao rematar). + Quicksy non pode cifrar as tuas mensaxes porque o teu contacto non publicou as sua chave pública.\n\nPor favor, solicita ao contacto que configure OpenPGP. + Quicksy non pode cifrar as tuas mensaxes porque os teus contactos non están a publicar a súa chave pública.\n\nPor favor, pídelle aos teus contactos que configuren OpenPGP. O período de tempo que Quicksy permanece acalado tras ver actividade en outro dispositivo - Enviando trazas de rexistro está axudando ao desenvolvemento de Quicksy + Enviando trazas de rexistro estás axudando ao desenvolvemento de Quicksy Quicksy precisa acceso ao almacenamento externo Quicksy precisa acceso a cámara - O seu dispositivo está a realizar optimizacións de batería intensivas con Quicksy que poderían levar a que as notificacións tarden en chegar ou que as mensaxes se perdan.\nRecomendamos desactivalas. - O seu dispositivo está a realizar optimizacións de batería moi fortes con Quicksy que poderían levar a que se retrasen as notificacións ou que se perdan mensaxes.\n\nPediráselle que as desactive. - Permitir a todos os seus contactos saber cando está a utilizar Quicksy - O seu sistema operativo está restrinxindo o acceso a internet en segundo plano para Quicksy. Para recibir notificacións ou novas mensaxes debería permitir a Quicksy acceso non limitado cando se activa o aforro de datos.\nQuicksy esforzarase en aforrar datos cando sexa posible. - O seu dispositivo non soporta a desactivación do aforro de datos para Quicksy. - Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisa engadir a Quicksy na lista de apps protexidas. - Quicksy non pode enviar mensaxes cifradas a %1$s. Esto podería deberse a que o seu contacto utiliza un servidor antigo ou un cliente sen soporte OMEMO. + O teu dispositivo está a realizar optimizacións de batería intensivas con Quicksy que poderían levar a que as notificacións tarden en chegar ou que as mensaxes se perdan.\nRecomendamos desactivalas. + O teu dispositivo está a realizar optimizacións de batería moi fortes con Quicksy que poderían levar a que se retrasen as notificacións ou que se perdan mensaxes.\n\nVaiche solicitar que as desactives. + Permitir a todos os teus contactos saber cando estás a utilizar Quicksy + O teu sistema operativo está restrinxindo o acceso a internet en segundo plano para Quicksy. Para recibir notificacións ou novas mensaxes deberías permitir a Quicksy acceso non limitado cando se activa o aforro de datos.\nQuicksy esforzarase en aforrar datos cando sexa posible. + O teu dispositivo non soporta a desactivación do aforro de datos para Quicksy. + Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisas engadir a Quicksy na lista de apps protexidas. + Quicksy non pode enviar mensaxes cifradas a %1$s. Esto podería deberse a que o teu contacto utiliza un servidor antigo ou un cliente sen soporte OMEMO. Quicksy precisa acceder ao micrófono 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. + Quicksy non está dispoñible no teu país. + Non se puido verificar a identidade do servidor. Fallo de seguridade descoñecido. Caducou a conexión mentras conectaba co servidor.