From 3c4ac4b10505c5c54eb435b974b4febb24325749 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Thu, 11 Dec 2014 16:10:11 -0800 Subject: [PATCH] Add option that allows disabling MMS fallback with TS users. // FREEBIE Closes #1444 --- res/layout/outgoing_sms_preference.xml | 11 ++++++++++- res/values/strings.xml | 5 +++-- res/xml/preferences_advanced.xml | 5 +++++ res/xml/preferences_sms_mms.xml | 7 +------ .../components/OutgoingSmsPreference.java | 12 +++++++++--- .../securesms/jobs/PushMediaSendJob.java | 6 +++--- .../thoughtcrime/securesms/jobs/PushSendJob.java | 14 +++++++++----- .../securesms/jobs/PushTextSendJob.java | 6 +++--- .../securesms/util/TextSecurePreferences.java | 11 +++++++++-- 9 files changed, 52 insertions(+), 25 deletions(-) diff --git a/res/layout/outgoing_sms_preference.xml b/res/layout/outgoing_sms_preference.xml index e5b8b3225e..34c0f2e609 100644 --- a/res/layout/outgoing_sms_preference.xml +++ b/res/layout/outgoing_sms_preference.xml @@ -31,9 +31,18 @@ android:layout_height="wrap_content" android:textSize="14sp" android:checkMark="?android:attr/listChoiceIndicatorMultiple" - android:text="@string/preferences__sms_fallback_ask_fallback" + android:text="@string/preferences__sms_fallback_ask_before_sending_sms_mms" android:layout_marginLeft="25dp" /> + + Increase privacy and avoid SMS fees by using the data channel for communication with other TextSecure users - Allow outgoing SMS to + Outgoing SMS/MMS Submit debug log TextSecure users (ask first) Send secure SMS if data connectivity is lost - Ask before sending SMS + Ask before sending SMS/MMS + Never send MMS Non-TextSecure users Nobody diff --git a/res/xml/preferences_advanced.xml b/res/xml/preferences_advanced.xml index f324b05504..167a8a8f2e 100644 --- a/res/xml/preferences_advanced.xml +++ b/res/xml/preferences_advanced.xml @@ -16,6 +16,11 @@ android:title="@string/preferences__choose_identity" android:summary="@string/preferences__choose_your_contact_entry_from_the_contacts_list"/> + + diff --git a/res/xml/preferences_sms_mms.xml b/res/xml/preferences_sms_mms.xml index 1f1b5be3c9..c785fb1461 100644 --- a/res/xml/preferences_sms_mms.xml +++ b/res/xml/preferences_sms_mms.xml @@ -17,7 +17,7 @@ + android:title="@string/preferences__sms_fallback" /> - - \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/components/OutgoingSmsPreference.java b/src/org/thoughtcrime/securesms/components/OutgoingSmsPreference.java index 946b8608b1..f21cfca785 100644 --- a/src/org/thoughtcrime/securesms/components/OutgoingSmsPreference.java +++ b/src/org/thoughtcrime/securesms/components/OutgoingSmsPreference.java @@ -12,7 +12,10 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; public class OutgoingSmsPreference extends DialogPreference { private CheckBox dataUsers; private CheckBox askForFallback; + private CheckBox neverFallbackMms; private CheckBox nonDataUsers; + + public OutgoingSmsPreference(Context context, AttributeSet attrs) { super(context, attrs); setPersistent(false); @@ -22,12 +25,14 @@ public class OutgoingSmsPreference extends DialogPreference { @Override protected void onBindDialogView(final View view) { super.onBindDialogView(view); - dataUsers = (CheckBox) view.findViewById(R.id.data_users); - askForFallback = (CheckBox) view.findViewById(R.id.ask_before_fallback_data); - nonDataUsers = (CheckBox) view.findViewById(R.id.non_data_users); + dataUsers = (CheckBox) view.findViewById(R.id.data_users); + askForFallback = (CheckBox) view.findViewById(R.id.ask_before_fallback_data); + neverFallbackMms = (CheckBox) view.findViewById(R.id.never_send_mms); + nonDataUsers = (CheckBox) view.findViewById(R.id.non_data_users); dataUsers.setChecked(TextSecurePreferences.isFallbackSmsAllowed(getContext())); askForFallback.setChecked(TextSecurePreferences.isFallbackSmsAskRequired(getContext())); + neverFallbackMms.setChecked(!TextSecurePreferences.isFallbackMmsEnabled(getContext())); nonDataUsers.setChecked(TextSecurePreferences.isDirectSmsAllowed(getContext())); dataUsers.setOnClickListener(new View.OnClickListener() { @@ -48,6 +53,7 @@ public class OutgoingSmsPreference extends DialogPreference { TextSecurePreferences.setFallbackSmsAllowed(getContext(), dataUsers.isChecked()); TextSecurePreferences.setFallbackSmsAskRequired(getContext(), askForFallback.isChecked()); TextSecurePreferences.setDirectSmsAllowed(getContext(), nonDataUsers.isChecked()); + TextSecurePreferences.setFallbackMmsEnabled(getContext(), !neverFallbackMms.isChecked()); if (getOnPreferenceChangeListener() != null) getOnPreferenceChangeListener().onPreferenceChange(this, null); } } diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index cf436269b9..a9dfd4b7fe 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -47,7 +47,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { private final long messageId; public PushMediaSendJob(Context context, long messageId, String destination) { - super(context, constructParameters(context, destination)); + super(context, constructParameters(context, destination, true)); this.messageId = messageId; } @@ -104,7 +104,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { MmsDatabase database = DatabaseFactory.getMmsDatabase(context); TextSecureMessageSender messageSender = messageSenderFactory.create(masterSecret); String destination = message.getTo()[0].getString(); - boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination); + boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination, true); try { Recipients recipients = RecipientFactory.getRecipientsFromString(context, destination, false); @@ -132,7 +132,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { { try { Recipient recipient = RecipientFactory.getRecipientsFromString(context, destination, false).getPrimaryRecipient(); - boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination); + boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination, true); AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret); if (!isSmsFallbackApprovalRequired) { diff --git a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java index fdd55a17cc..86d041d887 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -34,13 +34,13 @@ public abstract class PushSendJob extends MasterSecretJob { super(context, parameters); } - protected static JobParameters constructParameters(Context context, String destination) { + protected static JobParameters constructParameters(Context context, String destination, boolean media) { JobParameters.Builder builder = JobParameters.newBuilder(); builder.withPersistence(); builder.withGroupId(destination); builder.withRequirement(new MasterSecretRequirement(context)); - if (!isSmsFallbackSupported(context, destination)) { + if (!isSmsFallbackSupported(context, destination, media)) { builder.withRequirement(new NetworkRequirement(context)); builder.withRetryCount(5); } @@ -48,7 +48,7 @@ public abstract class PushSendJob extends MasterSecretJob { return builder.create(); } - protected static boolean isSmsFallbackSupported(Context context, String destination) { + protected static boolean isSmsFallbackSupported(Context context, String destination, boolean media) { try { String e164number = Util.canonicalizeNumber(context, destination); @@ -60,6 +60,10 @@ public abstract class PushSendJob extends MasterSecretJob { return false; } + if (media && !TextSecurePreferences.isFallbackMmsEnabled(context)) { + return false; + } + TextSecureDirectory directory = TextSecureDirectory.getInstance(context); return directory.isSmsFallbackSupported(e164number); } catch (InvalidNumberException e) { @@ -74,8 +78,8 @@ public abstract class PushSendJob extends MasterSecretJob { return new PushAddress(recipient.getRecipientId(), e164number, 1, relay); } - protected boolean isSmsFallbackApprovalRequired(String destination) { - return (isSmsFallbackSupported(context, destination) && TextSecurePreferences.isFallbackSmsAskRequired(context)); + protected boolean isSmsFallbackApprovalRequired(String destination, boolean media) { + return (isSmsFallbackSupported(context, destination, media) && TextSecurePreferences.isFallbackSmsAskRequired(context)); } protected List getAttachments(SendReq message) { diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index a08cdd441d..656d9bdad9 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -41,7 +41,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { private final long messageId; public PushTextSendJob(Context context, long messageId, String destination) { - super(context, constructParameters(context, destination)); + super(context, constructParameters(context, destination, false)); this.messageId = messageId; } @@ -101,7 +101,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { throws UntrustedIdentityException, SecureFallbackApprovalException, InsecureFallbackApprovalException, RetryLaterException { - boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination); + boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination, false); try { PushAddress address = getPushAddress(message.getIndividualRecipient()); @@ -133,7 +133,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { throws SecureFallbackApprovalException, InsecureFallbackApprovalException { Recipient recipient = smsMessage.getIndividualRecipient(); - boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination); + boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination, false); AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret); if (!isSmsFallbackApprovalRequired) { diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 3dc734a0b7..8b6d084eb7 100644 --- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -53,6 +53,7 @@ public class TextSecurePreferences { private static final String FALLBACK_SMS_ALLOWED_PREF = "pref_allow_sms_traffic_out"; private static final String FALLBACK_SMS_ASK_REQUIRED_PREF = "pref_sms_fallback_ask"; private static final String DIRECT_SMS_ALLOWED_PREF = "pref_sms_non_data_out"; + private static final String FALLBACK_MMS_ENABLED_PREF = "pref_mms_fallback_enabled"; private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered"; public static boolean isSignedPreKeyRegistered(Context context) { @@ -99,6 +100,14 @@ public class TextSecurePreferences { setBooleanPreference(context, FALLBACK_SMS_ASK_REQUIRED_PREF, required); } + public static boolean isFallbackMmsEnabled(Context context) { + return getBooleanPreference(context, FALLBACK_MMS_ENABLED_PREF, true); + } + + public static void setFallbackMmsEnabled(Context context, boolean enabled) { + setBooleanPreference(context, FALLBACK_MMS_ENABLED_PREF, enabled); + } + public static boolean isDirectSmsAllowed(Context context) { return getBooleanPreference(context, DIRECT_SMS_ALLOWED_PREF, true); } @@ -369,6 +378,4 @@ public class TextSecurePreferences { private static void setLongPreference(Context context, String key, long value) { PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(key, value).apply(); } - - }