Add option that allows disabling MMS fallback with TS users.

// FREEBIE

Closes #1444
This commit is contained in:
Moxie Marlinspike 2014-12-11 16:10:11 -08:00
parent ff05642f3e
commit 3c4ac4b105
9 changed files with 52 additions and 25 deletions

View File

@ -31,7 +31,16 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="14sp" android:textSize="14sp"
android:checkMark="?android:attr/listChoiceIndicatorMultiple" 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" />
<CheckBox android:id="@+id/never_send_mms"
style="@style/TextSecureDialogPrimaryText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:text="@string/preferences__sms_fallback_never_send_mms"
android:layout_marginLeft="25dp" /> android:layout_marginLeft="25dp" />
<CheckBox android:id="@+id/non_data_users" <CheckBox android:id="@+id/non_data_users"

View File

@ -683,12 +683,13 @@
<string name="preferences__use_the_data_channel_for_communication_with_other_textsecure_users"> <string name="preferences__use_the_data_channel_for_communication_with_other_textsecure_users">
Increase privacy and avoid SMS fees by using the data channel for communication with other TextSecure users Increase privacy and avoid SMS fees by using the data channel for communication with other TextSecure users
</string> </string>
<string name="preferences__allow_sms_fallback">Allow outgoing SMS to</string> <string name="preferences__sms_fallback">Outgoing SMS/MMS</string>
<string name="preferences__submit_debug_log">Submit debug log</string> <string name="preferences__submit_debug_log">Submit debug log</string>
<string name="preferences__sms_outgoing_push_users">TextSecure users</string> <string name="preferences__sms_outgoing_push_users">TextSecure users</string>
<string name="preferences__sms_fallback_push_users_ask">(ask first)</string> <string name="preferences__sms_fallback_push_users_ask">(ask first)</string>
<string name="preferences__sms_outgoing_push_users_description">Send secure SMS if data connectivity is lost</string> <string name="preferences__sms_outgoing_push_users_description">Send secure SMS if data connectivity is lost</string>
<string name="preferences__sms_fallback_ask_fallback">Ask before sending SMS</string> <string name="preferences__sms_fallback_ask_before_sending_sms_mms">Ask before sending SMS/MMS</string>
<string name="preferences__sms_fallback_never_send_mms">Never send MMS</string>
<string name="preferences__sms_fallback_non_push_users">Non-TextSecure users</string> <string name="preferences__sms_fallback_non_push_users">Non-TextSecure users</string>
<string name="preferences__sms_fallback_nobody">Nobody</string> <string name="preferences__sms_fallback_nobody">Nobody</string>

View File

@ -16,6 +16,11 @@
android:title="@string/preferences__choose_identity" android:title="@string/preferences__choose_identity"
android:summary="@string/preferences__choose_your_contact_entry_from_the_contacts_list"/> android:summary="@string/preferences__choose_your_contact_entry_from_the_contacts_list"/>
<CheckBoxPreference android:defaultValue="true"
android:key="pref_auto_complete_key_exchange"
android:title="@string/preferences__complete_key_exchanges"
android:summary="@string/preferences__automatically_complete_key_exchanges_for_new_sessions_or_for_existing_sessions_with_the_same_identity_key" />
<Preference android:key="pref_submit_debug_logs" <Preference android:key="pref_submit_debug_logs"
android:title="@string/preferences__submit_debug_log"/> android:title="@string/preferences__submit_debug_log"/>
</PreferenceScreen> </PreferenceScreen>

View File

