Correct retry logic for SMS JB+ and for push groups.
This commit is contained in:
parent
b79bc4c234
commit
4e703d5a00
8 changed files with 121 additions and 72 deletions
|
@ -92,7 +92,7 @@
|
|||
<activity android:name=".MmsPreferencesActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".ConversationListActivity"
|
||||
<activity android:name=".ConversationListActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
@ -251,14 +251,6 @@
|
|||
<data android:mimeType="application/vnd.wap.mms-message" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".service.SystemStateListener"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".notifications.MarkReadReceiver"
|
||||
android:enabled="true"
|
||||
|
|
|
@ -247,6 +247,11 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
|||
" WHERE " + ID + " = ?", new String[] {id + ""});
|
||||
}
|
||||
|
||||
public void markAsOutbox(long messageId) {
|
||||
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_OUTBOX_TYPE);
|
||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||
}
|
||||
|
||||
public void markAsSending(long messageId) {
|
||||
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_SENDING_TYPE);
|
||||
notifyConversationListeners(getThreadIdForMessage(messageId));
|
||||
|
@ -324,8 +329,8 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
|
|||
selection = ID_WHERE;
|
||||
selectionArgs = new String[]{messageId + ""};
|
||||
} else {
|
||||
selection = MESSAGE_BOX + " & " + Types.BASE_TYPE_MASK + " = ?";
|
||||
selectionArgs = new String[]{Types.BASE_OUTBOX_TYPE + ""};
|
||||
selection = MESSAGE_BOX + " & " + Types.BASE_TYPE_MASK + " = " + Types.BASE_OUTBOX_TYPE;
|
||||
selectionArgs = null;
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
*/
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
|
@ -28,6 +30,7 @@ import org.thoughtcrime.securesms.mms.MmsSendResult;
|
|||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
@ -37,10 +40,14 @@ import ws.com.google.android.mms.pdu.SendReq;
|
|||
|
||||
public class MmsSender {
|
||||
|
||||
private final Context context;
|
||||
private final Context context;
|
||||
private final SystemStateListener systemStateListener;
|
||||
private final ToastHandler toastHandler;
|
||||
|
||||
public MmsSender(Context context, ToastHandler toastHandler) {
|
||||
this.context = context;
|
||||
public MmsSender(Context context, SystemStateListener systemStateListener, ToastHandler toastHandler) {
|
||||
this.context = context;
|
||||
this.systemStateListener = systemStateListener;
|
||||
this.toastHandler = toastHandler;
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
|
@ -73,11 +80,23 @@ public class MmsSender {
|
|||
|
||||
database.markAsSent(message.getDatabaseMessageId(), result.getMessageId(),
|
||||
result.getResponseStatus());
|
||||
|
||||
systemStateListener.unregisterForConnectivityChange();
|
||||
} catch (UndeliverableMessageException e) {
|
||||
Log.w("MmsSender", e);
|
||||
database.markAsSentFailed(message.getDatabaseMessageId());
|
||||
Recipients recipients = threads.getRecipientsForThreadId(threadId);
|
||||
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
||||
} catch (RetryLaterException e) {
|
||||
Log.w("MmsSender", e);
|
||||
database.markAsOutbox(message.getDatabaseMessageId());
|
||||
|
||||
if (systemStateListener.isConnected()) scheduleQuickRetryAlarm();
|
||||
else systemStateListener.registerForConnectivityChange();
|
||||
|
||||
toastHandler
|
||||
.obtainMessage(0, context.getString(R.string.SmsReceiver_currently_unable_to_send_your_sms_message))
|
||||
.sendToTarget();
|
||||
}
|
||||
}
|
||||
} catch (MmsException e) {
|
||||
|
@ -86,4 +105,13 @@ public class MmsSender {
|
|||
database.markAsSentFailed(messageId);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleQuickRetryAlarm() {
|
||||
((AlarmManager)context.getSystemService(Context.ALARM_SERVICE))
|
||||
.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (30 * 1000),
|
||||
PendingIntent.getService(context, 0,
|
||||
new Intent(SendReceiveService.SEND_MMS_ACTION,
|
||||
null, context, SendReceiveService.class),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ import android.os.Message;
|
|||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.CanonicalSessionMigrator;
|
||||
import org.thoughtcrime.securesms.util.WorkerThread;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
@ -69,7 +69,8 @@ public class SendReceiveService extends Service {
|
|||
private static final int DOWNLOAD_PUSH = 7;
|
||||
private static final int DOWNLOAD_AVATAR = 8;
|
||||
|
||||
private ToastHandler toastHandler;
|
||||
private ToastHandler toastHandler;
|
||||
private SystemStateListener systemStateListener;
|
||||
|
||||
private SmsReceiver smsReceiver;
|
||||
private SmsSender smsSender;
|
||||
|
@ -149,14 +150,15 @@ public class SendReceiveService extends Service {
|
|||
}
|
||||
|
||||
private void initializeHandlers() {
|
||||
toastHandler = new ToastHandler();
|
||||
systemStateListener = new SystemStateListener(this);
|
||||
toastHandler = new ToastHandler();
|
||||
}
|
||||
|
||||
private void initializeProcessors() {
|
||||
smsReceiver = new SmsReceiver(this);
|
||||
smsSender = new SmsSender(this, toastHandler);
|
||||
smsSender = new SmsSender(this, systemStateListener, toastHandler);
|
||||
mmsReceiver = new MmsReceiver(this);
|
||||
mmsSender = new MmsSender(this, toastHandler);
|
||||
mmsSender = new MmsSender(this, systemStateListener, toastHandler);
|
||||
mmsDownloader = new MmsDownloader(this, toastHandler);
|
||||
pushReceiver = new PushReceiver(this);
|
||||
pushDownloader = new PushDownloader(this);
|
||||
|
|
|
@ -19,13 +19,11 @@ package org.thoughtcrime.securesms.service;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
|
@ -34,15 +32,18 @@ import org.thoughtcrime.securesms.recipients.Recipients;
|
|||
import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
public class SmsSender {
|
||||
|
||||
private final Context context;
|
||||
private final ToastHandler toastHandler;
|
||||
private final Context context;
|
||||
private final SystemStateListener systemStateListener;
|
||||
private final ToastHandler toastHandler;
|
||||
|
||||
public SmsSender(Context context, ToastHandler toastHandler) {
|
||||
this.context = context;
|
||||
this.toastHandler = toastHandler;
|
||||
public SmsSender(Context context, SystemStateListener systemStateListener, ToastHandler toastHandler) {
|
||||
this.context = context;
|
||||
this.systemStateListener = systemStateListener;
|
||||
this.toastHandler = toastHandler;
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
|
@ -127,18 +128,10 @@ public class SmsSender {
|
|||
}
|
||||
|
||||
private void registerForRadioChanges() {
|
||||
unregisterForRadioChanges();
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(SystemStateListener.ACTION_SERVICE_STATE);
|
||||
context.registerReceiver(SystemStateListener.getInstance(), intentFilter);
|
||||
systemStateListener.registerForConnectivityChange();
|
||||
}
|
||||
|
||||
private void unregisterForRadioChanges() {
|
||||
try {
|
||||
context.unregisterReceiver(SystemStateListener.getInstance());
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Log.w("SmsSender", iae);
|
||||
}
|
||||
systemStateListener.unregisterForConnectivityChange();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,21 +3,48 @@ package org.thoughtcrime.securesms.service;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.mms.MmsRadio;
|
||||
public class SystemStateListener {
|
||||
|
||||
public class SystemStateListener extends BroadcastReceiver {
|
||||
private final TelephonyListener telephonyListener = new TelephonyListener();
|
||||
private final ConnectivityListener connectivityListener = new ConnectivityListener();
|
||||
private final Context context;
|
||||
private final TelephonyManager telephonyManager;
|
||||
private final ConnectivityManager connectivityManager;
|
||||
|
||||
public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE";
|
||||
private static final String ACTION_CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
|
||||
public SystemStateListener(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
}
|
||||
|
||||
private static final SystemStateListener instance = new SystemStateListener();
|
||||
public void registerForConnectivityChange() {
|
||||
unregisterForConnectivityChange();
|
||||
|
||||
public static SystemStateListener getInstance() {
|
||||
return instance;
|
||||
telephonyManager.listen(telephonyListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||
context.registerReceiver(connectivityListener, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
}
|
||||
|
||||
public void unregisterForConnectivityChange() {
|
||||
telephonyManager.listen(telephonyListener, 0);
|
||||
|
||||
try {
|
||||
context.unregisterReceiver(connectivityListener);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Log.w("SystemStateListener", iae);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return
|
||||
connectivityManager.getActiveNetworkInfo() != null &&
|
||||
connectivityManager.getActiveNetworkInfo().isConnected();
|
||||
}
|
||||
|
||||
private void sendSmsOutbox(Context context) {
|
||||
|
@ -32,34 +59,27 @@ public class SystemStateListener extends BroadcastReceiver {
|
|||
context.startService(mmsSenderIntent);
|
||||
}
|
||||
|
||||
private void handleRadioServiceStateChange(Context context, Intent intent) {
|
||||
int state = intent.getIntExtra("state", -31337);
|
||||
|
||||
if (state == ServiceState.STATE_IN_SERVICE) {
|
||||
sendSmsOutbox(context);
|
||||
private class TelephonyListener extends PhoneStateListener {
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState state) {
|
||||
if (state.getState() == ServiceState.STATE_IN_SERVICE) {
|
||||
sendSmsOutbox(context);
|
||||
sendMmsOutbox(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDataServiceStateChange(Context context, Intent intent) {
|
||||
ConnectivityManager connectivityManager
|
||||
= (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(MmsRadio.TYPE_MOBILE_MMS);
|
||||
|
||||
if (networkInfo != null && networkInfo.isAvailable()) {
|
||||
sendMmsOutbox(context);
|
||||
private class ConnectivityListener extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent != null && ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
|
||||
if (connectivityManager.getActiveNetworkInfo() != null &&
|
||||
connectivityManager.getActiveNetworkInfo().isConnected())
|
||||
{
|
||||
sendSmsOutbox(context);
|
||||
sendMmsOutbox(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent == null) return;
|
||||
|
||||
if (intent.getAction().equals(ACTION_SERVICE_STATE)) {
|
||||
handleRadioServiceStateChange(context, intent);
|
||||
} else if (intent.getAction().equals(ACTION_CONNECTIVITY_CHANGE)) {
|
||||
handleDataServiceStateChange(context, intent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package org.thoughtcrime.securesms.transport;
|
||||
|
||||
public class RetryLaterException extends Exception {
|
||||
}
|
|
@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.transport;
|
|||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.MmsSendResult;
|
||||
|
@ -82,7 +83,7 @@ public class UniversalTransport {
|
|||
}
|
||||
|
||||
public MmsSendResult deliver(SendReq mediaMessage, long threadId)
|
||||
throws UndeliverableMessageException
|
||||
throws UndeliverableMessageException, RetryLaterException
|
||||
{
|
||||
if (Util.isEmpty(mediaMessage.getTo())) {
|
||||
throw new UndeliverableMessageException("No destination specified");
|
||||
|
@ -103,7 +104,11 @@ public class UniversalTransport {
|
|||
return new MmsSendResult("push".getBytes("UTF-8"), 0, true);
|
||||
} catch (IOException ioe) {
|
||||
Log.w("UniversalTransport", ioe);
|
||||
return mmsTransport.deliver(mediaMessage);
|
||||
if (!GroupUtil.isEncodedGroup(mediaMessage.getTo()[0].getString())) {
|
||||
return mmsTransport.deliver(mediaMessage);
|
||||
} else {
|
||||
throw new RetryLaterException();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.w("UniversalTransport", "Delivering media message with MMS...");
|
||||
|
|
Loading…
Add table
Reference in a new issue