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.
This commit is contained in:
Moxie Marlinspike 2012-12-08 16:46:38 -08:00
parent 10885fa8db
commit 54fad30f9f
7 changed files with 126 additions and 19 deletions

View File

@ -249,6 +249,14 @@
<string name="conversation_activity__send">Send</string>
<string name="conversation_activity__remove">Remove</string>
<!-- conversation_item_sent -->
<string name="conversation_item_sent__download">Download</string>
<string name="conversation_item_sent__downloading">Downloading</string>
<!-- conversation_item_received -->
<string name="conversation_item_received__download">Download</string>
<string name="conversation_item_received__downloading">Downloading</string>
<!-- conversation_fragment_cab -->
<string name="conversation_fragment_cab__batch_selection_mode">Batch Selection Mode</string>
@ -362,6 +370,12 @@
<string name="preferences__normal">Normal</string>
<string name="preferences__slow">Slow</string>
<string name="preferences__custom">Custom</string>
<string name="preferences__advanced_mms_access_point_names">Advanced: MMS Access Point Names</string>
<string name="preferences__enable_local_apns">Enable local APNs</string>
<string name="preferences__use_apn_information_configured_here_when_system_apn_information_is_unavailable">Use APN information configured here when system APN information is unavailable.</string>
<string name="preferences__mmsc_url_required">MMSC URL (Required)</string>
<string name="preferences__mms_proxy_optional">MMS Proxy (Optional)</string>
<!-- **************************************** -->
<!-- menus -->
@ -434,9 +448,5 @@
<string name="PlayStoreListing">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.</string>
<!-- EOF -->
<string name="conversation_item_sent__download">Download</string>
<string name="conversation_item_sent__downloading">Downloading</string>
<string name="conversation_item_received__download">Download</string>
<string name="conversation_item_received__downloading">Downloading</string>
</resources>

View File

@ -140,4 +140,20 @@
android:title="@string/preferences__vibrate"
android:summary="@string/preferences__also_vibrate_when_notified" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/preferences__advanced_mms_access_point_names">
<CheckBoxPreference android:key="pref_use_local_apns"
android:defaultValue="false"
android:title="@string/preferences__enable_local_apns"
android:summary="@string/preferences__use_apn_information_configured_here_when_system_apn_information_is_unavailable"/>
<EditTextPreference android:key="pref_apn_mmsc_host"
android:title="@string/preferences__mmsc_url_required"
android:dependency="pref_use_local_apns" />
<EditTextPreference android:key="pref_apn_mms_proxy"
android:title="@string/preferences__mms_proxy_optional"
android:dependency="pref_use_local_apns" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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...");
}
}