settings to force encryption and setting for not saving messages to disk. fixed #353

iNPUTmice created

Change summary

res/values/strings.xml                                         |  5 
res/xml/preferences.xml                                        | 13 
src/eu/siacs/conversations/entities/Conversation.java          | 29 +
src/eu/siacs/conversations/parser/MessageParser.java           |  4 
src/eu/siacs/conversations/services/XmppConnectionService.java | 20 +
src/eu/siacs/conversations/ui/ConversationActivity.java        | 63 ++-
src/eu/siacs/conversations/ui/ConversationFragment.java        |  8 
7 files changed, 96 insertions(+), 46 deletions(-)

Detailed changes

res/values/strings.xml πŸ”—

@@ -245,5 +245,10 @@
     <string name="sure_delete_fingerprint">Are you sure you would like to delete this fingerprint?</string>
     <string name="ignore">Ignore</string>
     <string name="without_mutual_presence_updates"><b>Warning:</b> Sending this without mutual presence updates could cause unexpected problems.\n\n<small>Go to contact details to verify your presence subscriptions.</small></string>
+    <string name="pref_encryption_settings">Encryption settings</string>
+    <string name="pref_force_encryption">Force end-to-end encryption</string>
+    <string name="pref_force_encryption_summary">Always send messages encrypted (execpt for conferences)</string>
+    <string name="pref_dont_save_encrypted">Don’t save encrypted messages</string>
+    <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
 
 </resources>

res/xml/preferences.xml πŸ”—

@@ -60,6 +60,19 @@
             android:summary="@string/pref_notification_grace_period_summary"
             android:defaultValue="true"/>
     </PreferenceCategory>
+    <PreferenceCategory 
+        android:title="@string/pref_encryption_settings">
+        <CheckBoxPreference 
+            android:key="force_encryption"
+            android:title="@string/pref_force_encryption"
+            android:summary="@string/pref_force_encryption_summary"
+            android:defaultValue="false"/>
+        <CheckBoxPreference 
+            android:key="dont_save_encrypted"
+            android:title="@string/pref_dont_save_encrypted"
+            android:summary="@string/pref_dont_save_encrypted_summary"
+            android:defaultValue="false"/>
+    </PreferenceCategory>
     <PreferenceCategory
         android:title="@string/pref_advanced_options">
         <CheckBoxPreference 

src/eu/siacs/conversations/entities/Conversation.java πŸ”—

@@ -339,24 +339,29 @@ public class Conversation extends AbstractEntity {
 		if ((latestEncryption == Message.ENCRYPTION_DECRYPTED)
 				|| (latestEncryption == Message.ENCRYPTION_DECRYPTION_FAILED)) {
 			return Message.ENCRYPTION_PGP;
-		} else if (latestEncryption == Message.ENCRYPTION_NONE) {
-			if (getContact().getPresences().size() == 1) {
-				if (getContact().getOtrFingerprints().size() >= 1) {
-					return Message.ENCRYPTION_OTR;
-				} else {
-					return latestEncryption;
-				}
-			} else {
-				return latestEncryption;
-			}
 		} else {
 			return latestEncryption;
 		}
 	}
 
-	public int getNextEncryption() {
+	public int getNextEncryption(boolean force) {
 		if (this.nextMessageEncryption == -1) {
-			return this.getLatestEncryption();
+			int latest = this.getLatestEncryption();
+			if (latest == Message.ENCRYPTION_NONE) {
+				if (force && getMode() == MODE_SINGLE) {
+					return Message.ENCRYPTION_OTR;
+				} else if (getContact().getPresences().size() == 1) {
+					if (getContact().getOtrFingerprints().size() >= 1) {
+						return Message.ENCRYPTION_OTR;
+					} else {
+						return latest;
+					}
+				} else {
+					return latest;
+				}
+			} else {
+				return latest;
+			}
 		}
 		return this.nextMessageEncryption;
 	}

src/eu/siacs/conversations/parser/MessageParser.java πŸ”—

@@ -453,7 +453,9 @@ public class MessageParser extends AbstractParser implements
 		Conversation conversation = message.getConversation();
 		conversation.getMessages().add(message);
 		if (packet.getType() != MessagePacket.TYPE_ERROR) {
-			mXmppConnectionService.databaseBackend.createMessage(message);
+			if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) {
+				mXmppConnectionService.databaseBackend.createMessage(message);
+			}
 		}
 		notify = notify && !conversation.isMuted();
 		mXmppConnectionService.notifyUi(conversation, notify);