@ -17,7 +17,7 @@
<org.thoughtcrime.securesms.components.OutgoingSmsPreference <org.thoughtcrime.securesms.components.OutgoingSmsPreference
android:key="pref_outgoing_sms" android:key="pref_outgoing_sms"
android:title="@string/preferences__allow_sms_fallback" /> android:title="@string/preferences__sms_fallback" />
<CheckBoxPreference android:defaultValue="false" <CheckBoxPreference android:defaultValue="false"
android:key="pref_delivery_report_sms" android:key="pref_delivery_report_sms"
@ -27,9 +27,4 @@
<Preference android:key="pref_mms_preferences" <Preference android:key="pref_mms_preferences"
android:title="@string/preferences__advanced_mms_access_point_names"/> android:title="@string/preferences__advanced_mms_access_point_names"/>
<CheckBoxPreference android:defaultValue="true"
android:key="pref_auto_complete_key_exchange"
android:title="@string/preferences__complete_key_exchanges"
android:summary="@string/preferences__automatically_complete_key_exchanges_for_new_sessions_or_for_existing_sessions_with_the_same_identity_key" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -12,7 +12,10 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class OutgoingSmsPreference extends DialogPreference { public class OutgoingSmsPreference extends DialogPreference {
private CheckBox dataUsers; private CheckBox dataUsers;
private CheckBox askForFallback; private CheckBox askForFallback;
private CheckBox neverFallbackMms;
private CheckBox nonDataUsers; private CheckBox nonDataUsers;
public OutgoingSmsPreference(Context context, AttributeSet attrs) { public OutgoingSmsPreference(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
setPersistent(false); setPersistent(false);
@ -24,10 +27,12 @@ public class OutgoingSmsPreference extends DialogPreference {
super.onBindDialogView(view); super.onBindDialogView(view);
dataUsers = (CheckBox) view.findViewById(R.id.data_users); dataUsers = (CheckBox) view.findViewById(R.id.data_users);
askForFallback = (CheckBox) view.findViewById(R.id.ask_before_fallback_data); 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); nonDataUsers = (CheckBox) view.findViewById(R.id.non_data_users);
dataUsers.setChecked(TextSecurePreferences.isFallbackSmsAllowed(getContext())); dataUsers.setChecked(TextSecurePreferences.isFallbackSmsAllowed(getContext()));
askForFallback.setChecked(TextSecurePreferences.isFallbackSmsAskRequired(getContext())); askForFallback.setChecked(TextSecurePreferences.isFallbackSmsAskRequired(getContext()));
neverFallbackMms.setChecked(!TextSecurePreferences.isFallbackMmsEnabled(getContext()));
nonDataUsers.setChecked(TextSecurePreferences.isDirectSmsAllowed(getContext())); nonDataUsers.setChecked(TextSecurePreferences.isDirectSmsAllowed(getContext()));
dataUsers.setOnClickListener(new View.OnClickListener() { dataUsers.setOnClickListener(new View.OnClickListener() {
@ -48,6 +53,7 @@ public class OutgoingSmsPreference extends DialogPreference {
TextSecurePreferences.setFallbackSmsAllowed(getContext(), dataUsers.isChecked()); TextSecurePreferences.setFallbackSmsAllowed(getContext(), dataUsers.isChecked());
TextSecurePreferences.setFallbackSmsAskRequired(getContext(), askForFallback.isChecked()); TextSecurePreferences.setFallbackSmsAskRequired(getContext(), askForFallback.isChecked());
TextSecurePreferences.setDirectSmsAllowed(getContext(), nonDataUsers.isChecked()); TextSecurePreferences.setDirectSmsAllowed(getContext(), nonDataUsers.isChecked());
TextSecurePreferences.setFallbackMmsEnabled(getContext(), !neverFallbackMms.isChecked());
if (getOnPreferenceChangeListener() != null) getOnPreferenceChangeListener().onPreferenceChange(this, null); if (getOnPreferenceChangeListener() != null) getOnPreferenceChangeListener().onPreferenceChange(this, null);
} }
} }

View File

@ -47,7 +47,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
private final long messageId; private final long messageId;
public PushMediaSendJob(Context context, long messageId, String destination) { public PushMediaSendJob(Context context, long messageId, String destination) {
super(context, constructParameters(context, destination)); super(context, constructParameters(context, destination, true));
this.messageId = messageId; this.messageId = messageId;
} }
@ -104,7 +104,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context); MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
TextSecureMessageSender messageSender = messageSenderFactory.create(masterSecret); TextSecureMessageSender messageSender = messageSenderFactory.create(masterSecret);
String destination = message.getTo()[0].getString(); String destination = message.getTo()[0].getString();
boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination); boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination, true);
try { try {
Recipients recipients = RecipientFactory.getRecipientsFromString(context, destination, false); Recipients recipients = RecipientFactory.getRecipientsFromString(context, destination, false);
@ -132,7 +132,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
{ {
try { try {
Recipient recipient = RecipientFactory.getRecipientsFromString(context, destination, false).getPrimaryRecipient(); Recipient recipient = RecipientFactory.getRecipientsFromString(context, destination, false).getPrimaryRecipient();
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination); boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination, true);
AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret); AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret);
if (!isSmsFallbackApprovalRequired) { if (!isSmsFallbackApprovalRequired) {

View File

@ -34,13 +34,13 @@ public abstract class PushSendJob extends MasterSecretJob {
super(context, parameters); 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(); JobParameters.Builder builder = JobParameters.newBuilder();
builder.withPersistence(); builder.withPersistence();
builder.withGroupId(destination); builder.withGroupId(destination);
builder.withRequirement(new MasterSecretRequirement(context)); builder.withRequirement(new MasterSecretRequirement(context));
if (!isSmsFallbackSupported(context, destination)) { if (!isSmsFallbackSupported(context, destination, media)) {
builder.withRequirement(new NetworkRequirement(context)); builder.withRequirement(new NetworkRequirement(context));
builder.withRetryCount(5); builder.withRetryCount(5);
} }
@ -48,7 +48,7 @@ public abstract class PushSendJob extends MasterSecretJob {
return builder.create(); return builder.create();
} }
protected static boolean isSmsFallbackSupported(Context context, String destination) { protected static boolean isSmsFallbackSupported(Context context, String destination, boolean media) {
try { try {
String e164number = Util.canonicalizeNumber(context, destination); String e164number = Util.canonicalizeNumber(context, destination);
@ -60,6 +60,10 @@ public abstract class PushSendJob extends MasterSecretJob {
return false; return false;
} }
if (media && !TextSecurePreferences.isFallbackMmsEnabled(context)) {
return false;
}
TextSecureDirectory directory = TextSecureDirectory.getInstance(context); TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
return directory.isSmsFallbackSupported(e164number); return directory.isSmsFallbackSupported(e164number);
} catch (InvalidNumberException e) { } catch (InvalidNumberException e) {
@ -74,8 +78,8 @@ public abstract class PushSendJob extends MasterSecretJob {
return new PushAddress(recipient.getRecipientId(), e164number, 1, relay); return new PushAddress(recipient.getRecipientId(), e164number, 1, relay);
} }
protected boolean isSmsFallbackApprovalRequired(String destination) { protected boolean isSmsFallbackApprovalRequired(String destination, boolean media) {
return (isSmsFallbackSupported(context, destination) && TextSecurePreferences.isFallbackSmsAskRequired(context)); return (isSmsFallbackSupported(context, destination, media) && TextSecurePreferences.isFallbackSmsAskRequired(context));
} }
protected List<TextSecureAttachment> getAttachments(SendReq message) { protected List<TextSecureAttachment> getAttachments(SendReq message) {

View File

@ -41,7 +41,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
private final long messageId; private final long messageId;
public PushTextSendJob(Context context, long messageId, String destination) { public PushTextSendJob(Context context, long messageId, String destination) {
super(context, constructParameters(context, destination)); super(context, constructParameters(context, destination, false));
this.messageId = messageId; this.messageId = messageId;
} }
@ -101,7 +101,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
throws UntrustedIdentityException, SecureFallbackApprovalException, throws UntrustedIdentityException, SecureFallbackApprovalException,
InsecureFallbackApprovalException, RetryLaterException InsecureFallbackApprovalException, RetryLaterException
{ {
boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination); boolean isSmsFallbackSupported = isSmsFallbackSupported(context, destination, false);
try { try {
PushAddress address = getPushAddress(message.getIndividualRecipient()); PushAddress address = getPushAddress(message.getIndividualRecipient());
@ -133,7 +133,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
throws SecureFallbackApprovalException, InsecureFallbackApprovalException throws SecureFallbackApprovalException, InsecureFallbackApprovalException
{ {
Recipient recipient = smsMessage.getIndividualRecipient(); Recipient recipient = smsMessage.getIndividualRecipient();
boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination); boolean isSmsFallbackApprovalRequired = isSmsFallbackApprovalRequired(destination, false);
AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret); AxolotlStore axolotlStore = new TextSecureAxolotlStore(context, masterSecret);
if (!isSmsFallbackApprovalRequired) { if (!isSmsFallbackApprovalRequired) {

View File

@ -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_ALLOWED_PREF = "pref_allow_sms_traffic_out";
private static final String FALLBACK_SMS_ASK_REQUIRED_PREF = "pref_sms_fallback_ask"; 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 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"; private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered";
public static boolean isSignedPreKeyRegistered(Context context) { public static boolean isSignedPreKeyRegistered(Context context) {
@ -99,6 +100,14 @@ public class TextSecurePreferences {
setBooleanPreference(context, FALLBACK_SMS_ASK_REQUIRED_PREF, required); 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) { public static boolean isDirectSmsAllowed(Context context) {
return getBooleanPreference(context, DIRECT_SMS_ALLOWED_PREF, true); 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) { private static void setLongPreference(Context context, String key, long value) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(key, value).apply(); PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(key, value).apply();
} }
} }