mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Support for server federation.
This commit is contained in:
parent
25a2ad7289
commit
fa5ccc3f8a
@ -6,9 +6,10 @@ option java_outer_classname = "PushMessageProtos";
|
||||
message IncomingPushMessageSignal {
|
||||
optional uint32 type = 1;
|
||||
optional string source = 2;
|
||||
repeated string destinations = 3;
|
||||
optional uint64 timestamp = 4;
|
||||
optional bytes message = 5; // Contains an encrypted IncomingPushMessageContent
|
||||
optional string relay = 3;
|
||||
repeated string destinations = 4;
|
||||
optional uint64 timestamp = 5;
|
||||
optional bytes message = 6; // Contains an encrypted PushMessageContent
|
||||
}
|
||||
|
||||
message PushMessageContent {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.whispersystems.textsecure;
|
||||
|
||||
public class Release {
|
||||
public static final String PUSH_SERVICE_URL = "https://gcm.textsecure.whispersystems.org";
|
||||
public static final String PUSH_SERVICE_URL = "https://federated.textsecure.whispersystems.org";
|
||||
// public static final String PUSH_SERVICE_URL = "http://192.168.1.135:8080";
|
||||
public static final boolean ENFORCE_SSL = true;
|
||||
}
|
||||
|
@ -132,6 +132,9 @@ public class PreKeyUtil {
|
||||
private static class PreKeyRecordIdComparator implements Comparator<String> {
|
||||
@Override
|
||||
public int compare(String lhs, String rhs) {
|
||||
if (lhs.equals(PreKeyIndex.FILE_NAME)) return -1;
|
||||
else if (rhs.equals(PreKeyIndex.FILE_NAME)) return 1;
|
||||
|
||||
try {
|
||||
long lhsLong = Long.parseLong(lhs);
|
||||
long rhsLong = Long.parseLong(rhs);
|
||||
|
@ -9,6 +9,7 @@ import android.net.Uri;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.util.Log;
|
||||
|
||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
|
||||
import org.whispersystems.textsecure.util.Util;
|
||||
@ -29,11 +30,15 @@ public class Directory {
|
||||
private static final String ID = "_id";
|
||||
private static final String TOKEN = "token";
|
||||
private static final String REGISTERED = "registered";
|
||||
private static final String RELAY = "relay";
|
||||
private static final String SUPPORTS_SMS = "supports_sms";
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY, " +
|
||||
TOKEN + " TEXT UNIQUE, " + REGISTERED + " INTEGER, " +
|
||||
SUPPORTS_SMS + " INTEGER, " + TIMESTAMP + " INTEGER);";
|
||||
TOKEN + " TEXT UNIQUE, " +
|
||||
REGISTERED + " INTEGER, " +
|
||||
RELAY + " TEXT " +
|
||||
SUPPORTS_SMS + " INTEGER, " +
|
||||
TIMESTAMP + " INTEGER);";
|
||||
|
||||
private static Directory instance;
|
||||
|
||||
@ -79,27 +84,49 @@ public class Directory {
|
||||
}
|
||||
}
|
||||
|
||||
public void setToken(String token, boolean active) {
|
||||
public String getRelay(String e164number) {
|
||||
String token = getToken(e164number);
|
||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, null, TOKEN + " = ?", new String[]{token}, null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getString(cursor.getColumnIndexOrThrow(RELAY));
|
||||
}
|
||||
|
||||
return null;
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setToken(ContactTokenDetails token, boolean active) {
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(TOKEN, token);
|
||||
values.put(TOKEN, token.getToken());
|
||||
values.put(RELAY, token.getRelay());
|
||||
values.put(REGISTERED, active ? 1 : 0);
|
||||
values.put(SUPPORTS_SMS, token.isSupportsSms());
|
||||
values.put(TIMESTAMP, System.currentTimeMillis());
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public void setTokens(List<String> activeTokens, Collection<String> inactiveTokens) {
|
||||
public void setTokens(List<ContactTokenDetails> activeTokens, Collection<String> inactiveTokens) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
|
||||
try {
|
||||
for (String token : activeTokens) {
|
||||
for (ContactTokenDetails token : activeTokens) {
|
||||
Log.w("Directory", "Adding active token: " + token);
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(TOKEN, token);
|
||||
values.put(TOKEN, token.getToken());
|
||||
values.put(REGISTERED, 1);
|
||||
values.put(TIMESTAMP, timestamp);
|
||||
values.put(RELAY, token.getRelay());
|
||||
db.replace(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
@ -125,7 +152,7 @@ public class Directory {
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, new String[] {Phone.NUMBER}, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String rawNumber = cursor.getString(0);
|
||||
|
||||
if (rawNumber != null) {
|
||||
@ -134,12 +161,13 @@ public class Directory {
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
|
||||
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {TOKEN},
|
||||
null, null, null, null, null);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
results.add(cursor.getString(0));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
package org.whispersystems.textsecure.push;
|
||||
|
||||
import com.google.thoughtcrimegson.Gson;
|
||||
|
||||
public class ContactTokenDetails {
|
||||
|
||||
private String token;
|
||||
private String relay;
|
||||
private boolean supportsSms;
|
||||
|
||||
public ContactTokenDetails() {}
|
||||
|
||||
public ContactTokenDetails(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public ContactTokenDetails(String token, String relay) {
|
||||
this.token = token;
|
||||
this.relay = relay;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package org.whispersystems.textsecure.push;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContactTokenDetailsList {
|
||||
|
||||
private List<ContactTokenDetails> contacts;
|
||||
|
||||
public ContactTokenDetailsList() {}
|
||||
|
||||
public List<ContactTokenDetails> getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
}
|
@ -43,14 +43,16 @@ public class IncomingPushMessage implements PushMessage, Parcelable {
|
||||
private List<String> destinations;
|
||||
private byte[] message;
|
||||
private long timestamp;
|
||||
private String relay;
|
||||
|
||||
private IncomingPushMessage(IncomingPushMessage message, byte[] body) {
|
||||
this.type = message.type;
|
||||
this.source = message.source;
|
||||
this.timestamp = message.timestamp;
|
||||
this.relay = message.relay;
|
||||
this.message = body;
|
||||
this.destinations = new LinkedList<String>();
|
||||
this.destinations.addAll(message.destinations);
|
||||
this.message = body;
|
||||
this.timestamp = message.timestamp;
|
||||
}
|
||||
|
||||
public IncomingPushMessage(IncomingPushMessageSignal signal) {
|
||||
@ -59,12 +61,18 @@ public class IncomingPushMessage implements PushMessage, Parcelable {
|
||||
this.destinations = signal.getDestinationsList();
|
||||
this.message = signal.getMessage().toByteArray();
|
||||
this.timestamp = signal.getTimestamp();
|
||||
this.relay = signal.getRelay();
|
||||
}
|
||||
|
||||
public IncomingPushMessage(Parcel in) {
|
||||
this.destinations = new LinkedList<String>();
|
||||
this.type = in.readInt();
|
||||
this.source = in.readString();
|
||||
|
||||
if (in.readInt() == 1) {
|
||||
this.relay = in.readString();
|
||||
}
|
||||
|
||||
in.readStringList(destinations);
|
||||
this.message = new byte[in.readInt()];
|
||||
in.readByteArray(this.message);
|
||||
@ -82,6 +90,10 @@ public class IncomingPushMessage implements PushMessage, Parcelable {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getRelay() {
|
||||
return relay;
|
||||
}
|
||||
|
||||
public long getTimestampMillis() {
|
||||
return timestamp;
|
||||
}
|
||||
@ -107,6 +119,10 @@ public class IncomingPushMessage implements PushMessage, Parcelable {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(type);
|
||||
dest.writeString(source);
|
||||
dest.writeInt(relay == null ? 0 : 1);
|
||||
if (relay != null) {
|
||||
dest.writeString(relay);
|
||||
}
|
||||
dest.writeStringList(destinations);
|
||||
dest.writeInt(message.length);
|
||||
dest.writeByteArray(message);
|
||||
|
@ -23,8 +23,14 @@ public class OutgoingPushMessage implements PushMessage {
|
||||
private int type;
|
||||
private String destination;
|
||||
private String body;
|
||||
private String relay;
|
||||
|
||||
public OutgoingPushMessage(String destination, byte[] body, int type) {
|
||||
this(null, destination, body, type);
|
||||
}
|
||||
|
||||
public OutgoingPushMessage(String relay, String destination, byte[] body, int type) {
|
||||
this.relay = relay;
|
||||
this.destination = destination;
|
||||
this.body = Base64.encodeBytes(body);
|
||||
this.type = type;
|
||||
@ -41,4 +47,8 @@ public class OutgoingPushMessage implements PushMessage {
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getRelay() {
|
||||
return relay;
|
||||
}
|
||||
}
|
||||
|
@ -19,16 +19,20 @@ public final class PushMessageProtos {
|
||||
boolean hasSource();
|
||||
String getSource();
|
||||
|
||||
// repeated string destinations = 3;
|
||||
// optional string relay = 3;
|
||||
boolean hasRelay();
|
||||
String getRelay();
|
||||
|
||||
// repeated string destinations = 4;
|
||||
java.util.List<String> getDestinationsList();
|
||||
int getDestinationsCount();
|
||||
String getDestinations(int index);
|
||||
|
||||
// optional uint64 timestamp = 4;
|
||||
// optional uint64 timestamp = 5;
|
||||
boolean hasTimestamp();
|
||||
long getTimestamp();
|
||||
|
||||
// optional bytes message = 5;
|
||||
// optional bytes message = 6;
|
||||
boolean hasMessage();
|
||||
com.google.protobuf.ByteString getMessage();
|
||||
}
|
||||
@ -103,8 +107,40 @@ public final class PushMessageProtos {
|
||||
}
|
||||
}
|
||||
|
||||
// repeated string destinations = 3;
|
||||
public static final int DESTINATIONS_FIELD_NUMBER = 3;
|
||||
// optional string relay = 3;
|
||||
public static final int RELAY_FIELD_NUMBER = 3;
|
||||
private java.lang.Object relay_;
|
||||
public boolean hasRelay() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public String getRelay() {
|
||||
java.lang.Object ref = relay_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
if (com.google.protobuf.Internal.isValidUtf8(bs)) {
|
||||
relay_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
private com.google.protobuf.ByteString getRelayBytes() {
|
||||
java.lang.Object ref = relay_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8((String) ref);
|
||||
relay_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// repeated string destinations = 4;
|
||||
public static final int DESTINATIONS_FIELD_NUMBER = 4;
|
||||
private com.google.protobuf.LazyStringList destinations_;
|
||||
public java.util.List<String>
|
||||
getDestinationsList() {
|
||||
@ -117,21 +153,21 @@ public final class PushMessageProtos {
|
||||
return destinations_.get(index);
|
||||
}
|
||||
|
||||
// optional uint64 timestamp = 4;
|
||||
public static final int TIMESTAMP_FIELD_NUMBER = 4;
|
||||
// optional uint64 timestamp = 5;
|
||||
public static final int TIMESTAMP_FIELD_NUMBER = 5;
|
||||
private long timestamp_;
|
||||
public boolean hasTimestamp() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return timestamp_;
|
||||
}
|
||||
|
||||
// optional bytes message = 5;
|
||||
public static final int MESSAGE_FIELD_NUMBER = 5;
|
||||
// optional bytes message = 6;
|
||||
public static final int MESSAGE_FIELD_NUMBER = 6;
|
||||
private com.google.protobuf.ByteString message_;
|
||||
public boolean hasMessage() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
public com.google.protobuf.ByteString getMessage() {
|
||||
return message_;
|
||||
@ -140,6 +176,7 @@ public final class PushMessageProtos {
|
||||
private void initFields() {
|
||||
type_ = 0;
|
||||
source_ = "";
|
||||
relay_ = "";
|
||||
destinations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
timestamp_ = 0L;
|
||||
message_ = com.google.protobuf.ByteString.EMPTY;
|
||||
@ -162,14 +199,17 @@ public final class PushMessageProtos {
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeBytes(2, getSourceBytes());
|
||||
}
|
||||
for (int i = 0; i < destinations_.size(); i++) {
|
||||
output.writeBytes(3, destinations_.getByteString(i));
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeUInt64(4, timestamp_);
|
||||
output.writeBytes(3, getRelayBytes());
|
||||
}
|
||||
for (int i = 0; i < destinations_.size(); i++) {
|
||||
output.writeBytes(4, destinations_.getByteString(i));
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeBytes(5, message_);
|
||||
output.writeUInt64(5, timestamp_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeBytes(6, message_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
@ -188,6 +228,10 @@ public final class PushMessageProtos {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(2, getSourceBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(3, getRelayBytes());
|
||||
}
|
||||
{
|
||||
int dataSize = 0;
|
||||
for (int i = 0; i < destinations_.size(); i++) {
|
||||
@ -197,13 +241,13 @@ public final class PushMessageProtos {
|
||||
size += dataSize;
|
||||
size += 1 * getDestinationsList().size();
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeUInt64Size(4, timestamp_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(5, message_);
|
||||
.computeUInt64Size(5, timestamp_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(6, message_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
@ -333,12 +377,14 @@ public final class PushMessageProtos {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
source_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
destinations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
relay_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
timestamp_ = 0L;
|
||||
destinations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
message_ = com.google.protobuf.ByteString.EMPTY;
|
||||
timestamp_ = 0L;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
message_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -385,19 +431,23 @@ public final class PushMessageProtos {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.source_ = source_;
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
destinations_ = new com.google.protobuf.UnmodifiableLazyStringList(
|
||||
destinations_);
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
}
|
||||
result.destinations_ = destinations_;
|
||||
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.timestamp_ = timestamp_;
|
||||
result.relay_ = relay_;
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
destinations_ = new com.google.protobuf.UnmodifiableLazyStringList(
|
||||
destinations_);
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
}
|
||||
result.destinations_ = destinations_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.timestamp_ = timestamp_;
|
||||
if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.message_ = message_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
@ -421,10 +471,13 @@ public final class PushMessageProtos {
|
||||
if (other.hasSource()) {
|
||||
setSource(other.getSource());
|
||||
}
|
||||
if (other.hasRelay()) {
|
||||
setRelay(other.getRelay());
|
||||
}
|
||||
if (!other.destinations_.isEmpty()) {
|
||||
if (destinations_.isEmpty()) {
|
||||
destinations_ = other.destinations_;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
} else {
|
||||
ensureDestinationsIsMutable();
|
||||
destinations_.addAll(other.destinations_);
|
||||
@ -479,17 +532,22 @@ public final class PushMessageProtos {
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
bitField0_ |= 0x00000004;
|
||||
relay_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
ensureDestinationsIsMutable();
|
||||
destinations_.add(input.readBytes());
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
bitField0_ |= 0x00000008;
|
||||
case 40: {
|
||||
bitField0_ |= 0x00000010;
|
||||
timestamp_ = input.readUInt64();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
bitField0_ |= 0x00000010;
|
||||
case 50: {
|
||||
bitField0_ |= 0x00000020;
|
||||
message_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
@ -556,12 +614,48 @@ public final class PushMessageProtos {
|
||||
onChanged();
|
||||
}
|
||||
|
||||
// repeated string destinations = 3;
|
||||
// optional string relay = 3;
|
||||
private java.lang.Object relay_ = "";
|
||||
public boolean hasRelay() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public String getRelay() {
|
||||
java.lang.Object ref = relay_;
|
||||
if (!(ref instanceof String)) {
|
||||
String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
|
||||
relay_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
public Builder setRelay(String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000004;
|
||||
relay_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearRelay() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
relay_ = getDefaultInstance().getRelay();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
void setRelay(com.google.protobuf.ByteString value) {
|
||||
bitField0_ |= 0x00000004;
|
||||
relay_ = value;
|
||||
onChanged();
|
||||
}
|
||||
|
||||
// repeated string destinations = 4;
|
||||
private com.google.protobuf.LazyStringList destinations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
private void ensureDestinationsIsMutable() {
|
||||
if (!((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
if (!((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
destinations_ = new com.google.protobuf.LazyStringArrayList(destinations_);
|
||||
bitField0_ |= 0x00000004;
|
||||
bitField0_ |= 0x00000008;
|
||||
}
|
||||
}
|
||||
public java.util.List<String>
|
||||
@ -602,7 +696,7 @@ public final class PushMessageProtos {
|
||||
}
|
||||
public Builder clearDestinations() {
|
||||
destinations_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@ -612,31 +706,31 @@ public final class PushMessageProtos {
|
||||
onChanged();
|
||||
}
|
||||
|
||||
// optional uint64 timestamp = 4;
|
||||
// optional uint64 timestamp = 5;
|
||||
private long timestamp_ ;
|
||||
public boolean hasTimestamp() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return timestamp_;
|
||||
}
|
||||
public Builder setTimestamp(long value) {
|
||||
bitField0_ |= 0x00000008;
|
||||
bitField0_ |= 0x00000010;
|
||||
timestamp_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearTimestamp() {
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
timestamp_ = 0L;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes message = 5;
|
||||
// optional bytes message = 6;
|
||||
private com.google.protobuf.ByteString message_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasMessage() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
return ((bitField0_ & 0x00000020) == 0x00000020);
|
||||
}
|
||||
public com.google.protobuf.ByteString getMessage() {
|
||||
return message_;
|
||||
@ -645,13 +739,13 @@ public final class PushMessageProtos {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
message_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearMessage() {
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
message_ = getDefaultInstance().getMessage();
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1833,15 +1927,16 @@ public final class PushMessageProtos {
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\037IncomingPushMessageSignal.proto\022\ntexts" +
|
||||
"ecure\"s\n\031IncomingPushMessageSignal\022\014\n\004ty" +
|
||||
"pe\030\001 \001(\r\022\016\n\006source\030\002 \001(\t\022\024\n\014destinations" +
|
||||
"\030\003 \003(\t\022\021\n\ttimestamp\030\004 \001(\004\022\017\n\007message\030\005 \001" +
|
||||
"(\014\"\254\001\n\022PushMessageContent\022\014\n\004body\030\001 \001(\t\022" +
|
||||
"E\n\013attachments\030\002 \003(\01320.textsecure.PushMe" +
|
||||
"ssageContent.AttachmentPointer\032A\n\021Attach" +
|
||||
"mentPointer\022\n\n\002id\030\001 \001(\006\022\023\n\013contentType\030\002" +
|
||||
" \001(\t\022\013\n\003key\030\003 \001(\014B7\n\"org.whispersystems." +
|
||||
"textsecure.pushB\021PushMessageProtos"
|
||||
"ecure\"\202\001\n\031IncomingPushMessageSignal\022\014\n\004t" +
|
||||
"ype\030\001 \001(\r\022\016\n\006source\030\002 \001(\t\022\r\n\005relay\030\003 \001(\t" +
|
||||
"\022\024\n\014destinations\030\004 \003(\t\022\021\n\ttimestamp\030\005 \001(" +
|
||||
"\004\022\017\n\007message\030\006 \001(\014\"\254\001\n\022PushMessageConten" +
|
||||
"t\022\014\n\004body\030\001 \001(\t\022E\n\013attachments\030\002 \003(\01320.t" +
|
||||
"extsecure.PushMessageContent.AttachmentP" +
|
||||
"ointer\032A\n\021AttachmentPointer\022\n\n\002id\030\001 \001(\006\022" +
|
||||
"\023\n\013contentType\030\002 \001(\t\022\013\n\003key\030\003 \001(\014B7\n\"org" +
|
||||
".whispersystems.textsecure.pushB\021PushMes",
|
||||
"sageProtos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -1853,7 +1948,7 @@ public final class PushMessageProtos {
|
||||
internal_static_textsecure_IncomingPushMessageSignal_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_textsecure_IncomingPushMessageSignal_descriptor,
|
||||
new java.lang.String[] { "Type", "Source", "Destinations", "Timestamp", "Message", },
|
||||
new java.lang.String[] { "Type", "Source", "Relay", "Destinations", "Timestamp", "Message", },
|
||||
org.whispersystems.textsecure.push.PushMessageProtos.IncomingPushMessageSignal.class,
|
||||
org.whispersystems.textsecure.push.PushMessageProtos.IncomingPushMessageSignal.Builder.class);
|
||||
internal_static_textsecure_PushMessageContent_descriptor =
|
||||
|
@ -5,6 +5,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.google.thoughtcrimegson.Gson;
|
||||
|
||||
import org.whispersystems.textsecure.R;
|
||||
import org.whispersystems.textsecure.Release;
|
||||
import org.whispersystems.textsecure.crypto.IdentityKey;
|
||||
@ -12,9 +13,6 @@ import org.whispersystems.textsecure.storage.PreKeyRecord;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
import org.whispersystems.textsecure.util.Util;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -34,6 +32,10 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
public class PushServiceSocket {
|
||||
|
||||
private static final String CREATE_ACCOUNT_SMS_PATH = "/v1/accounts/sms/code/%s";
|
||||
@ -78,28 +80,31 @@ public class PushServiceSocket {
|
||||
makeRequest(REGISTER_GCM_PATH, "DELETE", null);
|
||||
}
|
||||
|
||||
public void sendMessage(String recipient, byte[] body, int type)
|
||||
public void sendMessage(String relay, String recipient, byte[] body, int type)
|
||||
throws IOException
|
||||
{
|
||||
OutgoingPushMessage message = new OutgoingPushMessage(recipient, body, type);
|
||||
OutgoingPushMessage message = new OutgoingPushMessage(relay, recipient, body, type);
|
||||
sendMessage(new OutgoingPushMessageList(message));
|
||||
}
|
||||
|
||||
public void sendMessage(List<String> recipients, List<byte[]> bodies, List<Integer> types)
|
||||
public void sendMessage(List<String> relays, List<String> recipients,
|
||||
List<byte[]> bodies, List<Integer> types)
|
||||
throws IOException
|
||||
{
|
||||
List<OutgoingPushMessage> messages = new LinkedList<OutgoingPushMessage>();
|
||||
|
||||
Iterator<String> relaysIterator = relays.iterator();
|
||||
Iterator<String> recipientsIterator = recipients.iterator();
|
||||
Iterator<byte[]> bodiesIterator = bodies.iterator();
|
||||
Iterator<Integer> typesIterator = types.iterator();
|
||||
|
||||
while (recipientsIterator.hasNext()) {
|
||||
String relay = relaysIterator.next();
|
||||
String recipient = recipientsIterator.next();
|
||||
byte[] body = bodiesIterator.next();
|
||||
int type = typesIterator.next();
|
||||
|
||||
messages.add(new OutgoingPushMessage(recipient, body, type));
|
||||
messages.add(new OutgoingPushMessage(relay, recipient, body, type));
|
||||
}
|
||||
|
||||
sendMessage(new OutgoingPushMessageList(messages));
|
||||
@ -134,8 +139,14 @@ public class PushServiceSocket {
|
||||
makeRequest(String.format(PREKEY_PATH, ""), "PUT", PreKeyList.toJson(new PreKeyList(lastResortEntity, entities)));
|
||||
}
|
||||
|
||||
public PreKeyEntity getPreKey(String number) throws IOException {
|
||||
String responseText = makeRequest(String.format(PREKEY_PATH, number), "GET", null);
|
||||
public PreKeyEntity getPreKey(String number, String relay) throws IOException {
|
||||
String path = String.format(PREKEY_PATH, number);
|
||||
|
||||
if (relay != null) {
|
||||
path = path + "?relay=" + relay;
|
||||
}
|
||||
|
||||
String responseText = makeRequest(path, "GET", null);
|
||||
Log.w("PushServiceSocket", "Got prekey: " + responseText);
|
||||
return PreKeyEntity.fromJson(responseText);
|
||||
}
|
||||
@ -170,11 +181,11 @@ public class PushServiceSocket {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public List<String> retrieveDirectory(Set<String> contactTokens) {
|
||||
public List<ContactTokenDetails> retrieveDirectory(Set<String> contactTokens) {
|
||||
try {
|
||||
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList(contactTokens));
|
||||
String response = makeRequest(DIRECTORY_TOKENS_PATH, "PUT", new Gson().toJson(contactTokenList));
|
||||
ContactTokenList activeTokens = new Gson().fromJson(response, ContactTokenList.class);
|
||||
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList(contactTokens));
|
||||
String response = makeRequest(DIRECTORY_TOKENS_PATH, "PUT", new Gson().toJson(contactTokenList));
|
||||
ContactTokenDetailsList activeTokens = new Gson().fromJson(response, ContactTokenDetailsList.class);
|
||||
|
||||
return activeTokens.getContacts();
|
||||
} catch (IOException ioe) {
|
||||
@ -183,12 +194,12 @@ public class PushServiceSocket {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRegisteredUser(String contactToken) throws IOException {
|
||||
public ContactTokenDetails getContactTokenDetails(String contactToken) throws IOException {
|
||||
try {
|
||||
makeRequest(String.format(DIRECTORY_VERIFY_PATH, contactToken), "GET", null);
|
||||
return true;
|
||||
String response = makeRequest(String.format(DIRECTORY_VERIFY_PATH, contactToken), "GET", null);
|
||||
return new Gson().fromJson(response, ContactTokenDetails.class);
|
||||
} catch (NotFoundException nfe) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,6 +322,9 @@ public class PushServiceSocket {
|
||||
context.init(null, trustManagerFactory.getTrustManagers(), null);
|
||||
|
||||
URL url = new URL(String.format("%s%s", Release.PUSH_SERVICE_URL, urlFragment));
|
||||
Log.w("PushServiceSocket", "Push service URL: " + Release.PUSH_SERVICE_URL);
|
||||
Log.w("PushServiceSocket", "Opening URL: " + url);
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
|
||||
|
||||
if (Release.ENFORCE_SSL) {
|
||||
|
@ -10,6 +10,8 @@ import org.thoughtcrime.securesms.service.SendReceiveService;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.textsecure.crypto.InvalidVersionException;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.push.IncomingEncryptedPushMessage;
|
||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
@ -59,13 +61,16 @@ public class GcmIntentService extends GCMBaseIntentService {
|
||||
IncomingEncryptedPushMessage encryptedMessage = new IncomingEncryptedPushMessage(data, sessionKey);
|
||||
IncomingPushMessage message = encryptedMessage.getIncomingPushMessage();
|
||||
|
||||
if (!isActiveNumber(context, message.getSource())) {
|
||||
Directory directory = Directory.getInstance(context);
|
||||
String contactToken = directory.getToken(message.getSource());
|
||||
ContactTokenDetails contactTokenDetails = new ContactTokenDetails(contactToken, message.getRelay());
|
||||
directory.setToken(contactTokenDetails, true);
|
||||
}
|
||||
|
||||
Intent service = new Intent(context, SendReceiveService.class);
|
||||
service.setAction(SendReceiveService.RECEIVE_PUSH_ACTION);
|
||||
service.putExtra("message", message);
|
||||
|
||||
Directory directory = Directory.getInstance(context);
|
||||
directory.setToken(directory.getToken(message.getSource()), true);
|
||||
|
||||
context.startService(service);
|
||||
} catch (IOException e) {
|
||||
Log.w("GcmIntentService", e);
|
||||
@ -84,4 +89,16 @@ public class GcmIntentService extends GCMBaseIntentService {
|
||||
String password = TextSecurePreferences.getPushServerPassword(context);
|
||||
return new PushServiceSocket(context, localNumber, password);
|
||||
}
|
||||
|
||||
private boolean isActiveNumber(Context context, String e164number) {
|
||||
boolean isActiveNumber;
|
||||
|
||||
try {
|
||||
isActiveNumber = Directory.getInstance(context).isActiveNumber(e164number);
|
||||
} catch (NotInDirectoryException e) {
|
||||
isActiveNumber = false;
|
||||
}
|
||||
|
||||
return isActiveNumber;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
|
||||
import java.util.List;
|
||||
@ -61,11 +62,14 @@ public class DirectoryRefreshService extends Service {
|
||||
String password = TextSecurePreferences.getPushServerPassword(context);
|
||||
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
|
||||
|
||||
Set<String> eligibleContactTokens = directory.getPushEligibleContactTokens(localNumber);
|
||||
List<String> activeTokens = socket.retrieveDirectory(eligibleContactTokens);
|
||||
Set<String> eligibleContactTokens = directory.getPushEligibleContactTokens(localNumber);
|
||||
List<ContactTokenDetails> activeTokens = socket.retrieveDirectory(eligibleContactTokens);
|
||||
|
||||
if (activeTokens != null) {
|
||||
eligibleContactTokens.removeAll(activeTokens);
|
||||
for (ContactTokenDetails activeToken : activeTokens) {
|
||||
eligibleContactTokens.remove(activeToken.getToken());
|
||||
}
|
||||
|
||||
directory.setTokens(activeTokens, eligibleContactTokens);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import org.whispersystems.textsecure.crypto.IdentityKey;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.PreKeyUtil;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
import org.whispersystems.textsecure.storage.PreKeyRecord;
|
||||
import org.whispersystems.textsecure.util.Util;
|
||||
@ -282,11 +283,13 @@ public class RegistrationService extends Service {
|
||||
String gcmRegistrationId = waitForGcmRegistrationId();
|
||||
socket.registerGcmId(gcmRegistrationId);
|
||||
|
||||
Set<String> contactTokens = Directory.getInstance(this).getPushEligibleContactTokens(number);
|
||||
List<String> activeTokens = socket.retrieveDirectory(contactTokens);
|
||||
Set<String> contactTokens = Directory.getInstance(this).getPushEligibleContactTokens(number);
|
||||
List<ContactTokenDetails> activeTokens = socket.retrieveDirectory(contactTokens);
|
||||
|
||||
if (activeTokens != null) {
|
||||
contactTokens.removeAll(activeTokens);
|
||||
for (ContactTokenDetails activeToken : activeTokens) {
|
||||
contactTokens.remove(activeToken.getToken());
|
||||
}
|
||||
Directory.getInstance(this).setTokens(activeTokens, contactTokens);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import org.whispersystems.textsecure.crypto.KeyUtil;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.MessageCipher;
|
||||
import org.whispersystems.textsecure.crypto.protocol.PreKeyBundleMessage;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.push.OutgoingPushMessage;
|
||||
import org.whispersystems.textsecure.push.PreKeyEntity;
|
||||
import org.whispersystems.textsecure.push.PushAttachmentData;
|
||||
@ -61,12 +62,12 @@ public class PushTransport extends BaseTransport {
|
||||
String plaintextBody = message.getBody().getBody();
|
||||
PushMessageContent.Builder builder = PushMessageContent.newBuilder();
|
||||
byte[] plaintext = builder.setBody(plaintextBody).build().toByteArray();
|
||||
String recipientCanonicalNumber = PhoneNumberFormatter.formatNumber(recipient.getNumber(),
|
||||
localNumber);
|
||||
String recipientCanonicalNumber = PhoneNumberFormatter.formatNumber(recipient.getNumber(), localNumber);
|
||||
String relay = Directory.getInstance(context).getRelay(recipientCanonicalNumber);
|
||||
|
||||
Pair<Integer, byte[]> typeAndCiphertext = getEncryptedMessage(socket, recipient, recipientCanonicalNumber, plaintext);
|
||||
|
||||
socket.sendMessage(recipientCanonicalNumber, typeAndCiphertext.second, typeAndCiphertext.first);
|
||||
socket.sendMessage(relay, recipientCanonicalNumber, typeAndCiphertext.second, typeAndCiphertext.first);
|
||||
|
||||
context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType()));
|
||||
} catch (RateLimitException e) {
|
||||
@ -81,7 +82,8 @@ public class PushTransport extends BaseTransport {
|
||||
String password = TextSecurePreferences.getPushServerPassword(context);
|
||||
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
|
||||
String messageBody = PartParser.getMessageText(message.getBody());
|
||||
List<byte[]> ciphertext = new LinkedList<byte[]> ();
|
||||
List<String> relays = new LinkedList<String>();
|
||||
List<byte[]> ciphertext = new LinkedList<byte[]>();
|
||||
List<Integer> types = new LinkedList<Integer>();
|
||||
|
||||
for (String destination : destinations) {
|
||||
@ -108,11 +110,12 @@ public class PushTransport extends BaseTransport {
|
||||
Pair<Integer, byte[]> typeAndCiphertext = getEncryptedMessage(socket, recipients.getPrimaryRecipient(),
|
||||
destination, plaintext);
|
||||
|
||||
relays.add(Directory.getInstance(context).getRelay(destination));
|
||||
types.add(typeAndCiphertext.first);
|
||||
ciphertext.add(typeAndCiphertext.second);
|
||||
}
|
||||
|
||||
socket.sendMessage(destinations, ciphertext, types);
|
||||
socket.sendMessage(relays, destinations, ciphertext, types);
|
||||
|
||||
} catch (RateLimitException e) {
|
||||
Log.w("PushTransport", e);
|
||||
@ -187,7 +190,8 @@ public class PushTransport extends BaseTransport {
|
||||
{
|
||||
IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret);
|
||||
IdentityKey identityKey = identityKeyPair.getPublicKey();
|
||||
PreKeyEntity preKey = socket.getPreKey(canonicalRecipientNumber);
|
||||
String relay = Directory.getInstance(context).getRelay(canonicalRecipientNumber);
|
||||
PreKeyEntity preKey = socket.getPreKey(canonicalRecipientNumber, relay);
|
||||
KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
|
||||
|
||||
processor.processKeyExchangeMessage(preKey);
|
||||
|
@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||
import org.whispersystems.textsecure.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -126,15 +127,20 @@ public class UniversalTransport {
|
||||
return directory.isActiveNumber(destination);
|
||||
} catch (NotInDirectoryException e) {
|
||||
try {
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String pushPassword = TextSecurePreferences.getPushServerPassword(context);
|
||||
String contactToken = directory.getToken(destination);
|
||||
PushServiceSocket socket = new PushServiceSocket(context, localNumber, pushPassword);
|
||||
boolean registeredUser = socket.isRegisteredUser(contactToken);
|
||||
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||
String pushPassword = TextSecurePreferences.getPushServerPassword(context);
|
||||
String contactToken = directory.getToken(destination);
|
||||
PushServiceSocket socket = new PushServiceSocket(context, localNumber, pushPassword);
|
||||
ContactTokenDetails registeredUser = socket.getContactTokenDetails(contactToken);
|
||||
|
||||
directory.setToken(contactToken, registeredUser);
|
||||
|
||||
return registeredUser;
|
||||
if (registeredUser == null) {
|
||||
registeredUser = new ContactTokenDetails(contactToken);
|
||||
directory.setToken(registeredUser, false);
|
||||
return false;
|
||||
} else {
|
||||
directory.setToken(registeredUser, true);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
Log.w("UniversalTransport", e1);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user