aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--CHANGELOG.md4
-rw-r--r--README.md10
-rw-r--r--build.gradle4
-rw-r--r--src/main/java/eu/siacs/conversations/Config.java39
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Bookmark.java13
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Contact.java19
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Conversation.java10
-rw-r--r--src/main/java/eu/siacs/conversations/entities/ListItem.java12
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Message.java1
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java8
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java36
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java7
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java9
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java10
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java13
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java19
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java5
-rw-r--r--src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java18
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java4
-rw-r--r--src/main/java/eu/siacs/conversations/utils/UIHelper.java4
-rw-r--r--src/main/res/menu/message_context.xml4
-rw-r--r--src/main/res/values/strings.xml3
-rw-r--r--src/main/res/xml/preferences.xml2
24 files changed, 191 insertions, 65 deletions
diff --git a/.travis.yml b/.travis.yml
index 0b3dd195..e26ccaa4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,3 +15,5 @@ android:
- extra-google-google_play_services
licenses:
- '.+'
+script:
+ - ./gradlew assembleFreeRelease
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f847e94d..f18dab94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
###Changelog
+####Version 1.10.1
+* made message correction opt-in
+* various bug fixes
+
####Version 1.10.0
* Support for XEP-0357: Push Notifications
* Support for XEP-0308: Last Message Correction
diff --git a/README.md b/README.md
index 4bc0d7b5..98433510 100644
--- a/README.md
+++ b/README.md
@@ -149,12 +149,14 @@ a login (SASL) mechanism that Conversations is able to handle. Conversations sup
SCRAM-SHA1, PLAIN, EXTERNAL (client certs) and DIGEST-MD5.
#### How do XEP-0357: Push Notifications work?
-You need to be running the Play Store version of Conversations and your server needs to support push notifications. Because *Google Cloud Notifications (GCM)* are tied with an API key to a specific app your server can not initiate the push message directly. Instead your server will send the push notification to the Conversations App server (operated by us) which then acts as a proxy and initiates the push message for you. The push message sent from our App server through GCM doesn’t contain any personal information. It is just an empty message which will wake up your device and tell Conversations to reconnect to your server. The information send from your server to our App server depends on the configuration of your server but can be limited to your account name. (In any case the Conversations App server won't redirect any information through GCM even if your server sends this information.)
+You need to be running the Play Store version of Conversations and your server needs to support push notifications.¹ Because *Google Cloud Notifications (GCM)* are tied with an API key to a specific app your server can not initiate the push message directly. Instead your server will send the push notification to the Conversations App server (operated by us) which then acts as a proxy and initiates the push message for you. The push message sent from our App server through GCM doesn’t contain any personal information. It is just an empty message which will wake up your device and tell Conversations to reconnect to your server. The information send from your server to our App server depends on the configuration of your server but can be limited to your account name. (In any case the Conversations App server won't redirect any information through GCM even if your server sends this information.)
In summary Google will never get hold of any personal information besides that *something* happened. (Which doesn’t even have to be a message but can be some automated event as well.) We - as the operator of the App server - will just get hold of your account name (without being able to tie this to your specific device).
If you don’t want this simply pick a server which does not offer Push Notifications or build Conversations yourself without support for push notifications. (This is available via a gradle build flavor.) Non-play store source of Conversations like the Amazon App store will also offer a version without push notifications. Conversations will just work as before and maintain its own TCP connection in the background.
+ ¹ Your server only needs to support the server side of [XEP-0357: Push Notifications](http://xmpp.org/extensions/xep-0357.html). If you use the Play Store version you do **not** need to run your own app server. The server modules are called *mod_cloud_notify* on Prosody and *mod_push* on ejabberd.
+
#### Conversations doesn't work for me. Where can I get help?
You can join our conference room on `conversations@conference.siacs.eu`.
@@ -305,11 +307,13 @@ to sign up for the beta test.
#### How do I build Conversations
-Make sure to have ANDROID_HOME point to your Android SDK
+Make sure to have ANDROID_HOME point to your Android SDK. Use the Android SDK Manager to install missing dependencies.
git clone https://github.com/siacs/Conversations.git
cd Conversations
- ./gradlew build
+ ./gradlew assembleFreeRelease
+
+There are two build flavors available. *free* and *playstore*. Unless you know what you are doing you only need *free*.
[![Build Status](https://travis-ci.org/siacs/Conversations.svg?branch=development)](https://travis-ci.org/siacs/Conversations)
diff --git a/build.gradle b/build.gradle
index deaae0e2..b6ef6013 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,8 +58,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
- versionCode 127
- versionName "1.10.0"
+ versionCode 128
+ versionName "1.10.1"
archivesBaseName += "-$versionName"
applicationId "eu.siacs.conversations"
}
diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java
index 4d64c3aa..caadef80 100644
--- a/src/main/java/eu/siacs/conversations/Config.java
+++ b/src/main/java/eu/siacs/conversations/Config.java
@@ -6,13 +6,48 @@ import eu.siacs.conversations.xmpp.chatstate.ChatState;
public final class Config {
+
+ private static final int UNENCRYPTED = 1;
+ private static final int OPENPGP = 2;
+ private static final int OTR = 4;
+ private static final int OMEMO = 8;
+
+ private static final int ENCRYPTION_MASK = UNENCRYPTED | OPENPGP | OTR | OMEMO;
+
+ public static boolean supportUnencrypted() {
+ return (ENCRYPTION_MASK & UNENCRYPTED) != 0;
+ }
+
+ public static boolean supportOpenPgp() {
+ return (ENCRYPTION_MASK & OPENPGP) != 0;
+ }
+
+ public static boolean supportOpenPgpOnly() {
+ return supportOpenPgp() && !multipleEncryptionChoices();
+ }
+
+ public static boolean supportOtr() {
+ return (ENCRYPTION_MASK & OTR) != 0;
+ }
+
+ public static boolean supportOmemo() {
+ return (ENCRYPTION_MASK & OMEMO) != 0;
+ }
+
+ public static boolean multipleEncryptionChoices() {
+ return (ENCRYPTION_MASK & (ENCRYPTION_MASK - 1)) != 0;
+ }
+
public static final String LOGTAG = "conversations";
public static final String DOMAIN_LOCK = null; //only allow account creation for this domain
+ public static final String CONFERENCE_DOMAIN_LOCK = null; //only allow conference creation for this domain
+ public static final boolean LOCK_DOMAINS_IN_CONVERSATIONS = false; //only add contacts and conferences for own domains
+
+ public static final boolean SINGLE_ACCOUNT = false; //set to true to allow only one account
public static final boolean DISALLOW_REGISTRATION_IN_UI = false; //hide the register checkbox
- public static final boolean HIDE_PGP_IN_UI = false; //some more consumer focused clients might want to disable OpenPGP
- public static final boolean FORCE_E2E_ENCRYPTION = false; //disables ability to send unencrypted 1-on-1
+
public static final boolean ALLOW_NON_TLS_CONNECTIONS = false; //very dangerous. you should have a good reason to set this to true
public static final boolean FORCE_ORBOT = false; // always use TOR
public static final boolean HIDE_MESSAGE_TEXT_IN_NOTIFICATION = false;
diff --git a/src/main/java/eu/siacs/conversations/entities/Bookmark.java b/src/main/java/eu/siacs/conversations/entities/Bookmark.java
index acb4bf1a..088dfd8a 100644
--- a/src/main/java/eu/siacs/conversations/entities/Bookmark.java
+++ b/src/main/java/eu/siacs/conversations/entities/Bookmark.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -58,6 +59,18 @@ public class Bookmark extends Element implements ListItem {
}
@Override
+ public String getDisplayJid() {
+ Jid jid = getJid();
+ if (Config.LOCK_DOMAINS_IN_CONVERSATIONS && jid != null && jid.getDomainpart().equals(Config.CONFERENCE_DOMAIN_LOCK)) {
+ return jid.getLocalpart();
+ } else if (jid != null) {
+ return jid.toString();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
public Jid getJid() {
return this.getAttributeAsJid("jid");
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java
index aba9a809..691fc3e4 100644
--- a/src/main/java/eu/siacs/conversations/entities/Contact.java
+++ b/src/main/java/eu/siacs/conversations/entities/Contact.java
@@ -45,7 +45,7 @@ public class Contact implements ListItem, Blockable {
protected String photoUri;
protected JSONObject keys = new JSONObject();
protected JSONArray groups = new JSONArray();
- protected Presences presences = new Presences();
+ protected final Presences presences = new Presences();
protected Account account;
protected Avatar avatar;
@@ -121,6 +121,17 @@ public class Contact implements ListItem, Blockable {
}
}
+ @Override
+ public String getDisplayJid() {
+ if (Config.LOCK_DOMAINS_IN_CONVERSATIONS && jid != null && jid.getDomainpart().equals(Config.DOMAIN_LOCK)) {
+ return jid.getLocalpart();
+ } else if (jid != null) {
+ return jid.toString();
+ } else {
+ return null;
+ }
+ }
+
public String getProfilePhoto() {
return this.photoUri;
}
@@ -222,10 +233,6 @@ public class Contact implements ListItem, Blockable {
return this.presences;
}
- public void setPresences(Presences pres) {
- this.presences = pres;
- }
-
public void updatePresence(final String resource, final Presence presence) {
this.presences.updatePresence(resource, presence);
}
@@ -386,11 +393,13 @@ public class Contact implements ListItem, Blockable {
this.resetOption(Options.TO);
this.setOption(Options.FROM);
this.resetOption(Options.PREEMPTIVE_GRANT);
+ this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
break;
case "both":
this.setOption(Options.TO);
this.setOption(Options.FROM);
this.resetOption(Options.PREEMPTIVE_GRANT);
+ this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
break;
case "none":
this.resetOption(Options.FROM);
diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java
index a179d96b..796b36f9 100644
--- a/src/main/java/eu/siacs/conversations/entities/Conversation.java
+++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java
@@ -673,11 +673,15 @@ public class Conversation extends AbstractEntity implements Blockable {
next = outgoing;
}
}
- if (Config.FORCE_E2E_ENCRYPTION && mode == MODE_SINGLE && next <= 0) {
- if (axolotlService != null && axolotlService.isContactAxolotlCapable(getContact())) {
+ if (!Config.supportUnencrypted()
+ && (mode == MODE_SINGLE || Config.supportOpenPgpOnly())
+ && next <= 0) {
+ if (Config.supportOmemo() && (axolotlService != null && axolotlService.isContactAxolotlCapable(getContact()) || !Config.multipleEncryptionChoices())) {
return Message.ENCRYPTION_AXOLOTL;
- } else {
+ } else if (Config.supportOtr()) {
return Message.ENCRYPTION_OTR;
+ } else if (Config.supportOpenPgp()) {
+ return Message.ENCRYPTION_PGP;
}
}
return next;
diff --git a/src/main/java/eu/siacs/conversations/entities/ListItem.java b/src/main/java/eu/siacs/conversations/entities/ListItem.java
index efc1c2b9..22aedd4b 100644
--- a/src/main/java/eu/siacs/conversations/entities/ListItem.java
+++ b/src/main/java/eu/siacs/conversations/entities/ListItem.java
@@ -5,13 +5,15 @@ import java.util.List;
import eu.siacs.conversations.xmpp.jid.Jid;
public interface ListItem extends Comparable<ListItem> {
- public String getDisplayName();
+ String getDisplayName();
- public Jid getJid();
+ String getDisplayJid();
- public List<Tag> getTags();
+ Jid getJid();
- public final class Tag {
+ List<Tag> getTags();
+
+ final class Tag {
private final String name;
private final int color;
@@ -29,5 +31,5 @@ public interface ListItem extends Comparable<ListItem> {
}
}
- public boolean match(final String needle);
+ boolean match(final String needle);
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java
index 63db9a44..3dfbd787 100644
--- a/src/main/java/eu/siacs/conversations/entities/Message.java
+++ b/src/main/java/eu/siacs/conversations/entities/Message.java
@@ -449,6 +449,7 @@ public class Message extends AbstractEntity {
this.getTransferable() == null &&
message.getTransferable() == null &&
message.getEncryption() != Message.ENCRYPTION_PGP &&
+ message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED &&
this.getType() == message.getType() &&
//this.getStatus() == message.getStatus() &&
isStatusMergeable(this.getStatus(), message.getStatus()) &&
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index f01e7ce1..aa9d7f6c 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -3,7 +3,6 @@ package eu.siacs.conversations.parser;
import android.util.Log;
import android.util.Pair;
-import eu.siacs.conversations.crypto.PgpDecryptionService;
import net.java.otr4j.session.Session;
import net.java.otr4j.session.SessionStatus;
@@ -345,7 +344,7 @@ public class MessageParser extends AbstractParser implements
}
}
Message message;
- if (body != null && body.startsWith("?OTR")) {
+ if (body != null && body.startsWith("?OTR") && Config.supportOtr()) {
if (!isForwarded && !isTypeGroupChat && isProperlyAddressed) {
message = parseOtrChat(body, from, remoteMsgId, conversation);
if (message == null) {
@@ -355,9 +354,9 @@ public class MessageParser extends AbstractParser implements
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": ignoring OTR message from "+from+" isForwarded="+Boolean.toString(isForwarded)+", isProperlyAddressed="+Boolean.valueOf(isProperlyAddressed));
message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
}
- } else if (pgpEncrypted != null) {
+ } else if (pgpEncrypted != null && Config.supportOpenPgp()) {
message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status);
- } else if (axolotlEncrypted != null) {
+ } else if (axolotlEncrypted != null && Config.supportOmemo()) {
message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation, status);
if (message == null) {
return;
@@ -411,6 +410,7 @@ public class MessageParser extends AbstractParser implements
replacedMessage.markUnread();
}
mXmppConnectionService.updateMessage(replacedMessage, uuid);
+ mXmppConnectionService.getNotificationService().updateNotification(false);
if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) {
sendMessageReceipts(account, packet);
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 24a728f7..dde8ad28 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -262,7 +262,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (mPushManagementService.available(account)) {
mPushManagementService.registerPushTokenOnServer(account);
}
- mMessageArchiveService.executePendingQueries(account);
connectMultiModeConversations(account);
syncDirtyContacts(account);
}
@@ -276,6 +275,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
mOnAccountUpdate.onAccountUpdate();
}
if (account.getStatus() == Account.State.ONLINE) {
+ mMessageArchiveService.executePendingQueries(account);
if (connection != null && connection.getFeatures().csi()) {
if (checkListeners()) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + " sending csi//inactive");
@@ -351,7 +351,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public PgpEngine getPgpEngine() {
- if (pgpServiceConnection != null && pgpServiceConnection.isBound()) {
+ if (!Config.supportOpenPgp()) {
+ return null;
+ } else if (pgpServiceConnection != null && pgpServiceConnection.isBound()) {
if (this.mPgpEngine == null) {
this.mPgpEngine = new PgpEngine(new OpenPgpApi(
getApplicationContext(),
@@ -689,20 +691,23 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
this.fileObserver.startWatching();
- this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() {
- @Override
- public void onBound(IOpenPgpService2 service) {
- for (Account account : accounts) {
- if (account.getPgpDecryptionService() != null) {
- account.getPgpDecryptionService().onOpenPgpServiceBound();
+ if (Config.supportOpenPgp()) {
+ this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() {
+ @Override
+ public void onBound(IOpenPgpService2 service) {
+ for (Account account : accounts) {
+ if (account.getPgpDecryptionService() != null) {
+ account.getPgpDecryptionService().onOpenPgpServiceBound();
+ }
}
}
- }
- @Override
- public void onError(Exception e) { }
- });
- this.pgpServiceConnection.bindToService();
+ @Override
+ public void onError(Exception e) {
+ }
+ });
+ this.pgpServiceConnection.bindToService();
+ }
this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "XmppConnectionService");
@@ -1772,6 +1777,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.State.ONLINE) {
conversation.resetMucOptions();
+ conversation.setHasMessagesLeftOnServer(false);
fetchConferenceConfiguration(conversation, new OnConferenceConfigurationFetched() {
private void join(Conversation conversation) {
@@ -1806,7 +1812,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
conversation.setContactJid(joinJid);
databaseBackend.updateConversation(conversation);
}
- conversation.setHasMessagesLeftOnServer(false);
if (conversation.getMucOptions().mamSupport()) {
getMessageArchiveService().catchupMUC(conversation);
}
@@ -1828,6 +1833,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} else {
account.pendingConferenceJoins.add(conversation);
conversation.resetMucOptions();
+ conversation.setHasMessagesLeftOnServer(false);
updateConversationUi();
}
}
@@ -2623,7 +2629,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public boolean allowMessageCorrection() {
- return getPreferences().getBoolean("allow_message_correction", true);
+ return getPreferences().getBoolean("allow_message_correction", false);
}
public boolean sendChatStates() {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
index be454936..a83ca8ba 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
@@ -6,7 +6,6 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentSender.SendIntentException;
-import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.view.ContextMenu;
@@ -512,7 +511,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
mAccountJid.setText(getString(R.string.using_account, account));
mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48)));
setTitle(mConversation.getName());
- mFullJid.setText(mConversation.getJid().toBareJid().toString());
+ if (Config.LOCK_DOMAINS_IN_CONVERSATIONS && mConversation.getJid().getDomainpart().equals(Config.CONFERENCE_DOMAIN_LOCK)) {
+ mFullJid.setText(mConversation.getJid().getLocalpart());
+ } else {
+ mFullJid.setText(mConversation.getJid().toBareJid().toString());
+ }
mYourNick.setText(mucOptions.getActualNick());
mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
if (mucOptions.online()) {
diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
index f8d1c97f..64653acd 100644
--- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java
@@ -14,7 +14,6 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -140,7 +139,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
ContactDetailsActivity.this);
builder.setTitle(getString(R.string.action_add_phone_book));
builder.setMessage(getString(R.string.add_phone_book_text,
- contact.getJid()));
+ contact.getDisplayJid()));
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.add), addToPhonebook);
builder.create().show();
@@ -237,7 +236,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
builder.setTitle(getString(R.string.action_delete_contact))
.setMessage(
getString(R.string.remove_contact_text,
- contact.getJid()))
+ contact.getDisplayJid()))
.setPositiveButton(getString(R.string.delete),
removeFromRoster).create().show();
break;
@@ -359,10 +358,10 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
}
if (contact.getPresences().size() > 1) {
- contactJidTv.setText(contact.getJid() + " ("
+ contactJidTv.setText(contact.getDisplayJid() + " ("
+ contact.getPresences().size() + ")");
} else {
- contactJidTv.setText(contact.getJid().toString());
+ contactJidTv.setText(contact.getDisplayJid());
}
String account;
if (Config.DOMAIN_LOCK != null) {
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 11e2e889..7b2565c3 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -408,9 +408,10 @@ public class ConversationActivity extends XmppActivity
menuContactDetails.setVisible(false);
menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating());
menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite());
- menuSecure.setVisible(!Config.HIDE_PGP_IN_UI && !Config.X509_VERIFICATION); //if pgp is hidden conferences have no choice of encryption
+ menuSecure.setVisible(Config.supportOpenPgp() && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice
} else {
menuMucDetails.setVisible(false);
+ menuSecure.setVisible(Config.multipleEncryptionChoices());
}
if (this.getSelectedConversation().isMuted()) {
menuMute.setVisible(false);
@@ -849,9 +850,10 @@ public class ConversationActivity extends XmppActivity
MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none);
MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp);
MenuItem axolotl = popup.getMenu().findItem(R.id.encryption_choice_axolotl);
- pgp.setVisible(!Config.HIDE_PGP_IN_UI && !Config.X509_VERIFICATION);
- none.setVisible(!Config.FORCE_E2E_ENCRYPTION || conversation.getMode() == Conversation.MODE_MULTI);
- otr.setVisible(!Config.X509_VERIFICATION);
+ pgp.setVisible(Config.supportOpenPgp());
+ none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
+ otr.setVisible(Config.supportOtr());
+ axolotl.setVisible(Config.supportOmemo());
if (conversation.getMode() == Conversation.MODE_MULTI) {
otr.setVisible(false);
axolotl.setVisible(false);
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index d5c77490..15e4b985 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -523,6 +523,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
activity.getMenuInflater().inflate(R.menu.message_context, menu);
menu.setHeaderTitle(R.string.message_options);
MenuItem copyText = menu.findItem(R.id.copy_text);
+ MenuItem retryDecryption = menu.findItem(R.id.retry_decryption);
MenuItem correctMessage = menu.findItem(R.id.correct_message);
MenuItem shareWith = menu.findItem(R.id.share_with);
MenuItem sendAgain = menu.findItem(R.id.send_again);
@@ -535,6 +536,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
&& m.treatAsDownloadable() != Message.Decision.MUST) {
copyText.setVisible(true);
}
+ if (m.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
+ retryDecryption.setVisible(true);
+ }
if (relevantForCorrection.getType() == Message.TYPE_TEXT
&& relevantForCorrection.isLastCorrectableMessage()) {
correctMessage.setVisible(true);
@@ -590,6 +594,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
case R.id.cancel_transmission:
cancelTransmission(selectedMessage);
return true;
+ case R.id.retry_decryption:
+ retryDecryption(selectedMessage);
+ return true;
default:
return super.onContextItemSelected(item);
}
@@ -673,6 +680,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
+ private void retryDecryption(Message message) {
+ message.setEncryption(Message.ENCRYPTION_PGP);
+ activity.xmppConnectionService.updateConversationUi();
+ conversation.getAccount().getPgpDecryptionService().add(message);
+ }
+
protected void privateMessageWith(final Jid counterpart) {
this.mEditMessage.setText("");
this.conversation.setNextCounterpart(counterpart);
diff --git a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java
index bb55420d..a6b3c73c 100644
--- a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java
+++ b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java
@@ -2,13 +2,12 @@ package eu.siacs.conversations.ui;
import android.app.AlertDialog;
import android.content.Context;
-import android.content.DialogInterface.OnClickListener;
-import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Spinner;
+import android.widget.TextView;
import java.util.List;
@@ -44,12 +43,17 @@ public class EnterJidDialog {
final String title, final String positiveButton,
final String prefilledJid, final String account, boolean allowEditJid
) {
+ final boolean lock = Config.LOCK_DOMAINS_IN_CONVERSATIONS && Config.DOMAIN_LOCK != null;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
View dialogView = LayoutInflater.from(context).inflate(R.layout.enter_jid_dialog, null);
+ final TextView jabberIdDesc = (TextView) dialogView.findViewById(R.id.jabber_id);
+ jabberIdDesc.setText(lock ? R.string.username : R.string.account_settings_jabber_id);
final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView.findViewById(R.id.jid);
- jid.setAdapter(new KnownHostsAdapter(context,android.R.layout.simple_list_item_1, knownHosts));
+ if (!lock) {
+ jid.setAdapter(new KnownHostsAdapter(context, android.R.layout.simple_list_item_1, knownHosts));
+ }
if (prefilledJid != null) {
jid.append(prefilledJid);
if (!allowEditJid) {
@@ -60,6 +64,7 @@ public class EnterJidDialog {
}
}
+ jid.setHint(Config.LOCK_DOMAINS_IN_CONVERSATIONS && Config.DOMAIN_LOCK != null ? R.string.username_hint : R.string.account_settings_example_jabber_id);
if (account == null) {
StartConversationActivity.populateAccountSpinner(context, activatedAccounts, spinner);
@@ -95,9 +100,13 @@ public class EnterJidDialog {
}
final Jid contactJid;
try {
- contactJid = Jid.fromString(jid.getText().toString());
+ if (lock) {
+ contactJid = Jid.fromParts(jid.getText().toString(), Config.DOMAIN_LOCK, null);
+ } else {
+ contactJid = Jid.fromString(jid.getText().toString());
+ }
} catch (final InvalidJidException e) {
- jid.setError(context.getString(R.string.invalid_jid));
+ jid.setError(context.getString(lock ? R.string.invalid_username : R.string.invalid_jid));
return;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
index f2511ecb..1fc1924d 100644
--- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java
@@ -123,7 +123,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false);
} else {
menu.findItem(R.id.mgmt_account_enable).setVisible(false);
- menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(!Config.HIDE_PGP_IN_UI);
+ menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(Config.supportOpenPgp());
}
menu.setHeaderTitle(this.selectedAccount.getJid().toBareJid().toString());
}
@@ -154,7 +154,10 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
if (Config.X509_VERIFICATION) {
addAccount.setVisible(false);
addAccountWithCertificate.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ } else {
+ addAccount.setVisible(!Config.SINGLE_ACCOUNT);
}
+ addAccountWithCertificate.setVisible(!Config.SINGLE_ACCOUNT);
if (!accountsLeftToEnable()) {
enableAll.setVisible(false);
diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
index 8b3b4607..48baf914 100644
--- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
@@ -44,6 +44,7 @@ import android.widget.Checkable;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
+import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
@@ -64,7 +65,6 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.entities.Presence;
-import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
@@ -390,7 +390,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
final View dialogView = getLayoutInflater().inflate(R.layout.join_conference_dialog, null);
final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView.findViewById(R.id.jid);
- jid.setAdapter(new KnownHostsAdapter(this, android.R.layout.simple_list_item_1, mKnownConferenceHosts));
+ final boolean lock = Config.LOCK_DOMAINS_IN_CONVERSATIONS && Config.CONFERENCE_DOMAIN_LOCK != null;
+ final TextView jabberIdDesc = (TextView) dialogView.findViewById(R.id.jabber_id);
+ jabberIdDesc.setText(lock ? R.string.conference_name : R.string.conference_address);
+ jid.setHint(lock ? R.string.conference_name : R.string.conference_address_example);
+ if (!lock) {
+ jid.setAdapter(new KnownHostsAdapter(this, android.R.layout.simple_list_item_1, mKnownConferenceHosts));
+ }
if (prefilledJid != null) {
jid.append(prefilledJid);
}
@@ -416,9 +422,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
final Jid conferenceJid;
try {
- conferenceJid = Jid.fromString(jid.getText().toString());
+ if (lock) {
+ conferenceJid = Jid.fromParts(jid.getText().toString(),Config.CONFERENCE_DOMAIN_LOCK, null);
+ } else {
+ conferenceJid = Jid.fromString(jid.getText().toString());
+ }
} catch (final InvalidJidException e) {
- jid.setError(getString(R.string.invalid_jid));
+ jid.setError(getString(lock ? R.string.invalid_conference_name : R.string.invalid_jid));
return;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
index 47414f90..da8e3910 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
@@ -76,10 +76,10 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
tagLayout.addView(tv);
}
}
- final Jid jid = item.getJid();
+ final String jid = item.getDisplayJid();
if (jid != null) {
tvJid.setVisibility(View.VISIBLE);
- tvJid.setText(jid.toString());
+ tvJid.setText(jid);
} else {
tvJid.setVisibility(View.GONE);
}
diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
index cf1e0d3b..5e8af085 100644
--- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
@@ -171,7 +171,9 @@ public class UIHelper {
return new Pair<>("",false);
}
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
- return new Pair<>(context.getString(R.string.encrypted_message_received),true);
+ return new Pair<>(context.getString(R.string.pgp_message),true);
+ } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
+ return new Pair<>(context.getString(R.string.decryption_failed), true);
} else if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) {
if (message.getStatus() == Message.STATUS_RECEIVED) {
return new Pair<>(context.getString(R.string.received_x_file,
diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml
index 0d4e66ef..4096297c 100644
--- a/src/main/res/menu/message_context.xml
+++ b/src/main/res/menu/message_context.xml
@@ -6,6 +6,10 @@
android:title="@string/copy_text"
android:visible="false"/>
<item
+ android:id="@+id/retry_decryption"
+ android:title="Retry decryption"
+ android:visible="false"/>
+ <item
android:id="@+id/correct_message"
android:title="@string/correct_message"
android:visible="false"/>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 48c3de6c..a25c1a84 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -97,7 +97,6 @@
<string name="contact_has_no_pgp_key">Conversations is unable to encrypt your messages because your contact is not announcing his or hers public key.\n\n<small>Please ask your contact to setup OpenPGP.</small></string>
<string name="no_pgp_keys">No OpenPGP Keys found</string>
<string name="contacts_have_no_pgp_keys">Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\n<small>Please ask your contacts to setup OpenPGP.</small></string>
- <string name="encrypted_message_received"><i>Encrypted message received. Touch to decrypt.</i></string>
<string name="pref_general">General</string>
<string name="pref_xmpp_resource">XMPP resource</string>
<string name="pref_xmpp_resource_summary">The name this client identifies itself with</string>
@@ -523,6 +522,8 @@
<string name="username">Username</string>
<string name="username_hint">Username</string>
<string name="invalid_username">This is not a valid username</string>
+ <string name="conference_name">Conference name</string>
+ <string name="invalid_conference_name">This is not a valid conference name</string>
<string name="download_failed_server_not_found">Download failed: Server not found</string>
<string name="download_failed_file_not_found">Download failed: File not found</string>
<string name="download_failed_could_not_connect">Download failed: Could not connect to host</string>
diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml
index e8747a8b..35799573 100644
--- a/src/main/res/xml/preferences.xml
+++ b/src/main/res/xml/preferences.xml
@@ -147,7 +147,7 @@
android:summary="@string/pref_remove_trusted_certificates_summary"
android:title="@string/pref_remove_trusted_certificates_title"/>
<CheckBoxPreference
- android:defaultValue="true"
+ android:defaultValue="false"
android:key="allow_message_correction"
android:title="@string/pref_allow_message_correction"
android:summary="@string/pref_allow_message_correction_summary"/>