src/eu/siacs/conversations/services/XmppConnectionService.java πŸ”—

@@ -270,12 +270,12 @@ public class XmppConnectionService extends Service {
 	public Message attachImageToConversation(final Conversation conversation,
 			final Uri uri, final UiCallback<Message> callback) {
 		final Message message;
-		if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
+		if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
 			message = new Message(conversation, "",
 					Message.ENCRYPTION_DECRYPTED);
 		} else {
 			message = new Message(conversation, "",
-					conversation.getNextEncryption());
+					conversation.getNextEncryption(forceEncryption()));
 		}
 		message.setPresence(conversation.getNextPresence());
 		message.setType(Message.TYPE_IMAGE);
@@ -286,7 +286,7 @@ public class XmppConnectionService extends Service {
 			public void run() {
 				try {
 					getFileBackend().copyImageToPrivateStorage(message, uri);
-					if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
+					if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
 						getPgpEngine().encrypt(message, callback);
 					} else {
 						callback.success(message);
@@ -567,9 +567,11 @@ public class XmppConnectionService extends Service {
 					String pgpBody = message.getEncryptedBody();
 					String decryptedBody = message.getBody();
 					message.setBody(pgpBody);
+					message.setEncryption(Message.ENCRYPTION_PGP);
 					databaseBackend.createMessage(message);
 					saveInDb = false;
 					message.setBody(decryptedBody);
+					message.setEncryption(Message.ENCRYPTION_DECRYPTED);
 				} else if (message.getEncryption() == Message.ENCRYPTION_OTR) {
 					if (conv.hasValidOtrSession()) {
 						message.setPresence(conv.getOtrSession().getSessionID()
@@ -583,7 +585,9 @@ public class XmppConnectionService extends Service {
 
 		}
 		if (saveInDb) {
-			databaseBackend.createMessage(message);
+			if (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages()) {
+				databaseBackend.createMessage(message);
+			}
 		}
 		conv.getMessages().add(message);
 		if ((send) && (packet != null)) {
@@ -1542,10 +1546,18 @@ public class XmppConnectionService extends Service {
 		return PreferenceManager
 				.getDefaultSharedPreferences(getApplicationContext());
 	}
+	
+	public boolean forceEncryption() {
+		return getPreferences().getBoolean("force_encryption", false);
+	}
 
 	public boolean confirmMessages() {
 		return getPreferences().getBoolean("confirm_messages", true);
 	}
+	
+	public boolean saveEncryptedMessages() {
+		return !getPreferences().getBoolean("dont_save_encrypted", false);
+	}
 
 	public void notifyUi(Conversation conversation, boolean notify) {
 		if (mOnConversationUpdate != null) {

src/eu/siacs/conversations/ui/ConversationActivity.java πŸ”—

@@ -14,6 +14,7 @@ import eu.siacs.conversations.utils.UIHelper;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.preference.PreferenceManager;
 import android.provider.MediaStore;
 import android.app.ActionBar;
 import android.app.AlertDialog;
@@ -279,7 +280,7 @@ public class ConversationActivity extends XmppActivity {
 
 	private void attachFile(final int attachmentChoice) {
 		final Conversation conversation = getSelectedConversation();
-		if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
+		if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
 			if (hasPgp()) {
 				if (conversation.getContact().getPgpKeyId() != 0) {
 					xmppConnectionService.getPgpEngine().hasKey(
@@ -323,7 +324,7 @@ public class ConversationActivity extends XmppActivity {
 			} else {
 				showInstallPgpDialog();
 			}
-		} else if (getSelectedConversation().getNextEncryption() == Message.ENCRYPTION_NONE) {
+		} else if (getSelectedConversation().getNextEncryption(forceEncryption()) == Message.ENCRYPTION_NONE) {
 			selectPresenceToAttachFile(attachmentChoice);
 		} else {
 			selectPresenceToAttachFile(attachmentChoice);
@@ -439,13 +440,17 @@ public class ConversationActivity extends XmppActivity {
 				popup.inflate(R.menu.encryption_choices);
 				MenuItem otr = popup.getMenu().findItem(
 						R.id.encryption_choice_otr);
+				MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none);
 				if (conversation.getMode() == Conversation.MODE_MULTI) {
 					otr.setEnabled(false);
+				} else {
+					if (forceEncryption()) {
+						none.setVisible(false);
+					}
 				}
-				switch (conversation.getNextEncryption()) {
+				switch (conversation.getNextEncryption(forceEncryption())) {
 				case Message.ENCRYPTION_NONE:
-					popup.getMenu().findItem(R.id.encryption_choice_none)
-							.setChecked(true);
+					none.setChecked(true);
 					break;
 				case Message.ENCRYPTION_OTR:
 					otr.setChecked(true);
@@ -510,29 +515,32 @@ public class ConversationActivity extends XmppActivity {
 				});
 		builder.create().show();
 	}
-	
+
 	protected void muteConversationDialog(final Conversation conversation) {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
 		builder.setTitle(R.string.disable_notifications_for_this_conversation);
-		final int[] durations = getResources().getIntArray(R.array.mute_options_durations);
-		builder.setItems(R.array.mute_options_descriptions, new OnClickListener() {
-			
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				long till;
-				if (durations[which]==-1) {
-					till = Long.MAX_VALUE;
-				} else {
-					till = SystemClock.elapsedRealtime() + (durations[which] * 1000);
-				}
-				conversation.setMutedTill(till);
-				ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
-						.findFragmentByTag("conversation");
-				if (selectedFragment!=null) {
-					selectedFragment.updateMessages();
-				}
-			}
-		});
+		final int[] durations = getResources().getIntArray(
+				R.array.mute_options_durations);
+		builder.setItems(R.array.mute_options_descriptions,
+				new OnClickListener() {
+
+					@Override
+					public void onClick(DialogInterface dialog, int which) {
+						long till;
+						if (durations[which] == -1) {
+							till = Long.MAX_VALUE;
+						} else {
+							till = SystemClock.elapsedRealtime()
+									+ (durations[which] * 1000);
+						}
+						conversation.setMutedTill(till);
+						ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
+								.findFragmentByTag("conversation");
+						if (selectedFragment != null) {
+							selectedFragment.updateMessages();
+						}
+					}
+				});
 		builder.create().show();
 	}
 
@@ -794,4 +802,9 @@ public class ConversationActivity extends XmppActivity {
 					}
 				});
 	}
+
+	public boolean forceEncryption() {
+		return PreferenceManager.getDefaultSharedPreferences(
+				getApplicationContext()).getBoolean("force_encryption", false);
+	}
 }

src/eu/siacs/conversations/ui/ConversationFragment.java πŸ”—

@@ -188,7 +188,7 @@ public class ConversationFragment extends Fragment {
 			return;
 		}
 		Message message = new Message(conversation, mEditMessage.getText()
-				.toString(), conversation.getNextEncryption());
+				.toString(), conversation.getNextEncryption(activity.forceEncryption()));
 		if (conversation.getMode() == Conversation.MODE_MULTI) {
 			if (conversation.getNextPresence() != null) {
 				message.setPresence(conversation.getNextPresence());
@@ -196,9 +196,9 @@ public class ConversationFragment extends Fragment {
 				conversation.setNextPresence(null);
 			}
 		}
-		if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) {
+		if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) {
 			sendOtrMessage(message);
-		} else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
+		} else if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_PGP) {
 			sendPgpMessage(message);
 		} else {
 			sendPlainTextMessage(message);
@@ -212,7 +212,7 @@ public class ConversationFragment extends Fragment {
 					R.string.send_private_message_to,
 					conversation.getNextPresence()));
 		} else {
-			switch (conversation.getNextEncryption()) {
+			switch (conversation.getNextEncryption(activity.forceEncryption())) {
 			case Message.ENCRYPTION_NONE:
 				mEditMessage
 						.setHint(getString(R.string.send_plain_text_message));