mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-20 14:54:09 +00:00
Add support for "delivery notifications." Currently SMS-only.
This commit is contained in:
@@ -47,6 +47,7 @@ public class SendReceiveService extends Service {
|
||||
|
||||
public static final String SEND_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_SMS_ACTION";
|
||||
public static final String SENT_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SENT_SMS_ACTION";
|
||||
public static final String DELIVERED_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DELIVERED_SMS_ACTION";
|
||||
public static final String RECEIVE_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_SMS_ACTION";
|
||||
public static final String SEND_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_ACTION";
|
||||
public static final String SEND_MMS_CONNECTIVITY_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_CONNECTIVITY_ACTION";
|
||||
@@ -93,6 +94,8 @@ public class SendReceiveService extends Service {
|
||||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(SENT_SMS_ACTION))
|
||||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(DELIVERED_SMS_ACTION))
|
||||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(SEND_MMS_ACTION) || intent.getAction().equals(SEND_MMS_CONNECTIVITY_ACTION))
|
||||
scheduleSecretRequiredIntent(SEND_MMS, intent);
|
||||
else if (intent.getAction().equals(RECEIVE_MMS_ACTION))
|
||||
@@ -191,8 +194,8 @@ public class SendReceiveService extends Service {
|
||||
|
||||
public void run() {
|
||||
switch (what) {
|
||||
case RECEIVE_SMS: smsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_SMS: smsSender.process(masterSecret, intent); return;
|
||||
case RECEIVE_SMS: smsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_SMS: smsSender.process(masterSecret, intent); return;
|
||||
case RECEIVE_MMS: mmsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_MMS: mmsSender.process(masterSecret, intent); return;
|
||||
case DOWNLOAD_MMS: mmsDownloader.process(masterSecret, intent); return;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
/**
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -10,14 +10,12 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import org.thoughtcrime.securesms.protocol.WirePrefix;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -26,6 +24,8 @@ import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.protocol.WirePrefix;
|
||||
|
||||
public class SmsListener extends BroadcastReceiver {
|
||||
|
||||
private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
|
||||
@@ -40,58 +40,58 @@ public class SmsListener extends BroadcastReceiver {
|
||||
if (messageBody.startsWith("Sparebank1://otp?")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Sprint Visual Voicemail
|
||||
return
|
||||
message.getOriginatingAddress().length() < 7 &&
|
||||
(messageBody.startsWith("//ANDROID:") || messageBody.startsWith("//Android:") ||
|
||||
return
|
||||
message.getOriginatingAddress().length() < 7 &&
|
||||
(messageBody.startsWith("//ANDROID:") || messageBody.startsWith("//Android:") ||
|
||||
messageBody.startsWith("//android:") || messageBody.startsWith("//BREW:"));
|
||||
}
|
||||
|
||||
|
||||
private SmsMessage getSmsMessageFromIntent(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
Object[] pdus = (Object[])bundle.get("pdus");
|
||||
|
||||
if (pdus == null || pdus.length == 0)
|
||||
return null;
|
||||
|
||||
|
||||
return SmsMessage.createFromPdu((byte[])pdus[0]);
|
||||
}
|
||||
|
||||
|
||||
private String getSmsMessageBodyFromIntent(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
Object[] pdus = (Object[])bundle.get("pdus");
|
||||
StringBuilder bodyBuilder = new StringBuilder();
|
||||
|
||||
|
||||
if (pdus == null)
|
||||
return null;
|
||||
|
||||
|
||||
for (int i=0;i<pdus.length;i++)
|
||||
bodyBuilder.append(SmsMessage.createFromPdu((byte[])pdus[i]).getDisplayMessageBody());
|
||||
|
||||
return bodyBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private boolean isRelevent(Context context, Intent intent) {
|
||||
SmsMessage message = getSmsMessageFromIntent(intent);
|
||||
String messageBody = getSmsMessageBodyFromIntent(intent);
|
||||
|
||||
if (message == null && messageBody == null)
|
||||
return false;
|
||||
|
||||
|
||||
if (isExemption(message, messageBody))
|
||||
return false;
|
||||
|
||||
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_all_sms", true))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
return WirePrefix.isEncryptedMessage(messageBody) || WirePrefix.isKeyExchange(messageBody);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.w("SMSListener", "Got SMS broadcast...");
|
||||
|
||||
|
||||
if (intent.getAction().equals(SMS_RECEIVED_ACTION) && isRelevent(context, intent)) {
|
||||
intent.setAction(SendReceiveService.RECEIVE_SMS_ACTION);
|
||||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
@@ -103,6 +103,10 @@ public class SmsListener extends BroadcastReceiver {
|
||||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
intent.setClass(context, SendReceiveService.class);
|
||||
context.startService(intent);
|
||||
} else if (intent.getAction().equals(SendReceiveService.DELIVERED_SMS_ACTION)) {
|
||||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
intent.setClass(context, SendReceiveService.class);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -176,10 +176,26 @@ public class SmsReceiver {
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
}
|
||||
|
||||
private void handleDeliveredMessage(Intent intent) {
|
||||
long messageId = intent.getLongExtra("message_id", -1);
|
||||
long type = intent.getLongExtra("type", -1);
|
||||
byte[] pdu = intent.getByteArrayExtra("pdu");
|
||||
String format = intent.getStringExtra("format");
|
||||
SmsMessage message = SmsMessage.createFromPdu(pdu);
|
||||
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseFactory.getSmsDatabase(context).markStatus(messageId, message.getStatus());
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
if (intent.getAction().equals(SendReceiveService.RECEIVE_SMS_ACTION))
|
||||
handleReceiveMessage(masterSecret, intent);
|
||||
else if (intent.getAction().equals(SendReceiveService.SENT_SMS_ACTION))
|
||||
handleSentMessage(intent);
|
||||
else if (intent.getAction().equals(SendReceiveService.DELIVERED_SMS_ACTION))
|
||||
handleDeliveredMessage(intent);
|
||||
}
|
||||
}
|
||||
|
@@ -21,9 +21,11 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.crypto.SessionCipher;
|
||||
@@ -111,15 +113,36 @@ public class SmsSender {
|
||||
return sentIntents;
|
||||
}
|
||||
|
||||
private ArrayList<PendingIntent> constructDeliveredIntents(long messageId, long type, ArrayList<String> messages) {
|
||||
if (!PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(ApplicationPreferencesActivity.SMS_DELIVERY_REPORT_PREF, false))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<PendingIntent> deliveredIntents = new ArrayList<PendingIntent>(messages.size());
|
||||
|
||||
for (int i=0;i<messages.size();i++) {
|
||||
Intent pending = new Intent(SendReceiveService.DELIVERED_SMS_ACTION, Uri.parse("custom://" + messageId + System.currentTimeMillis()), context, SmsListener.class);
|
||||
pending.putExtra("type", type);
|
||||
pending.putExtra("message_id", messageId);
|
||||
deliveredIntents.add(PendingIntent.getBroadcast(context, 0, pending, 0));
|
||||
}
|
||||
|
||||
return deliveredIntents;
|
||||
}
|
||||
|
||||
private void deliverGSMTransportTextMessage(String recipient, String text, long messageId, long type) {
|
||||
ArrayList<String> messages = SmsManager.getDefault().divideMessage(text);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<String> messages = SmsManager.getDefault().divideMessage(text);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<PendingIntent> deliveredIntents = constructDeliveredIntents(messageId, type, messages);
|
||||
|
||||
// XXX moxie@thoughtcrime.org 1/7/11 -- There's apparently a bug where for some unknown recipients
|
||||
// and messages, this will throw an NPE. I have no idea why, so I'm just catching it and marking
|
||||
// the message as a failure. That way at least it doesn't repeatedly crash every time you start
|
||||
// the app.
|
||||
try {
|
||||
SmsManager.getDefault().sendMultipartTextMessage(recipient, null, messages, sentIntents, null);
|
||||
SmsManager.getDefault().sendMultipartTextMessage(recipient, null, messages, sentIntents, deliveredIntents);
|
||||
} catch (NullPointerException npe) {
|
||||
Log.w("SmsSender", npe);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
@@ -142,15 +165,18 @@ public class SmsSender {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> messages = multipartMessageHandler.divideMessage(recipient, text, prefix);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<String> messages = multipartMessageHandler.divideMessage(recipient, text, prefix);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<PendingIntent> deliveredIntents = constructDeliveredIntents(messageId, type, messages);
|
||||
|
||||
for (int i=0;i<messages.size();i++) {
|
||||
// XXX moxie@thoughtcrime.org 1/7/11 -- There's apparently a bug where for some unknown recipients
|
||||
// and messages, this will throw an NPE. I have no idea why, so I'm just catching it and marking
|
||||
// the message as a failure. That way at least it doesn't repeatedly crash every time you start
|
||||
// the app.
|
||||
try {
|
||||
SmsManager.getDefault().sendTextMessage(recipient, null, messages.get(i), sentIntents.get(i), null);
|
||||
SmsManager.getDefault().sendTextMessage(recipient, null, messages.get(i), sentIntents.get(i),
|
||||
deliveredIntents == null ? null : deliveredIntents.get(i));
|
||||
} catch (NullPointerException npe) {
|
||||
Log.w("SmsSender", npe);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
|
Reference in New Issue
Block a user