diff --git a/res/values/strings.xml b/res/values/strings.xml
index 48a2d8eadb..eacd477392 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -103,6 +103,11 @@
No scanned key found!
+
+
+ No connectivity available for MMS download, try again later...
+ Error storing MMS!
+ Error connecting to MMS provider...
Passphrases Don\'t Match!
diff --git a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
index da150c6352..4174ff34e0 100644
--- a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
+++ b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
@@ -63,7 +63,8 @@ public class MmsCommunication {
throw new ApnUnavailableException("No locally configured parameters available");
}
- protected static MmsConnectionParameters getMmsConnectionParameters(Context context, String apn)
+ protected static MmsConnectionParameters getMmsConnectionParameters(Context context, String apn,
+ boolean proxyIfPossible)
throws ApnUnavailableException
{
Cursor cursor = null;
@@ -76,8 +77,13 @@ public class MmsCommunication {
do {
String mmsc = cursor.getString(cursor.getColumnIndexOrThrow("mmsc"));
- String proxy = cursor.getString(cursor.getColumnIndexOrThrow("mmsproxy"));
- String port = cursor.getString(cursor.getColumnIndexOrThrow("mmsport"));
+ String proxy = null;
+ String port = null;
+
+ if (proxyIfPossible) {
+ proxy = cursor.getString(cursor.getColumnIndexOrThrow("mmsproxy"));
+ port = cursor.getString(cursor.getColumnIndexOrThrow("mmsport"));
+ }
if (mmsc != null && !mmsc.equals(""))
return new MmsConnectionParameters(mmsc, proxy, port);
@@ -97,15 +103,29 @@ public class MmsCommunication {
}
}
- protected static void checkRouteToHost(Context context, MmsConnectionParameters parameters, String url) throws IOException {
+ protected static void checkRouteToHost(Context context, MmsConnectionParameters parameters,
+ String url, boolean usingMmsRadio)
+ throws IOException
+ {
if (parameters == null || !parameters.hasProxy())
- checkRouteToHost(context, Uri.parse(url).getHost());
+ checkRouteToHost(context, Uri.parse(url).getHost(), usingMmsRadio);
else
- checkRouteToHost(context, parameters.getProxy());
+ checkRouteToHost(context, parameters.getProxy(), usingMmsRadio);
}
- private static void checkRouteToHost(Context context, String host) throws IOException {
- InetAddress inetAddress = InetAddress.getByName(host);
+ private static void checkRouteToHost(Context context, String host, boolean usingMmsRadio)
+ throws IOException
+ {
+ InetAddress inetAddress = InetAddress.getByName(host);
+
+ if (!usingMmsRadio) {
+ if (inetAddress.isSiteLocalAddress()) {
+ throw new IOException("RFC1918 address in non-MMS radio situation!");
+ }
+
+ return;
+ }
+
byte[] ipAddressBytes = inetAddress.getAddress();
int ipAddress = Conversions.byteArrayToIntLittleEndian(ipAddressBytes, 0);
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java b/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java
index 0e380a911b..c32227cbb5 100644
--- a/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java
+++ b/src/org/thoughtcrime/securesms/mms/MmsDownloadHelper.java
@@ -26,6 +26,9 @@ import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
+import ws.com.google.android.mms.pdu.PduParser;
+import ws.com.google.android.mms.pdu.RetrieveConf;
+
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -46,15 +49,6 @@ public class MmsDownloadHelper extends MmsCommunication {
request.setParams(client.getParams());
request.addHeader("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
-// java.util.logging.Logger.getLogger("org.apache.http.wire").setLevel(java.util.logging.Level.FINEST);
-// java.util.logging.Logger.getLogger("org.apache.http.headers").setLevel(java.util.logging.Level.FINEST);
-//
-// System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
-// System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
-// System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
-// System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
-// System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug");
-
HttpResponse response = client.execute(target, request);
StatusLine status = response.getStatusLine();
@@ -71,17 +65,29 @@ public class MmsDownloadHelper extends MmsCommunication {
}
}
- public static byte[] retrieveMms(Context context, String url, String apn) throws IOException {
+ public static RetrieveConf retrieveMms(Context context, String url, String apn,
+ boolean usingMmsRadio, boolean proxyIfPossible)
+ throws IOException
+ {
MmsConnectionParameters connectionParameters;
try {
- connectionParameters = getMmsConnectionParameters(context, apn);
+ connectionParameters = getMmsConnectionParameters(context, apn, proxyIfPossible);
} catch (ApnUnavailableException aue) {
Log.w("MmsDownloadHelper", aue);
connectionParameters = new MmsConnectionParameters(null, null, null);
}
- checkRouteToHost(context, connectionParameters, url);
- return makeRequest(context, connectionParameters, url);
+ checkRouteToHost(context, connectionParameters, url, usingMmsRadio);
+
+ byte[] pdu = makeRequest(context, connectionParameters, url);
+
+ RetrieveConf retrieved = (RetrieveConf)new PduParser(pdu).parse();
+
+ if (retrieved == null) {
+ throw new IOException("Bad retrieved PDU");
+ }
+
+ return retrieved;
}
}
diff --git a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
index 8197629365..225b61f671 100644
--- a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
+++ b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
@@ -27,6 +27,9 @@ import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
+import ws.com.google.android.mms.pdu.PduParser;
+import ws.com.google.android.mms.pdu.SendConf;
+
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -66,12 +69,16 @@ public class MmsSendHelper extends MmsCommunication {
}
}
- public static byte[] sendMms(Context context, byte[] mms, String apn) throws IOException {
+ public static SendConf sendMms(Context context, byte[] mms, String apn,
+ boolean usingMmsRadio, boolean useProxyIfAvailable)
+ throws IOException
+ {
Log.w("MmsSender", "Sending MMS of length: " + mms.length);
try {
- MmsConnectionParameters parameters = getMmsConnectionParameters(context, apn);
- checkRouteToHost(context, parameters, parameters.getMmsc());
- return makePost(context, parameters, mms);
+ MmsConnectionParameters parameters = getMmsConnectionParameters(context, apn, useProxyIfAvailable);
+ checkRouteToHost(context, parameters, parameters.getMmsc(), usingMmsRadio);
+ byte[] response = makePost(context, parameters, mms);
+ return (SendConf) new PduParser(response).parse();
} catch (ApnUnavailableException aue) {
Log.w("MmsSender", aue);
throw new IOException("Failed to get MMSC information...");
diff --git a/src/org/thoughtcrime/securesms/service/MmsDownloader.java b/src/org/thoughtcrime/securesms/service/MmsDownloader.java
index ef9981ed78..668831c420 100644
--- a/src/org/thoughtcrime/securesms/service/MmsDownloader.java
+++ b/src/org/thoughtcrime/securesms/service/MmsDownloader.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
+import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.crypto.DecryptingQueue;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
@@ -28,7 +29,6 @@ import org.thoughtcrime.securesms.mms.MmsDownloadHelper;
import org.thoughtcrime.securesms.protocol.WirePrefix;
import ws.com.google.android.mms.MmsException;
-import ws.com.google.android.mms.pdu.PduParser;
import ws.com.google.android.mms.pdu.RetrieveConf;
import java.io.IOException;
@@ -44,73 +44,105 @@ public class MmsDownloader extends MmscProcessor {
this.toastHandler = toastHandler;
}
- private void handleDownloadMms(DownloadItem item) {
- if (!isConnectivityPossible()) {
- DatabaseFactory.getMmsDatabase(context).markDownloadState(item.getMessageId(), MmsDatabase.Types.DOWNLOAD_NO_CONNECTIVITY);
- toastHandler.makeToast("No connectivity available for MMS download, try again later...");
- Log.w("MmsDownloadService", "Unable to download MMS, please try again later.");
- } else {
- DatabaseFactory.getMmsDatabase(context).markDownloadState(item.getMessageId(), MmsDatabase.Types.DOWNLOAD_CONNECTING);
- pendingMessages.add(item);
- issueConnectivityRequest();
+ public void process(MasterSecret masterSecret, Intent intent) {
+ if (intent.getAction().equals(SendReceiveService.DOWNLOAD_MMS_ACTION)) {
+ DownloadItem item = new DownloadItem(masterSecret, false, false,
+ intent.getLongExtra("message_id", -1),
+ intent.getLongExtra("thread_id", -1),
+ intent.getStringExtra("content_location"),
+ intent.getByteArrayExtra("transaction_id"));
+
+ handleDownloadMmsAction(item);
+ } else if (intent.getAction().equals(SendReceiveService.DOWNLOAD_MMS_CONNECTIVITY_ACTION)) {
+ handleConnectivityChange();
}
}
- private void handleDownloadMmsContinued(DownloadItem item) {
- Log.w("MmsDownloadService", "Handling MMS download continuation...");
+ private void handleDownloadMmsAction(DownloadItem item) {
+ if (!isConnectivityPossible()) {
+ Log.w("MmsDownloader", "No MMS connectivity available!");
+ DatabaseFactory.getMmsDatabase(context).markDownloadState(item.getMessageId(), MmsDatabase.Types.DOWNLOAD_NO_CONNECTIVITY);
+ toastHandler.makeToast(context.getString(R.string.MmsDownloader_no_connectivity_available_for_mms_download_try_again_later));
+ return;
+ }
+
+ DatabaseFactory.getMmsDatabase(context).markDownloadState(item.getMessageId(), MmsDatabase.Types.DOWNLOAD_CONNECTING);
+
+ if (item.useMmsRadioMode()) downloadMmsWithRadioChange(item);
+ else downloadMms(item);
+ }
+
+ private void downloadMmsWithRadioChange(DownloadItem item) {
+ Log.w("MmsDownloader", "Handling MMS download with radio change...");
+ pendingMessages.add(item);
+ issueConnectivityRequest();
+ }
+
+ private void downloadMms(DownloadItem item) {
+ Log.w("MmsDownloadService", "Handling actual MMS download...");
MmsDatabase mmsDatabase;
- if (item.getMasterSecret() == null)
+ if (item.getMasterSecret() == null) {
mmsDatabase = DatabaseFactory.getMmsDatabase(context);
- else
+ } else {
mmsDatabase = DatabaseFactory.getEncryptingMmsDatabase(context, item.getMasterSecret());
-
+ }
try {
- byte[] pdu = MmsDownloadHelper.retrieveMms(context, item.getContentLocation(),
- getApnInformation());
- RetrieveConf retrieved = (RetrieveConf)new PduParser(pdu).parse();
-
- if (retrieved == null)
- throw new IOException("Bad retrieved PDU");
+ RetrieveConf retrieved = MmsDownloadHelper.retrieveMms(context, item.getContentLocation(),
+ getApnInformation(),
+ item.useMmsRadioMode(),
+ item.proxyRequestIfPossible());
for (int i=0;i pendingMessages = new LinkedList();
- private final Handler toastHandler;
+ private final LinkedList pendingMessages = new LinkedList();
+ private final ToastHandler toastHandler;
- public MmsSender(Context context, Handler toastHandler) {
+ public MmsSender(Context context, ToastHandler toastHandler) {
super(context);
this.toastHandler = toastHandler;
}
@@ -66,49 +67,137 @@ public class MmsSender extends MmscProcessor {
MmsDatabase database = DatabaseFactory.getEncryptingMmsDatabase(context, masterSecret);
try {
- SendReq[] sendRequests;
+ List sendRequests = getOutgoingMessages(masterSecret, messageId);
- if (messageId == -1) {
- sendRequests = database.getOutgoingMessages();
- } else {
- sendRequests = new SendReq[1];
- sendRequests[0] = database.getSendRequest(messageId);
+ for (SendReq sendRequest : sendRequests) {
+ handleSendMmsAction(new SendItem(masterSecret, sendRequest, messageId != -1, false, false));
}
- if (sendRequests != null && sendRequests.length > 0)
- handleSendMms(sendRequests, messageId != -1);
-
} catch (MmsException me) {
Log.w("MmsSender", me);
if (messageId != -1)
database.markAsSentFailed(messageId);
}
} else if (intent.getAction().equals(SendReceiveService.SEND_MMS_CONNECTIVITY_ACTION)) {
- handleConnectivityChange(masterSecret);
+ handleConnectivityChange();
}
}
- protected void handleConnectivityChange(MasterSecret masterSecret) {
- if (!isConnected())
- return;
-
- if (!pendingMessages.isEmpty()) handleSendMmsContinued(masterSecret, pendingMessages.remove());
- else finishConnectivity();
- }
-
- private void handleSendMms(SendReq[] sendRequests, boolean targeted) {
+ private void handleSendMmsAction(SendItem item) {
if (!isConnectivityPossible()) {
- if (targeted) {
+ if (item.targeted) {
toastHandler
.obtainMessage(0, context.getString(R.string.MmsSender_currently_unable_to_send_your_mms_message))
.sendToTarget();
}
-// for (int i=0;i getOutgoingMessages(MasterSecret masterSecret, long messageId)
+ throws MmsException
+ {
+ MmsDatabase database = DatabaseFactory.getEncryptingMmsDatabase(context, masterSecret);
+ List sendRequests;
+
+ if (messageId == -1) {
+ sendRequests = Arrays.asList(database.getOutgoingMessages());
+ } else {
+ sendRequests = new ArrayList(1);
+ sendRequests.add(database.getSendRequest(messageId));
+ }
+
+ return sendRequests;
+ }
+
+ protected void handleConnectivityChange() {
+ if (!isConnected()) {
+ if (!isConnectivityPossible() && !pendingMessages.isEmpty()) {
+ DatabaseFactory.getMmsDatabase(context).markAsSentFailed(pendingMessages.remove().request.getDatabaseMessageId());
+ toastHandler.makeToast(context.getString(R.string.MmsSender_currently_unable_to_send_your_mms_message));
+ Log.w("MmsSender", "Unable to send MMS.");
+ finishConnectivity();
+ }
+
+ return;
+ }
+
+ for (SendItem item : pendingMessages) {
+ sendMmsMessage(item);
+ }
+
+ pendingMessages.clear();
+ finishConnectivity();
}
private boolean isInconsistentResponse(SendReq send, SendConf response) {
@@ -145,69 +234,15 @@ public class MmsSender extends MmscProcessor {
return pdu;
}
- private void sendMms(MmsDatabase db, SendReq pdu, String number, long messageId, boolean secure) {
- try {
- if (number != null && number.trim().length() != 0)
- pdu.setFrom(new EncodedStringValue(number));
-
- byte[] response = MmsSendHelper.sendMms(context, new PduComposer(context, pdu).make(), getApnInformation());
- SendConf conf = (SendConf) new PduParser(response).parse();
-
- for (int i=0;i