mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-22 04:18:27 +00:00
Handle SMS fallback preferences correctly, and fix directory sync.
This commit is contained in:
parent
94b54a6d63
commit
9bb327db42
@ -7,11 +7,9 @@ import android.database.sqlite.SQLiteDatabase;
|
|||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.whispersystems.textsecure.push.ContactNumberDetails;
|
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||||
import org.whispersystems.textsecure.util.DirectoryUtil;
|
|
||||||
import org.whispersystems.textsecure.util.InvalidNumberException;
|
import org.whispersystems.textsecure.util.InvalidNumberException;
|
||||||
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
|
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
|
||||||
|
|
||||||
@ -19,7 +17,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class Directory {
|
public class Directory {
|
||||||
@ -66,6 +63,25 @@ public class Directory {
|
|||||||
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSmsFallbackSupported(String e164number) {
|
||||||
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
|
Cursor cursor = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
cursor = db.query(TABLE_NAME, new String[] {SUPPORTS_SMS}, NUMBER + " = ?",
|
||||||
|
new String[]{e164number}, null, null, null);
|
||||||
|
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
return cursor.getInt(0) == 1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null)
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isActiveNumber(String e164number) throws NotInDirectoryException {
|
public boolean isActiveNumber(String e164number) throws NotInDirectoryException {
|
||||||
if (e164number == null || e164number.length() == 0) {
|
if (e164number == null || e164number.length() == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -109,7 +125,7 @@ public class Directory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumber(ContactNumberDetails token, boolean active) {
|
public void setNumber(ContactTokenDetails token, boolean active) {
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(NUMBER, token.getNumber());
|
values.put(NUMBER, token.getNumber());
|
||||||
@ -120,13 +136,13 @@ public class Directory {
|
|||||||
db.replace(TABLE_NAME, null, values);
|
db.replace(TABLE_NAME, null, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumbers(List<ContactNumberDetails> activeTokens, Collection<String> inactiveTokens) {
|
public void setNumbers(List<ContactTokenDetails> activeTokens, Collection<String> inactiveTokens) {
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.beginTransaction();
|
db.beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (ContactNumberDetails token : activeTokens) {
|
for (ContactTokenDetails token : activeTokens) {
|
||||||
Log.w("Directory", "Adding active token: " + token);
|
Log.w("Directory", "Adding active token: " + token);
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(NUMBER, token.getNumber());
|
values.put(NUMBER, token.getNumber());
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.whispersystems.textsecure.push;
|
||||||
|
|
||||||
|
public class AccountAttributes {
|
||||||
|
|
||||||
|
private String signalingKey;
|
||||||
|
private boolean supportsSms;
|
||||||
|
|
||||||
|
public AccountAttributes(String signalingKey, boolean supportsSms) {
|
||||||
|
this.signalingKey = signalingKey;
|
||||||
|
this.supportsSms = supportsSms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountAttributes() {}
|
||||||
|
|
||||||
|
public String getSignalingKey() {
|
||||||
|
return signalingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupportsSms() {
|
||||||
|
return supportsSms;
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
package org.whispersystems.textsecure.push;
|
|
||||||
|
|
||||||
import com.google.thoughtcrimegson.Gson;
|
|
||||||
|
|
||||||
public abstract class ContactDetails {
|
|
||||||
|
|
||||||
private String relay;
|
|
||||||
private boolean supportsSms;
|
|
||||||
|
|
||||||
public ContactDetails() {}
|
|
||||||
|
|
||||||
public ContactDetails(String relay) {
|
|
||||||
this.relay = relay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRelay() {
|
|
||||||
return relay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRelay(String relay) {
|
|
||||||
this.relay = relay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSupportsSms() {
|
|
||||||
return supportsSms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return new Gson().toJson(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package org.whispersystems.textsecure.push;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ContactNumberDetails extends ContactDetails {
|
|
||||||
private static final String TAG = "ContactNumberDetails";
|
|
||||||
|
|
||||||
private String number;
|
|
||||||
|
|
||||||
public ContactNumberDetails() { super(); }
|
|
||||||
|
|
||||||
public ContactNumberDetails(String number) {
|
|
||||||
super();
|
|
||||||
this.number = number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactNumberDetails(String number, String relay) {
|
|
||||||
super(relay);
|
|
||||||
this.number = number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNumber() {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ContactNumberDetails> fromContactTokenDetailsList(List<ContactTokenDetails> contactTokenDetails, final Map<String, String> tokenMap) {
|
|
||||||
if (contactTokenDetails == null || tokenMap == null) return null;
|
|
||||||
|
|
||||||
List<ContactNumberDetails> contactNumberDetails = new ArrayList<ContactNumberDetails>(contactTokenDetails.size());
|
|
||||||
for (ContactTokenDetails tokenDetails : contactTokenDetails) {
|
|
||||||
if (tokenMap.containsKey(tokenDetails.getToken()))
|
|
||||||
contactNumberDetails.add(new ContactNumberDetails(tokenMap.get(tokenDetails.getToken()), tokenDetails.getRelay()));
|
|
||||||
else
|
|
||||||
Log.w(TAG, "tokenMap was missing a contact.");
|
|
||||||
}
|
|
||||||
return contactNumberDetails;
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,24 +2,32 @@ package org.whispersystems.textsecure.push;
|
|||||||
|
|
||||||
import com.google.thoughtcrimegson.Gson;
|
import com.google.thoughtcrimegson.Gson;
|
||||||
|
|
||||||
public class ContactTokenDetails extends ContactDetails {
|
public class ContactTokenDetails {
|
||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
|
private String relay;
|
||||||
|
private String number;
|
||||||
|
private boolean supportsSms;
|
||||||
|
|
||||||
public ContactTokenDetails() { super(); }
|
public ContactTokenDetails() {}
|
||||||
|
|
||||||
public ContactTokenDetails(String token) {
|
|
||||||
super();
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactTokenDetails(String token, String relay) {
|
|
||||||
super(relay);
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRelay() {
|
||||||
|
return relay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupportsSms() {
|
||||||
|
return supportsSms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(String number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,10 @@ public class PushServiceSocket {
|
|||||||
makeRequest(String.format(path, localNumber), "GET", null);
|
makeRequest(String.format(path, localNumber), "GET", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyAccount(String verificationCode, String signalingKey) throws IOException {
|
public void verifyAccount(String verificationCode, String signalingKey, boolean supportsSms)
|
||||||
SignalingKey signalingKeyEntity = new SignalingKey(signalingKey);
|
throws IOException
|
||||||
|
{
|
||||||
|
AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, supportsSms);
|
||||||
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode),
|
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode),
|
||||||
"PUT", new Gson().toJson(signalingKeyEntity));
|
"PUT", new Gson().toJson(signalingKeyEntity));
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package org.whispersystems.textsecure.push;
|
|
||||||
|
|
||||||
public class SignalingKey {
|
|
||||||
|
|
||||||
private String signalingKey;
|
|
||||||
|
|
||||||
public SignalingKey(String signalingKey) {
|
|
||||||
this.signalingKey = signalingKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignalingKey() {}
|
|
||||||
|
|
||||||
public String getSignalingKey() {
|
|
||||||
return signalingKey;
|
|
||||||
}
|
|
||||||
}
|
|
@ -501,7 +501,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
|||||||
protected Integer doInBackground(Void... params) {
|
protected Integer doInBackground(Void... params) {
|
||||||
try {
|
try {
|
||||||
PushServiceSocket socket = PushServiceSocketFactory.create(context, e164number, password);
|
PushServiceSocket socket = PushServiceSocketFactory.create(context, e164number, password);
|
||||||
socket.verifyAccount(code, signalingKey);
|
socket.verifyAccount(code, signalingKey, true);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
} catch (RateLimitException e) {
|
} catch (RateLimitException e) {
|
||||||
Log.w("RegistrationProgressActivity", e);
|
Log.w("RegistrationProgressActivity", e);
|
||||||
|
@ -6,7 +6,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.google.android.gcm.GCMBaseIntentService;
|
import com.google.android.gcm.GCMBaseIntentService;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.Release;
|
|
||||||
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
||||||
import org.thoughtcrime.securesms.service.RegistrationService;
|
import org.thoughtcrime.securesms.service.RegistrationService;
|
||||||
import org.thoughtcrime.securesms.service.SendReceiveService;
|
import org.thoughtcrime.securesms.service.SendReceiveService;
|
||||||
@ -14,7 +13,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||||||
import org.whispersystems.textsecure.crypto.InvalidVersionException;
|
import org.whispersystems.textsecure.crypto.InvalidVersionException;
|
||||||
import org.whispersystems.textsecure.directory.Directory;
|
import org.whispersystems.textsecure.directory.Directory;
|
||||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||||
import org.whispersystems.textsecure.push.ContactNumberDetails;
|
|
||||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||||
import org.whispersystems.textsecure.push.IncomingEncryptedPushMessage;
|
import org.whispersystems.textsecure.push.IncomingEncryptedPushMessage;
|
||||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
||||||
@ -69,9 +67,10 @@ public class GcmIntentService extends GCMBaseIntentService {
|
|||||||
|
|
||||||
if (!isActiveNumber(context, message.getSource())) {
|
if (!isActiveNumber(context, message.getSource())) {
|
||||||
Directory directory = Directory.getInstance(context);
|
Directory directory = Directory.getInstance(context);
|
||||||
String contactNumber = message.getSource();
|
ContactTokenDetails contactTokenDetails = new ContactTokenDetails();
|
||||||
ContactNumberDetails contactNumberDetails = new ContactNumberDetails(contactNumber, message.getRelay());
|
contactTokenDetails.setNumber(message.getSource());
|
||||||
directory.setNumber(contactNumberDetails, true);
|
|
||||||
|
directory.setNumber(contactTokenDetails, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent service = new Intent(context, SendReceiveService.class);
|
Intent service = new Intent(context, SendReceiveService.class);
|
||||||
|
@ -242,7 +242,7 @@ public class RegistrationService extends Service {
|
|||||||
|
|
||||||
setState(new RegistrationState(RegistrationState.STATE_VERIFYING, number));
|
setState(new RegistrationState(RegistrationState.STATE_VERIFYING, number));
|
||||||
String challenge = waitForChallenge();
|
String challenge = waitForChallenge();
|
||||||
socket.verifyAccount(challenge, signalingKey);
|
socket.verifyAccount(challenge, signalingKey, true);
|
||||||
|
|
||||||
handleCommonRegistration(masterSecret, socket, number);
|
handleCommonRegistration(masterSecret, socket, number);
|
||||||
markAsVerified(number, password, signalingKey);
|
markAsVerified(number, password, signalingKey);
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
package org.thoughtcrime.securesms.service;
|
package org.thoughtcrime.securesms.service;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.telephony.SmsManager;
|
import android.telephony.SmsManager;
|
||||||
@ -31,12 +33,11 @@ import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
|||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler;
|
import org.thoughtcrime.securesms.service.SendReceiveService.ToastHandler;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage;
|
import org.thoughtcrime.securesms.sms.IncomingIdentityUpdateMessage;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||||
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
import org.thoughtcrime.securesms.transport.UniversalTransport;
|
||||||
import org.thoughtcrime.securesms.transport.UntrustedIdentityException;
|
import org.thoughtcrime.securesms.transport.UntrustedIdentityException;
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
import org.whispersystems.textsecure.util.Base64;
|
|
||||||
|
|
||||||
public class SmsSender {
|
public class SmsSender {
|
||||||
|
|
||||||
@ -87,6 +88,10 @@ public class SmsSender {
|
|||||||
} catch (UndeliverableMessageException ude) {
|
} catch (UndeliverableMessageException ude) {
|
||||||
Log.w("SmsSender", ude);
|
Log.w("SmsSender", ude);
|
||||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||||
|
} catch (RetryLaterException rle) {
|
||||||
|
Log.w("SmsSender", rle);
|
||||||
|
if (systemStateListener.isConnected()) scheduleQuickRetryAlarm();
|
||||||
|
else systemStateListener.registerForConnectivityChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -140,10 +145,20 @@ public class SmsSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerForRadioChanges() {
|
private void registerForRadioChanges() {
|
||||||
systemStateListener.registerForConnectivityChange();
|
if (systemStateListener.isConnected()) systemStateListener.registerForRadioChange();
|
||||||
|
else systemStateListener.registerForConnectivityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregisterForRadioChanges() {
|
private void unregisterForRadioChanges() {
|
||||||
systemStateListener.unregisterForConnectivityChange();
|
systemStateListener.unregisterForConnectivityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_SMS_ACTION,
|
||||||
|
null, context, SendReceiveService.class),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,15 @@ public class SystemStateListener {
|
|||||||
this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerForRadioChange() {
|
||||||
|
Log.w("SystemStateListener", "Registering for radio changes...");
|
||||||
|
unregisterForConnectivityChange();
|
||||||
|
|
||||||
|
telephonyManager.listen(telephonyListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||||
|
}
|
||||||
|
|
||||||
public void registerForConnectivityChange() {
|
public void registerForConnectivityChange() {
|
||||||
|
Log.w("SystemStateListener", "Registering for any connectivity changes...");
|
||||||
unregisterForConnectivityChange();
|
unregisterForConnectivityChange();
|
||||||
|
|
||||||
telephonyManager.listen(telephonyListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
telephonyManager.listen(telephonyListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||||
@ -63,6 +71,7 @@ public class SystemStateListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onServiceStateChanged(ServiceState state) {
|
public void onServiceStateChanged(ServiceState state) {
|
||||||
if (state.getState() == ServiceState.STATE_IN_SERVICE) {
|
if (state.getState() == ServiceState.STATE_IN_SERVICE) {
|
||||||
|
Log.w("SystemStateListener", "In service, sending sms/mms outboxes...");
|
||||||
sendSmsOutbox(context);
|
sendSmsOutbox(context);
|
||||||
sendMmsOutbox(context);
|
sendMmsOutbox(context);
|
||||||
}
|
}
|
||||||
@ -76,6 +85,7 @@ public class SystemStateListener {
|
|||||||
if (connectivityManager.getActiveNetworkInfo() != null &&
|
if (connectivityManager.getActiveNetworkInfo() != null &&
|
||||||
connectivityManager.getActiveNetworkInfo().isConnected())
|
connectivityManager.getActiveNetworkInfo().isConnected())
|
||||||
{
|
{
|
||||||
|
Log.w("SystemStateListener", "Got connectivity action: " + intent.toString());
|
||||||
sendSmsOutbox(context);
|
sendSmsOutbox(context);
|
||||||
sendMmsOutbox(context);
|
sendMmsOutbox(context);
|
||||||
}
|
}
|
||||||
|
@ -91,11 +91,6 @@ public class PushTransport extends BaseTransport {
|
|||||||
|
|
||||||
context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType(), true));
|
context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType(), true));
|
||||||
|
|
||||||
} catch (UnregisteredUserException e) {
|
|
||||||
Log.w("PushTransport", e);
|
|
||||||
//TODO We should probably remove the user from the directory?
|
|
||||||
// destroySessions(message.getIndividualRecipient());
|
|
||||||
throw new IOException("Not push registered after all.");
|
|
||||||
} catch (InvalidNumberException e) {
|
} catch (InvalidNumberException e) {
|
||||||
Log.w("PushTransport", e);
|
Log.w("PushTransport", e);
|
||||||
throw new IOException("Badly formatted number.");
|
throw new IOException("Badly formatted number.");
|
||||||
|
@ -24,8 +24,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.service.SendReceiveService;
|
|
||||||
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
|
|
||||||
import org.thoughtcrime.securesms.sms.MultipartSmsMessageHandler;
|
import org.thoughtcrime.securesms.sms.MultipartSmsMessageHandler;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingPrekeyBundleMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingPrekeyBundleMessage;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||||
|
@ -33,13 +33,9 @@ import org.thoughtcrime.securesms.util.Util;
|
|||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
import org.whispersystems.textsecure.directory.Directory;
|
import org.whispersystems.textsecure.directory.Directory;
|
||||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||||
import org.whispersystems.textsecure.push.ContactNumberDetails;
|
|
||||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
|
||||||
import org.whispersystems.textsecure.push.PushMessageProtos;
|
|
||||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||||
import org.whispersystems.textsecure.push.UnregisteredUserException;
|
import org.whispersystems.textsecure.push.UnregisteredUserException;
|
||||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
|
||||||
import org.whispersystems.textsecure.util.DirectoryUtil;
|
import org.whispersystems.textsecure.util.DirectoryUtil;
|
||||||
import org.whispersystems.textsecure.util.InvalidNumberException;
|
import org.whispersystems.textsecure.util.InvalidNumberException;
|
||||||
|
|
||||||
@ -47,8 +43,6 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import ws.com.google.android.mms.pdu.SendReq;
|
import ws.com.google.android.mms.pdu.SendReq;
|
||||||
|
|
||||||
import static org.whispersystems.textsecure.push.PushMessageProtos.IncomingPushMessageSignal;
|
|
||||||
|
|
||||||
public class UniversalTransport {
|
public class UniversalTransport {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
@ -66,7 +60,7 @@ public class UniversalTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deliver(SmsMessageRecord message)
|
public void deliver(SmsMessageRecord message)
|
||||||
throws UndeliverableMessageException, UntrustedIdentityException
|
throws UndeliverableMessageException, UntrustedIdentityException, RetryLaterException
|
||||||
{
|
{
|
||||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||||
smsTransport.deliver(message);
|
smsTransport.deliver(message);
|
||||||
@ -78,12 +72,19 @@ public class UniversalTransport {
|
|||||||
String number = Util.canonicalizeNumber(context, recipient.getNumber());
|
String number = Util.canonicalizeNumber(context, recipient.getNumber());
|
||||||
|
|
||||||
if (isPushTransport(number)) {
|
if (isPushTransport(number)) {
|
||||||
|
boolean isSmsFallbackSupported = isSmsFallbackSupported(number);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.w("UniversalTransport", "Delivering with GCM...");
|
Log.w("UniversalTransport", "Delivering with GCM...");
|
||||||
pushTransport.deliver(message);
|
pushTransport.deliver(message);
|
||||||
|
} catch (UnregisteredUserException uue) {
|
||||||
|
Log.w("UnviersalTransport", uue);
|
||||||
|
if (isSmsFallbackSupported) smsTransport.deliver(message);
|
||||||
|
else throw new UndeliverableMessageException(uue);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.w("UniversalTransport", ioe);
|
Log.w("UniversalTransport", ioe);
|
||||||
smsTransport.deliver(message);
|
if (isSmsFallbackSupported) smsTransport.deliver(message);
|
||||||
|
else throw new RetryLaterException(ioe);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w("UniversalTransport", "Delivering with SMS...");
|
Log.w("UniversalTransport", "Delivering with SMS...");
|
||||||
@ -118,20 +119,25 @@ public class UniversalTransport {
|
|||||||
String destination = Util.canonicalizeNumber(context, mediaMessage.getTo()[0].getString());
|
String destination = Util.canonicalizeNumber(context, mediaMessage.getTo()[0].getString());
|
||||||
|
|
||||||
if (isPushTransport(destination)) {
|
if (isPushTransport(destination)) {
|
||||||
|
boolean isSmsFallbackSupported = isSmsFallbackSupported(destination);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.w("UniversalTransport", "Delivering media message with GCM...");
|
Log.w("UniversalTransport", "Delivering media message with GCM...");
|
||||||
pushTransport.deliver(mediaMessage, threadId);
|
pushTransport.deliver(mediaMessage, threadId);
|
||||||
return new MmsSendResult("push".getBytes("UTF-8"), 0, true);
|
return new MmsSendResult("push".getBytes("UTF-8"), 0, true);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.w("UniversalTransport", ioe);
|
Log.w("UniversalTransport", ioe);
|
||||||
return mmsTransport.deliver(mediaMessage);
|
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
|
||||||
|
else throw new RetryLaterException(ioe);
|
||||||
} catch (RecipientFormattingException e) {
|
} catch (RecipientFormattingException e) {
|
||||||
Log.w("UniversalTransport", e);
|
Log.w("UniversalTransport", e);
|
||||||
return mmsTransport.deliver(mediaMessage);
|
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
|
||||||
|
else throw new UndeliverableMessageException(e);
|
||||||
} catch (EncapsulatedExceptions ee) {
|
} catch (EncapsulatedExceptions ee) {
|
||||||
Log.w("UniversalTransport", ee);
|
Log.w("UniversalTransport", ee);
|
||||||
if (!ee.getUnregisteredUserExceptions().isEmpty()) {
|
if (!ee.getUnregisteredUserExceptions().isEmpty()) {
|
||||||
return mmsTransport.deliver(mediaMessage);
|
if (isSmsFallbackSupported) return mmsTransport.deliver(mediaMessage);
|
||||||
|
else throw new UndeliverableMessageException(ee);
|
||||||
} else {
|
} else {
|
||||||
throw new UntrustedIdentityException(ee.getUntrustedIdentityExceptions().get(0));
|
throw new UntrustedIdentityException(ee.getUntrustedIdentityExceptions().get(0));
|
||||||
}
|
}
|
||||||
@ -203,6 +209,15 @@ public class UniversalTransport {
|
|||||||
return recipientCount > 1;
|
return recipientCount > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isSmsFallbackSupported(String destination) {
|
||||||
|
if (GroupUtil.isEncodedGroup(destination)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory directory = Directory.getInstance(context);
|
||||||
|
return directory.isSmsFallbackSupported(destination);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isPushTransport(String destination) {
|
private boolean isPushTransport(String destination) {
|
||||||
if (GroupUtil.isEncodedGroup(destination)) {
|
if (GroupUtil.isEncodedGroup(destination)) {
|
||||||
return true;
|
return true;
|
||||||
@ -215,12 +230,19 @@ public class UniversalTransport {
|
|||||||
} catch (NotInDirectoryException e) {
|
} catch (NotInDirectoryException e) {
|
||||||
try {
|
try {
|
||||||
PushServiceSocket socket = PushServiceSocketFactory.create(context);
|
PushServiceSocket socket = PushServiceSocketFactory.create(context);
|
||||||
ContactTokenDetails registeredUser = socket.getContactTokenDetails(DirectoryUtil.getDirectoryServerToken(destination));
|
String contactToken = DirectoryUtil.getDirectoryServerToken(destination);
|
||||||
boolean registeredFound = !(registeredUser == null);
|
ContactTokenDetails registeredUser = socket.getContactTokenDetails(contactToken);
|
||||||
ContactNumberDetails numberDetails = new ContactNumberDetails(destination, registeredUser == null ? null : registeredUser.getRelay());
|
|
||||||
|
|
||||||
directory.setNumber(numberDetails, registeredFound);
|
if (registeredUser == null) {
|
||||||
return registeredFound;
|
registeredUser = new ContactTokenDetails();
|
||||||
|
registeredUser.setNumber(destination);
|
||||||
|
directory.setNumber(registeredUser, false);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
registeredUser.setNumber(destination);
|
||||||
|
directory.setNumber(registeredUser, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
Log.w("UniversalTransport", e1);
|
Log.w("UniversalTransport", e1);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package org.thoughtcrime.securesms.util;
|
package org.thoughtcrime.securesms.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
|
||||||
import org.whispersystems.textsecure.directory.Directory;
|
import org.whispersystems.textsecure.directory.Directory;
|
||||||
import org.whispersystems.textsecure.push.ContactNumberDetails;
|
|
||||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||||
import org.whispersystems.textsecure.util.DirectoryUtil;
|
import org.whispersystems.textsecure.util.DirectoryUtil;
|
||||||
@ -24,20 +24,19 @@ public class DirectoryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void refreshDirectory(final Context context, final PushServiceSocket socket, final String localNumber) {
|
public static void refreshDirectory(final Context context, final PushServiceSocket socket, final String localNumber) {
|
||||||
final Directory directory = Directory.getInstance(context);
|
Directory directory = Directory.getInstance(context);
|
||||||
|
Set<String> eligibleContactNumbers = directory.getPushEligibleContactNumbers(localNumber);
|
||||||
|
Map<String, String> tokenMap = DirectoryUtil.getDirectoryServerTokenMap(eligibleContactNumbers);
|
||||||
|
List<ContactTokenDetails> activeTokens = socket.retrieveDirectory(tokenMap.keySet());
|
||||||
|
|
||||||
final Set<String> eligibleContactNumbers = directory.getPushEligibleContactNumbers(localNumber);
|
|
||||||
|
|
||||||
final Map<String, String> tokenMap = DirectoryUtil.getDirectoryServerTokenMap(eligibleContactNumbers);
|
|
||||||
final List<ContactTokenDetails> activeTokens = socket.retrieveDirectory(tokenMap.keySet());
|
|
||||||
|
|
||||||
if (activeTokens != null) {
|
if (activeTokens != null) {
|
||||||
final List<ContactNumberDetails> activeNumbers = ContactNumberDetails.fromContactTokenDetailsList(activeTokens, tokenMap);
|
|
||||||
for (ContactTokenDetails activeToken : activeTokens) {
|
for (ContactTokenDetails activeToken : activeTokens) {
|
||||||
eligibleContactNumbers.remove(tokenMap.get(activeToken.getToken()));
|
eligibleContactNumbers.remove(tokenMap.get(activeToken.getToken()));
|
||||||
|
activeToken.setNumber(tokenMap.get(activeToken.getToken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
directory.setNumbers(activeNumbers, eligibleContactNumbers);
|
directory.setNumbers(activeTokens, eligibleContactNumbers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user