From 54fad30f9f19c68e8e42ae3f85f76dd7f1113a3f Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sat, 8 Dec 2012 16:46:38 -0800 Subject: [PATCH] Add ability to specify APN information in TextSecure settings. 1) Add configuration options for APN information in TextSecure settings. 2) Fall back to TextSecure settings if system settings are unavailable while sending/receiving MMS. 3) Catch sqlite exception when devices randomly don't have the same APN db or table structure. --- res/values/strings.xml | 18 ++++++-- res/xml/preferences.xml | 16 ++++++++ .../ApplicationPreferencesActivity.java | 39 ++++++++++++++++++ .../mms/ApnUnavailableException.java | 19 +++++++++ .../securesms/mms/MmsCommunication.java | 41 +++++++++++++++---- .../securesms/mms/MmsDownloadHelper.java | 6 +-- .../securesms/mms/MmsSendHelper.java | 6 +-- 7 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/mms/ApnUnavailableException.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 8966823744..034918a648 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -249,6 +249,14 @@ Send Remove + + Download + Downloading + + + Download + Downloading + Batch Selection Mode @@ -362,6 +370,12 @@ Normal Slow Custom + Advanced: MMS Access Point Names + Enable local APNs + Use APN information configured here when system APN information is unavailable. + MMSC URL (Required) + MMS Proxy (Optional) + @@ -434,9 +448,5 @@ TextSecure is a security enhanced text messaging application that serves as a full replacement for the default text messaging application. Messages to other TextSecure users are encrypted over the air, and all text messages are stored in an encrypted database on the device. If your phone is lost or stolen, your messages will be safe, and communication with other TextSecure users can\'t be monitored over the air. - Download - Downloading - Download - Downloading diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index df6695a8cc..a853df6857 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -140,4 +140,20 @@ android:title="@string/preferences__vibrate" android:summary="@string/preferences__also_vibrate_when_notified" /> + + + + + + + + + diff --git a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java index 8ec4fb69c5..7470d3e239 100644 --- a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java +++ b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; +import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceManager; import android.provider.ContactsContract; @@ -74,6 +75,10 @@ public class ApplicationPreferencesActivity extends SherlockPreferenceActivity { private static final String MANAGE_IDENTITIES_PREF = "pref_manage_identity"; private static final String CHANGE_PASSPHRASE_PREF = "pref_change_passphrase"; + public static final String USE_LOCAL_MMS_APNS_PREF = "pref_use_local_apns"; + public static final String MMSC_HOST_PREF = "pref_apn_mmsc_host"; + public static final String MMSC_PROXY_PREF = "pref_apn_mms_proxy"; + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -83,6 +88,7 @@ public class ApplicationPreferencesActivity extends SherlockPreferenceActivity { addPreferencesFromResource(R.xml.preferences); initializeIdentitySelection(); + initializeEditTextSummaries(); this.findPreference(VIEW_MY_IDENTITY_PREF) .setOnPreferenceClickListener(new ViewMyIdentityClickListener()); @@ -138,6 +144,39 @@ public class ApplicationPreferencesActivity extends SherlockPreferenceActivity { return false; } + + private void initializeEditTextSummaries() { + final EditTextPreference mmscUrlPreference = (EditTextPreference)this.findPreference(MMSC_HOST_PREF); + final EditTextPreference mmsProxyPreference = (EditTextPreference)this.findPreference(MMSC_PROXY_PREF); + + if (mmscUrlPreference.getText() == null) { + mmscUrlPreference.setSummary("Not set"); + } else { + mmscUrlPreference.setSummary(mmscUrlPreference.getText()); + } + + if (mmsProxyPreference.getText() == null) { + mmsProxyPreference.setSummary("Not set"); + } else { + mmsProxyPreference.setSummary(mmsProxyPreference.getText()); + } + + mmscUrlPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mmscUrlPreference.setSummary(newValue == null ? "Not set" : (String)newValue); + return true; + } + }); + + mmsProxyPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mmsProxyPreference.setSummary(newValue == null ? "Not set" : (String)newValue); + return true; + } + }); + } private void initializeIdentitySelection() { ContactIdentityManager identity = ContactIdentityManager.getInstance(this); diff --git a/src/org/thoughtcrime/securesms/mms/ApnUnavailableException.java b/src/org/thoughtcrime/securesms/mms/ApnUnavailableException.java new file mode 100644 index 0000000000..7aea170fb8 --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/ApnUnavailableException.java @@ -0,0 +1,19 @@ +package org.thoughtcrime.securesms.mms; + +public class ApnUnavailableException extends Exception { + + public ApnUnavailableException() { + } + + public ApnUnavailableException(String detailMessage) { + super(detailMessage); + } + + public ApnUnavailableException(Throwable throwable) { + super(throwable); + } + + public ApnUnavailableException(String detailMessage, Throwable throwable) { + super(detailMessage, throwable); + } +} diff --git a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java index 870eda6fc4..3c48304a28 100644 --- a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java +++ b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java @@ -17,9 +17,13 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; +import android.content.SharedPreferences; import android.database.Cursor; +import android.database.sqlite.SQLiteException; import android.net.ConnectivityManager; import android.net.Uri; +import android.preference.PreferenceManager; +import android.util.Log; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; @@ -37,26 +41,46 @@ import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; +import org.thoughtcrime.securesms.ApplicationPreferencesActivity; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.service.MmsDownloader; import org.thoughtcrime.securesms.util.Conversions; -import ws.com.google.android.mms.MmsException; - import java.io.DataInputStream; import java.io.IOException; import java.net.InetAddress; public class MmsCommunication { - protected static MmsConnectionParameters getMmsConnectionParameters(Context context, String apn) - throws MmsException + protected static MmsConnectionParameters getLocallyConfiguredMmsConnectionParameters(Context context) + throws ApnUnavailableException { - Cursor cursor = DatabaseFactory.getMmsDatabase(context).getCarrierMmsInformation(apn); + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + if (preferences.getBoolean(ApplicationPreferencesActivity.USE_LOCAL_MMS_APNS_PREF, false)) { + String mmsc = preferences.getString(ApplicationPreferencesActivity.MMSC_HOST_PREF, null); + + if (mmsc == null || !mmsc.startsWith("http")) + throw new ApnUnavailableException("Malformed locally configured MMSC: " + mmsc); + + String proxy = preferences.getString(ApplicationPreferencesActivity.MMSC_PROXY_PREF, null); + + return new MmsConnectionParameters(mmsc, proxy, null); + } + + throw new ApnUnavailableException("No locally configured parameters available"); + } + + protected static MmsConnectionParameters getMmsConnectionParameters(Context context, String apn) + throws ApnUnavailableException + { + Cursor cursor = null; try { + cursor = DatabaseFactory.getMmsDatabase(context).getCarrierMmsInformation(apn); + if (cursor == null || !cursor.moveToFirst()) - throw new MmsException("No carrier MMS information available."); + return getLocallyConfiguredMmsConnectionParameters(context); do { String mmsc = cursor.getString(cursor.getColumnIndexOrThrow("mmsc")); @@ -68,7 +92,10 @@ public class MmsCommunication { } while (cursor.moveToNext()); - throw new MmsException("No carrier MMS information available."); + return getLocallyConfiguredMmsConnectionParameters(context); + } catch (SQLiteException sqe) { + Log.w("MmsCommunication", sqe); + return getLocallyConfiguredMmsConnectionParameters(context); } finally { if (cursor != null) cursor.close(); diff --git a/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java b/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java index d1f5334248..3e65da13f0 100644 --- a/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java +++ b/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java @@ -25,8 +25,6 @@ import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; -import ws.com.google.android.mms.MmsException; - import java.io.IOException; public class MmsDownloadHelper extends MmsCommunication { @@ -54,8 +52,8 @@ public class MmsDownloadHelper extends MmsCommunication { try { connectionParameters = getMmsConnectionParameters(context, apn); - } catch (MmsException me) { - Log.w("MmsDownloadHelper", me); + } catch (ApnUnavailableException aue) { + Log.w("MmsDownloadHelper", aue); connectionParameters = new MmsConnectionParameters(null, null, null); } diff --git a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java index 8e2c3837cf..4ed5b9d42e 100644 --- a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java +++ b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java @@ -26,8 +26,6 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; -import ws.com.google.android.mms.MmsException; - import java.io.IOException; public class MmsSendHelper extends MmsCommunication { @@ -59,8 +57,8 @@ public class MmsSendHelper extends MmsCommunication { MmsConnectionParameters parameters = getMmsConnectionParameters(context, apn); checkRouteToHost(context, parameters, parameters.getMmsc()); return makePost(parameters, mms); - } catch (MmsException me) { - Log.w("MmsSender", me); + } catch (ApnUnavailableException aue) { + Log.w("MmsSender", aue); throw new IOException("Failed to get MMSC information..."); } }