mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Add last resort key and signaling key.
This commit is contained in:
parent
45e380a5bb
commit
68ec0a3727
@ -40,6 +40,24 @@ public class PreKeyUtil {
|
|||||||
return records;
|
return records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PreKeyRecord generateLastResortKey(Context context, MasterSecret masterSecret) {
|
||||||
|
if (PreKeyRecord.hasRecord(context, Medium.MAX_VALUE)) {
|
||||||
|
try {
|
||||||
|
return new PreKeyRecord(context, masterSecret, Medium.MAX_VALUE);
|
||||||
|
} catch (InvalidKeyIdException e) {
|
||||||
|
Log.w("PreKeyUtil", e);
|
||||||
|
PreKeyRecord.delete(context, Medium.MAX_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PreKeyPair keyPair = new PreKeyPair(masterSecret, KeyUtil.generateKeyPair());
|
||||||
|
PreKeyRecord record = new PreKeyRecord(context, masterSecret, Medium.MAX_VALUE, keyPair);
|
||||||
|
|
||||||
|
record.save();
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<PreKeyRecord> getPreKeys(Context context, MasterSecret masterSecret) {
|
public static List<PreKeyRecord> getPreKeys(Context context, MasterSecret masterSecret) {
|
||||||
List<PreKeyRecord> records = new LinkedList<PreKeyRecord>();
|
List<PreKeyRecord> records = new LinkedList<PreKeyRecord>();
|
||||||
File directory = getPreKeysDirectory(context);
|
File directory = getPreKeysDirectory(context);
|
||||||
@ -49,7 +67,9 @@ public class PreKeyUtil {
|
|||||||
|
|
||||||
for (String keyRecordId : keyRecordIds) {
|
for (String keyRecordId : keyRecordIds) {
|
||||||
try {
|
try {
|
||||||
records.add(new PreKeyRecord(context, masterSecret, Integer.parseInt(keyRecordId)));
|
if (Integer.parseInt(keyRecordId) != Medium.MAX_VALUE) {
|
||||||
|
records.add(new PreKeyRecord(context, masterSecret, Integer.parseInt(keyRecordId)));
|
||||||
|
}
|
||||||
} catch (InvalidKeyIdException e) {
|
} catch (InvalidKeyIdException e) {
|
||||||
Log.w("PreKeyUtil", e);
|
Log.w("PreKeyUtil", e);
|
||||||
new File(getPreKeysDirectory(context), keyRecordId).delete();
|
new File(getPreKeysDirectory(context), keyRecordId).delete();
|
||||||
|
@ -4,10 +4,12 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PreKeyList {
|
public class PreKeyList {
|
||||||
|
|
||||||
|
private PreKeyEntity lastResortKey;
|
||||||
private List<PreKeyEntity> keys;
|
private List<PreKeyEntity> keys;
|
||||||
|
|
||||||
public PreKeyList(List<PreKeyEntity> keys) {
|
public PreKeyList(PreKeyEntity lastResortKey, List<PreKeyEntity> keys) {
|
||||||
this.keys = keys;
|
this.keys = keys;
|
||||||
|
this.lastResortKey = lastResortKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PreKeyEntity> getKeys() {
|
public List<PreKeyEntity> getKeys() {
|
||||||
@ -17,4 +19,8 @@ public class PreKeyList {
|
|||||||
public static String toJson(PreKeyList entity) {
|
public static String toJson(PreKeyList entity) {
|
||||||
return PreKeyEntity.getBuilder().create().toJson(entity);
|
return PreKeyEntity.getBuilder().create().toJson(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PreKeyEntity getLastResortKey() {
|
||||||
|
return lastResortKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,9 @@ public class PushServiceSocket {
|
|||||||
makeRequest(String.format(path, localNumber), "POST", null);
|
makeRequest(String.format(path, localNumber), "POST", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyAccount(String verificationCode) throws IOException {
|
public void verifyAccount(String verificationCode, String signalingKey) throws IOException {
|
||||||
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode), "PUT", null);
|
SignalingKey signalingKeyEntity = new SignalingKey(signalingKey);
|
||||||
|
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode), "PUT", new Gson().toJson(signalingKeyEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerGcmId(String gcmRegistrationId) throws IOException {
|
public void registerGcmId(String gcmRegistrationId) throws IOException {
|
||||||
@ -109,7 +110,9 @@ public class PushServiceSocket {
|
|||||||
throw new IOException("Got send failure: " + response.getFailure().get(0));
|
throw new IOException("Got send failure: " + response.getFailure().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerPreKeys(IdentityKey identityKey, List<PreKeyRecord> records)
|
public void registerPreKeys(IdentityKey identityKey,
|
||||||
|
PreKeyRecord lastResortKey,
|
||||||
|
List<PreKeyRecord> records)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
List<PreKeyEntity> entities = new LinkedList<PreKeyEntity>();
|
List<PreKeyEntity> entities = new LinkedList<PreKeyEntity>();
|
||||||
@ -121,7 +124,11 @@ public class PushServiceSocket {
|
|||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
makeRequest(String.format(PREKEY_PATH, ""), "PUT", PreKeyList.toJson(new PreKeyList(entities)));
|
PreKeyEntity lastResortEntity = new PreKeyEntity(lastResortKey.getId(),
|
||||||
|
lastResortKey.getKeyPair().getPublicKey(),
|
||||||
|
identityKey);
|
||||||
|
|
||||||
|
makeRequest(String.format(PREKEY_PATH, ""), "PUT", PreKeyList.toJson(new PreKeyList(lastResortEntity, entities)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PreKeyEntity getPreKey(String number) throws IOException {
|
public PreKeyEntity getPreKey(String number) throws IOException {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ import org.whispersystems.textsecure.crypto.KeyPair;
|
|||||||
import org.whispersystems.textsecure.crypto.KeyUtil;
|
import org.whispersystems.textsecure.crypto.KeyUtil;
|
||||||
import org.whispersystems.textsecure.crypto.MasterCipher;
|
import org.whispersystems.textsecure.crypto.MasterCipher;
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
|
import org.whispersystems.textsecure.util.Medium;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -65,7 +66,8 @@ public class LocalKeyRecord extends Record {
|
|||||||
Log.w("LocalKeyRecord", "Remote client acknowledges receiving key id: " + keyId);
|
Log.w("LocalKeyRecord", "Remote client acknowledges receiving key id: " + keyId);
|
||||||
if (keyId == localNextKeyPair.getId()) {
|
if (keyId == localNextKeyPair.getId()) {
|
||||||
this.localCurrentKeyPair = this.localNextKeyPair;
|
this.localCurrentKeyPair = this.localNextKeyPair;
|
||||||
this.localNextKeyPair = new KeyPair(this.localNextKeyPair.getId()+1, KeyUtil.generateKeyPair(), masterSecret);
|
this.localNextKeyPair = new KeyPair((this.localNextKeyPair.getId()+1) % Medium.MAX_VALUE,
|
||||||
|
KeyUtil.generateKeyPair(), masterSecret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import android.util.Log;
|
|||||||
import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
||||||
import org.whispersystems.textsecure.crypto.PublicKey;
|
import org.whispersystems.textsecure.crypto.PublicKey;
|
||||||
import org.whispersystems.textsecure.util.Hex;
|
import org.whispersystems.textsecure.util.Hex;
|
||||||
|
import org.whispersystems.textsecure.util.Medium;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -62,7 +63,7 @@ public class RemoteKeyRecord extends Record {
|
|||||||
|
|
||||||
public void updateCurrentRemoteKey(PublicKey remoteKey) {
|
public void updateCurrentRemoteKey(PublicKey remoteKey) {
|
||||||
Log.w("RemoteKeyRecord", "Updating current remote key: " + remoteKey.getId());
|
Log.w("RemoteKeyRecord", "Updating current remote key: " + remoteKey.getId());
|
||||||
if (remoteKey.getId() > remoteKeyCurrent.getId()) {
|
if (isWrappingGreaterThan(remoteKey.getId(), remoteKeyCurrent.getId())) {
|
||||||
this.remoteKeyLast = this.remoteKeyCurrent;
|
this.remoteKeyLast = this.remoteKeyCurrent;
|
||||||
this.remoteKeyCurrent = remoteKey;
|
this.remoteKeyCurrent = remoteKey;
|
||||||
}
|
}
|
||||||
@ -112,6 +113,20 @@ public class RemoteKeyRecord extends Record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isWrappingGreaterThan(int receivedValue, int currentValue) {
|
||||||
|
if (receivedValue > currentValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receivedValue == currentValue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gap = (receivedValue - currentValue) + Medium.MAX_VALUE;
|
||||||
|
|
||||||
|
return (gap >= 0) && (gap < 5);
|
||||||
|
}
|
||||||
|
|
||||||
private void loadData() {
|
private void loadData() {
|
||||||
Log.w("RemoteKeyRecord", "Loading remote key record for recipient: " + this.address);
|
Log.w("RemoteKeyRecord", "Loading remote key record for recipient: " + this.address);
|
||||||
synchronized (FILE_LOCK) {
|
synchronized (FILE_LOCK) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package org.whispersystems.textsecure.util;
|
package org.whispersystems.textsecure.util;
|
||||||
|
|
||||||
public class Medium {
|
public class Medium {
|
||||||
public static int MAX_VALUE = 0xFFF;
|
public static int MAX_VALUE = 0xFFFFFF;
|
||||||
}
|
}
|
||||||
|
@ -432,14 +432,16 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
|||||||
|
|
||||||
private final String e164number;
|
private final String e164number;
|
||||||
private final String password;
|
private final String password;
|
||||||
|
private final String signalingKey;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
public VerifyClickListener(String e164number, String password) {
|
public VerifyClickListener(String e164number, String password) {
|
||||||
this.e164number = e164number;
|
this.e164number = e164number;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.context = RegistrationProgressActivity.this;
|
this.signalingKey = Util.getSecret(52);
|
||||||
|
this.context = RegistrationProgressActivity.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -473,6 +475,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
|||||||
intent.setAction(RegistrationService.VOICE_REGISTER_ACTION);
|
intent.setAction(RegistrationService.VOICE_REGISTER_ACTION);
|
||||||
intent.putExtra("e164number", e164number);
|
intent.putExtra("e164number", e164number);
|
||||||
intent.putExtra("password", password);
|
intent.putExtra("password", password);
|
||||||
|
intent.putExtra("signaling_key", signalingKey);
|
||||||
intent.putExtra("master_secret", masterSecret);
|
intent.putExtra("master_secret", masterSecret);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
break;
|
break;
|
||||||
@ -495,7 +498,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
|||||||
protected Integer doInBackground(Void... params) {
|
protected Integer doInBackground(Void... params) {
|
||||||
try {
|
try {
|
||||||
PushServiceSocket socket = new PushServiceSocket(context, e164number, password);
|
PushServiceSocket socket = new PushServiceSocket(context, e164number, password);
|
||||||
socket.verifyAccount(code);
|
socket.verifyAccount(code, signalingKey);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
} catch (RateLimitException e) {
|
} catch (RateLimitException e) {
|
||||||
Log.w("RegistrationProgressActivity", e);
|
Log.w("RegistrationProgressActivity", e);
|
||||||
@ -521,9 +524,9 @@ public class RegistrationProgressActivity extends SherlockActivity {
|
|||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
public CallClickListener(String e164number) {
|
public CallClickListener(String e164number) {
|
||||||
this.e164number = e164number;
|
this.e164number = e164number;
|
||||||
this.password = Util.getSecret(18);
|
this.password = Util.getSecret(18);
|
||||||
this.context = RegistrationProgressActivity.this;
|
this.context = RegistrationProgressActivity.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,6 +153,7 @@ public class RegistrationService extends Service {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (PreKeyUtil.getPreKeys(RegistrationService.this, masterSecret).size() < PreKeyUtil.BATCH_SIZE) {
|
if (PreKeyUtil.getPreKeys(RegistrationService.this, masterSecret).size() < PreKeyUtil.BATCH_SIZE) {
|
||||||
PreKeyUtil.generatePreKeys(RegistrationService.this, masterSecret);
|
PreKeyUtil.generatePreKeys(RegistrationService.this, masterSecret);
|
||||||
|
PreKeyUtil.generateLastResortKey(RegistrationService.this, masterSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (GENERATING_PREKEYS_SEMAPHOR) {
|
synchronized (GENERATING_PREKEYS_SEMAPHOR) {
|
||||||
@ -188,6 +189,7 @@ public class RegistrationService extends Service {
|
|||||||
|
|
||||||
String number = intent.getStringExtra("e164number");
|
String number = intent.getStringExtra("e164number");
|
||||||
String password = intent.getStringExtra("password" );
|
String password = intent.getStringExtra("password" );
|
||||||
|
String signalingKey = intent.getStringExtra("signaling_key");
|
||||||
MasterSecret masterSecret = intent.getParcelableExtra("master_secret");
|
MasterSecret masterSecret = intent.getParcelableExtra("master_secret");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -198,7 +200,7 @@ public class RegistrationService extends Service {
|
|||||||
|
|
||||||
handleCommonRegistration(masterSecret, socket, number);
|
handleCommonRegistration(masterSecret, socket, number);
|
||||||
|
|
||||||
markAsVerified(number, password);
|
markAsVerified(number, password, signalingKey);
|
||||||
|
|
||||||
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
|
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
|
||||||
broadcastComplete(true);
|
broadcastComplete(true);
|
||||||
@ -226,7 +228,9 @@ public class RegistrationService extends Service {
|
|||||||
MasterSecret masterSecret = intent.getParcelableExtra("master_secret");
|
MasterSecret masterSecret = intent.getParcelableExtra("master_secret");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String password = Util.getSecret(18);
|
String password = Util.getSecret(18);
|
||||||
|
String signalingKey = Util.getSecret(52);
|
||||||
|
|
||||||
initializeChallengeListener();
|
initializeChallengeListener();
|
||||||
initializeGcmRegistrationListener();
|
initializeGcmRegistrationListener();
|
||||||
initializePreKeyGenerator(masterSecret);
|
initializePreKeyGenerator(masterSecret);
|
||||||
@ -237,10 +241,10 @@ 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);
|
socket.verifyAccount(challenge, signalingKey);
|
||||||
|
|
||||||
handleCommonRegistration(masterSecret, socket, number);
|
handleCommonRegistration(masterSecret, socket, number);
|
||||||
markAsVerified(number, password);
|
markAsVerified(number, password, signalingKey);
|
||||||
|
|
||||||
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
|
setState(new RegistrationState(RegistrationState.STATE_COMPLETE, number));
|
||||||
broadcastComplete(true);
|
broadcastComplete(true);
|
||||||
@ -272,7 +276,8 @@ public class RegistrationService extends Service {
|
|||||||
setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number));
|
setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number));
|
||||||
IdentityKey identityKey = IdentityKeyUtil.getIdentityKey(this);
|
IdentityKey identityKey = IdentityKeyUtil.getIdentityKey(this);
|
||||||
List<PreKeyRecord> records = waitForPreKeys(masterSecret);
|
List<PreKeyRecord> records = waitForPreKeys(masterSecret);
|
||||||
socket.registerPreKeys(identityKey, records);
|
PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this, masterSecret);
|
||||||
|
socket.registerPreKeys(identityKey, lastResort, records);
|
||||||
|
|
||||||
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
||||||
GCMRegistrar.register(this, GcmIntentService.GCM_SENDER_ID);
|
GCMRegistrar.register(this, GcmIntentService.GCM_SENDER_ID);
|
||||||
@ -280,7 +285,10 @@ public class RegistrationService extends Service {
|
|||||||
|
|
||||||
socket.registerGcmId(gcmRegistrationId);
|
socket.registerGcmId(gcmRegistrationId);
|
||||||
Pair<DirectoryDescriptor, File> directory = socket.retrieveDirectory();
|
Pair<DirectoryDescriptor, File> directory = socket.retrieveDirectory();
|
||||||
NumberFilter.getInstance(this).update(directory.first, directory.second);
|
|
||||||
|
if (directory != null) {
|
||||||
|
NumberFilter.getInstance(this).update(directory.first, directory.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized String waitForChallenge() throws AccountVerificationTimeoutException {
|
private synchronized String waitForChallenge() throws AccountVerificationTimeoutException {
|
||||||
@ -347,11 +355,12 @@ public class RegistrationService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markAsVerified(String number, String password) {
|
private void markAsVerified(String number, String password, String signalingKey) {
|
||||||
TextSecurePreferences.setVerifying(this, false);
|
TextSecurePreferences.setVerifying(this, false);
|
||||||
TextSecurePreferences.setPushRegistered(this, true);
|
TextSecurePreferences.setPushRegistered(this, true);
|
||||||
TextSecurePreferences.setLocalNumber(this, number);
|
TextSecurePreferences.setLocalNumber(this, number);
|
||||||
TextSecurePreferences.setPushServerPassword(this, password);
|
TextSecurePreferences.setPushServerPassword(this, password);
|
||||||
|
TextSecurePreferences.setSignalingKey(this, signalingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setState(RegistrationState state) {
|
private void setState(RegistrationState state) {
|
||||||
@ -432,9 +441,9 @@ public class RegistrationService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RegistrationState(int state, String number, String password) {
|
public RegistrationState(int state, String number, String password) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,6 @@ import android.content.Context;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
|
||||||
import org.thoughtcrime.securesms.RoutingActivity;
|
|
||||||
|
|
||||||
public class TextSecurePreferences {
|
public class TextSecurePreferences {
|
||||||
|
|
||||||
public static final String IDENTITY_PREF = "pref_choose_identity";
|
public static final String IDENTITY_PREF = "pref_choose_identity";
|
||||||
@ -40,6 +37,7 @@ public class TextSecurePreferences {
|
|||||||
private static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
|
private static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
|
||||||
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
||||||
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
|
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
|
||||||
|
private static final String SIGNALING_KEY_PREF = "pref_signaling_key";
|
||||||
|
|
||||||
public static String getLocalNumber(Context context) {
|
public static String getLocalNumber(Context context) {
|
||||||
return getStringPreference(context, LOCAL_NUMBER_PREF, "No Stored Number");
|
return getStringPreference(context, LOCAL_NUMBER_PREF, "No Stored Number");
|
||||||
@ -57,6 +55,10 @@ public class TextSecurePreferences {
|
|||||||
setStringPreference(context, GCM_PASSWORD_PREF, password);
|
setStringPreference(context, GCM_PASSWORD_PREF, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setSignalingKey(Context context, String signalingKey) {
|
||||||
|
setStringPreference(context, SIGNALING_KEY_PREF, signalingKey);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isEnterImeKeyEnabled(Context context) {
|
public static boolean isEnterImeKeyEnabled(Context context) {
|
||||||
return getBooleanPreference(context, ENTER_PRESENT_PREF, false);
|
return getBooleanPreference(context, ENTER_PRESENT_PREF, false);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user