mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-02 14:35:21 +00:00
Start increasing frequency of signed prekey rotation
// FREEBIE
This commit is contained in:
parent
884d8b7f72
commit
bb5dcb7131
@ -502,7 +502,12 @@
|
|||||||
|
|
||||||
<receiver android:name=".service.DirectoryRefreshListener">
|
<receiver android:name=".service.DirectoryRefreshListener">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.whispersystems.whisperpush.DIRECTORY_REFRESH"/>
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".service.RotateSignedPreKeyListener">
|
||||||
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
@ -34,7 +34,9 @@ import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirementProvi
|
|||||||
import org.thoughtcrime.securesms.jobs.requirements.MediaNetworkRequirementProvider;
|
import org.thoughtcrime.securesms.jobs.requirements.MediaNetworkRequirementProvider;
|
||||||
import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirementProvider;
|
import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirementProvider;
|
||||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||||
|
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
|
||||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||||
|
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.whispersystems.jobqueue.JobManager;
|
import org.whispersystems.jobqueue.JobManager;
|
||||||
import org.whispersystems.jobqueue.dependencies.DependencyInjector;
|
import org.whispersystems.jobqueue.dependencies.DependencyInjector;
|
||||||
@ -75,6 +77,7 @@ public class ApplicationContext extends Application implements DependencyInjecto
|
|||||||
initializeExpiringMessageManager();
|
initializeExpiringMessageManager();
|
||||||
initializeGcmCheck();
|
initializeGcmCheck();
|
||||||
initializeSignedPreKeyCheck();
|
initializeSignedPreKeyCheck();
|
||||||
|
initializePeriodicTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -150,4 +153,9 @@ public class ApplicationContext extends Application implements DependencyInjecto
|
|||||||
this.expiringMessageManager = new ExpiringMessageManager(this);
|
this.expiringMessageManager = new ExpiringMessageManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializePeriodicTasks() {
|
||||||
|
RotateSignedPreKeyListener.schedule(this);
|
||||||
|
DirectoryRefreshListener.schedule(this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||||||
|
|
||||||
initializeContactUpdatesReceiver();
|
initializeContactUpdatesReceiver();
|
||||||
|
|
||||||
DirectoryRefreshListener.schedule(this);
|
|
||||||
RatingManager.showRatingDialogIfNecessary(this);
|
RatingManager.showRatingDialogIfNecessary(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import org.whispersystems.libsignal.state.PreKeyStore;
|
|||||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
||||||
import org.whispersystems.libsignal.util.Medium;
|
import org.whispersystems.libsignal.util.Medium;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -46,7 +47,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PreKeyUtil {
|
public class PreKeyUtil {
|
||||||
|
|
||||||
public static final int BATCH_SIZE = 100;
|
private static final String TAG = PreKeyUtil.class.getName();
|
||||||
|
|
||||||
|
private static final int BATCH_SIZE = 100;
|
||||||
|
|
||||||
public static List<PreKeyRecord> generatePreKeys(Context context) {
|
public static List<PreKeyRecord> generatePreKeys(Context context) {
|
||||||
PreKeyStore preKeyStore = new TextSecurePreKeyStore(context);
|
PreKeyStore preKeyStore = new TextSecurePreKeyStore(context);
|
||||||
@ -66,7 +69,7 @@ public class PreKeyUtil {
|
|||||||
return records;
|
return records;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SignedPreKeyRecord generateSignedPreKey(Context context, IdentityKeyPair identityKeyPair)
|
public static SignedPreKeyRecord generateSignedPreKey(Context context, IdentityKeyPair identityKeyPair, boolean active)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context);
|
SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context);
|
||||||
@ -78,6 +81,10 @@ public class PreKeyUtil {
|
|||||||
signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record);
|
signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record);
|
||||||
setNextSignedPreKeyId(context, (signedPreKeyId + 1) % Medium.MAX_VALUE);
|
setNextSignedPreKeyId(context, (signedPreKeyId + 1) % Medium.MAX_VALUE);
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
setActiveSignedPreKeyId(context, signedPreKeyId);
|
||||||
|
}
|
||||||
|
|
||||||
return record;
|
return record;
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
@ -104,7 +111,7 @@ public class PreKeyUtil {
|
|||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setNextPreKeyId(Context context, int id) {
|
private static synchronized void setNextPreKeyId(Context context, int id) {
|
||||||
try {
|
try {
|
||||||
File nextFile = new File(getPreKeysDirectory(context), PreKeyIndex.FILE_NAME);
|
File nextFile = new File(getPreKeysDirectory(context), PreKeyIndex.FILE_NAME);
|
||||||
FileOutputStream fout = new FileOutputStream(nextFile);
|
FileOutputStream fout = new FileOutputStream(nextFile);
|
||||||
@ -115,18 +122,36 @@ public class PreKeyUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setNextSignedPreKeyId(Context context, int id) {
|
private static synchronized void setNextSignedPreKeyId(Context context, int id) {
|
||||||
try {
|
try {
|
||||||
File nextFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
|
SignedPreKeyIndex index = getSignedPreKeyIndex(context).or(new SignedPreKeyIndex());
|
||||||
FileOutputStream fout = new FileOutputStream(nextFile);
|
index.nextSignedPreKeyId = id;
|
||||||
fout.write(JsonUtils.toJson(new SignedPreKeyIndex(id)).getBytes());
|
|
||||||
fout.close();
|
setSignedPreKeyIndex(context, index);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w("PreKeyUtil", e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getNextPreKeyId(Context context) {
|
public static synchronized void setActiveSignedPreKeyId(Context context, int id) {
|
||||||
|
try {
|
||||||
|
SignedPreKeyIndex index = getSignedPreKeyIndex(context).or(new SignedPreKeyIndex());
|
||||||
|
index.activeSignedPreKeyId = id;
|
||||||
|
|
||||||
|
setSignedPreKeyIndex(context, index);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized int getActiveSignedPreKeyId(Context context) {
|
||||||
|
Optional<SignedPreKeyIndex> index = getSignedPreKeyIndex(context);
|
||||||
|
|
||||||
|
if (index.isPresent()) return index.get().activeSignedPreKeyId;
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized int getNextPreKeyId(Context context) {
|
||||||
try {
|
try {
|
||||||
File nextFile = new File(getPreKeysDirectory(context), PreKeyIndex.FILE_NAME);
|
File nextFile = new File(getPreKeysDirectory(context), PreKeyIndex.FILE_NAME);
|
||||||
|
|
||||||
@ -144,7 +169,7 @@ public class PreKeyUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getNextSignedPreKeyId(Context context) {
|
private static synchronized int getNextSignedPreKeyId(Context context) {
|
||||||
try {
|
try {
|
||||||
File nextFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
|
File nextFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
|
||||||
|
|
||||||
@ -162,6 +187,32 @@ public class PreKeyUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static synchronized Optional<SignedPreKeyIndex> getSignedPreKeyIndex(Context context) {
|
||||||
|
File indexFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
|
||||||
|
|
||||||
|
if (!indexFile.exists()) {
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStreamReader reader = new InputStreamReader(new FileInputStream(indexFile));
|
||||||
|
SignedPreKeyIndex index = JsonUtils.fromJson(reader, SignedPreKeyIndex.class);
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
return Optional.of(index);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized void setSignedPreKeyIndex(Context context, SignedPreKeyIndex index) throws IOException {
|
||||||
|
File indexFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
|
||||||
|
FileOutputStream fout = new FileOutputStream(indexFile);
|
||||||
|
fout.write(JsonUtils.toJson(index).getBytes());
|
||||||
|
fout.close();
|
||||||
|
}
|
||||||
|
|
||||||
private static File getPreKeysDirectory(Context context) {
|
private static File getPreKeysDirectory(Context context) {
|
||||||
return getKeysDirectory(context, TextSecurePreKeyStore.PREKEY_DIRECTORY);
|
return getKeysDirectory(context, TextSecurePreKeyStore.PREKEY_DIRECTORY);
|
||||||
}
|
}
|
||||||
@ -198,11 +249,11 @@ public class PreKeyUtil {
|
|||||||
@JsonProperty
|
@JsonProperty
|
||||||
private int nextSignedPreKeyId;
|
private int nextSignedPreKeyId;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private int activeSignedPreKeyId = -1;
|
||||||
|
|
||||||
public SignedPreKeyIndex() {}
|
public SignedPreKeyIndex() {}
|
||||||
|
|
||||||
public SignedPreKeyIndex(int nextSignedPreKeyId) {
|
|
||||||
this.nextSignedPreKeyId = nextSignedPreKeyId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,7 +79,9 @@ public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore {
|
|||||||
|
|
||||||
for (File signedPreKeyFile : directory.listFiles()) {
|
for (File signedPreKeyFile : directory.listFiles()) {
|
||||||
try {
|
try {
|
||||||
results.add(new SignedPreKeyRecord(loadSerializedRecord(signedPreKeyFile)));
|
if (!"index.dat".equals(signedPreKeyFile.getName())) {
|
||||||
|
results.add(new SignedPreKeyRecord(loadSerializedRecord(signedPreKeyFile)));
|
||||||
|
}
|
||||||
} catch (IOException | InvalidMessageException e) {
|
} catch (IOException | InvalidMessageException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.jobs.PushTextSendJob;
|
|||||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
||||||
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
|
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
|
||||||
import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob;
|
import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob;
|
||||||
|
import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
|
||||||
import org.thoughtcrime.securesms.push.SecurityEventListener;
|
import org.thoughtcrime.securesms.push.SecurityEventListener;
|
||||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||||
import org.thoughtcrime.securesms.service.MessageRetrievalService;
|
import org.thoughtcrime.securesms.service.MessageRetrievalService;
|
||||||
@ -56,7 +57,8 @@ import dagger.Provides;
|
|||||||
GcmRefreshJob.class,
|
GcmRefreshJob.class,
|
||||||
RequestGroupInfoJob.class,
|
RequestGroupInfoJob.class,
|
||||||
PushGroupUpdateJob.class,
|
PushGroupUpdateJob.class,
|
||||||
AvatarDownloadJob.class})
|
AvatarDownloadJob.class,
|
||||||
|
RotateSignedPreKeyJob.class})
|
||||||
public class SignalCommunicationModule {
|
public class SignalCommunicationModule {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
|
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
@ -11,7 +12,6 @@ import org.whispersystems.libsignal.InvalidKeyIdException;
|
|||||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||||
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity;
|
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ public class CleanPreKeysJob extends MasterSecretJob implements InjectableType {
|
|||||||
|
|
||||||
private static final String TAG = CleanPreKeysJob.class.getSimpleName();
|
private static final String TAG = CleanPreKeysJob.class.getSimpleName();
|
||||||
|
|
||||||
private static final int ARCHIVE_AGE_DAYS = 15;
|
private static final long ARCHIVE_AGE = TimeUnit.DAYS.toMillis(7);
|
||||||
|
|
||||||
@Inject transient SignalServiceAccountManager accountManager;
|
@Inject transient SignalServiceAccountManager accountManager;
|
||||||
@Inject transient SignedPreKeyStoreFactory signedPreKeyStoreFactory;
|
@Inject transient SignedPreKeyStoreFactory signedPreKeyStoreFactory;
|
||||||
@ -51,17 +51,20 @@ public class CleanPreKeysJob extends MasterSecretJob implements InjectableType {
|
|||||||
@Override
|
@Override
|
||||||
public void onRun(MasterSecret masterSecret) throws IOException {
|
public void onRun(MasterSecret masterSecret) throws IOException {
|
||||||
try {
|
try {
|
||||||
SignedPreKeyStore signedPreKeyStore = signedPreKeyStoreFactory.create();
|
Log.w(TAG, "Cleaning prekeys...");
|
||||||
SignedPreKeyEntity currentSignedPreKey = accountManager.getSignedPreKey();
|
|
||||||
|
|
||||||
if (currentSignedPreKey == null) return;
|
int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context);
|
||||||
|
SignedPreKeyStore signedPreKeyStore = signedPreKeyStoreFactory.create();
|
||||||
|
|
||||||
SignedPreKeyRecord currentRecord = signedPreKeyStore.loadSignedPreKey(currentSignedPreKey.getKeyId());
|
if (activeSignedPreKeyId < 0) return;
|
||||||
|
|
||||||
|
SignedPreKeyRecord currentRecord = signedPreKeyStore.loadSignedPreKey(activeSignedPreKeyId);
|
||||||
List<SignedPreKeyRecord> allRecords = signedPreKeyStore.loadSignedPreKeys();
|
List<SignedPreKeyRecord> allRecords = signedPreKeyStore.loadSignedPreKeys();
|
||||||
LinkedList<SignedPreKeyRecord> oldRecords = removeRecordFrom(currentRecord, allRecords);
|
LinkedList<SignedPreKeyRecord> oldRecords = removeRecordFrom(currentRecord, allRecords);
|
||||||
|
|
||||||
Collections.sort(oldRecords, new SignedPreKeySorter());
|
Collections.sort(oldRecords, new SignedPreKeySorter());
|
||||||
|
|
||||||
|
Log.w(TAG, "Active signed prekey: " + activeSignedPreKeyId);
|
||||||
Log.w(TAG, "Old signed prekey record count: " + oldRecords.size());
|
Log.w(TAG, "Old signed prekey record count: " + oldRecords.size());
|
||||||
|
|
||||||
boolean foundAgedRecord = false;
|
boolean foundAgedRecord = false;
|
||||||
@ -69,7 +72,7 @@ public class CleanPreKeysJob extends MasterSecretJob implements InjectableType {
|
|||||||
for (SignedPreKeyRecord oldRecord : oldRecords) {
|
for (SignedPreKeyRecord oldRecord : oldRecords) {
|
||||||
long archiveDuration = System.currentTimeMillis() - oldRecord.getTimestamp();
|
long archiveDuration = System.currentTimeMillis() - oldRecord.getTimestamp();
|
||||||
|
|
||||||
if (archiveDuration >= TimeUnit.DAYS.toMillis(ARCHIVE_AGE_DAYS)) {
|
if (archiveDuration >= ARCHIVE_AGE) {
|
||||||
if (!foundAgedRecord) {
|
if (!foundAgedRecord) {
|
||||||
foundAgedRecord = true;
|
foundAgedRecord = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +53,7 @@ public class CreateSignedPreKeyJob extends MasterSecretJob implements Injectable
|
|||||||
}
|
}
|
||||||
|
|
||||||
IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context);
|
IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context);
|
||||||
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKeyPair);
|
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true);
|
||||||
|
|
||||||
accountManager.setSignedPreKey(signedPreKeyRecord);
|
accountManager.setSignedPreKey(signedPreKeyRecord);
|
||||||
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
||||||
|
@ -70,12 +70,10 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdded() {
|
public void onAdded() {
|
||||||
// DatabaseFactory.getMmsDatabase(context)
|
|
||||||
// .markAsSending(messageId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSend(MasterSecret masterSecret)
|
public void onPushSend(MasterSecret masterSecret)
|
||||||
throws MmsException, IOException, NoSuchMessageException
|
throws MmsException, IOException, NoSuchMessageException
|
||||||
{
|
{
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
@ -84,8 +82,6 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
try {
|
try {
|
||||||
deliver(masterSecret, message, filterRecipientId);
|
deliver(masterSecret, message, filterRecipientId);
|
||||||
|
|
||||||
// database.markAsPush(messageId);
|
|
||||||
// database.markAsSecure(messageId);
|
|
||||||
database.markAsSent(messageId, true);
|
database.markAsSent(messageId, true);
|
||||||
markAttachmentsUploaded(messageId, message.getAttachments());
|
markAttachmentsUploaded(messageId, message.getAttachments());
|
||||||
|
|
||||||
@ -114,10 +110,8 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
database.addFailures(messageId, failures);
|
database.addFailures(messageId, failures);
|
||||||
// database.markAsPush(messageId);
|
|
||||||
|
|
||||||
if (e.getNetworkExceptions().isEmpty() && e.getUntrustedIdentityExceptions().isEmpty()) {
|
if (e.getNetworkExceptions().isEmpty() && e.getUntrustedIdentityExceptions().isEmpty()) {
|
||||||
// database.markAsSecure(messageId);
|
|
||||||
database.markAsSent(messageId, true);
|
database.markAsSent(messageId, true);
|
||||||
markAttachmentsUploaded(messageId, message.getAttachments());
|
markAttachmentsUploaded(messageId, message.getAttachments());
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,13 +53,11 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdded() {
|
public void onAdded() {
|
||||||
// MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context);
|
|
||||||
// mmsDatabase.markAsSending(messageId);
|
|
||||||
// mmsDatabase.markAsPush(messageId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSend(MasterSecret masterSecret)
|
public void onPushSend(MasterSecret masterSecret)
|
||||||
throws RetryLaterException, MmsException, NoSuchMessageException,
|
throws RetryLaterException, MmsException, NoSuchMessageException,
|
||||||
UndeliverableMessageException
|
UndeliverableMessageException
|
||||||
{
|
{
|
||||||
@ -69,8 +67,6 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
deliver(masterSecret, message);
|
deliver(masterSecret, message);
|
||||||
// database.markAsPush(messageId);
|
|
||||||
// database.markAsSecure(messageId);
|
|
||||||
database.markAsSent(messageId, true);
|
database.markAsSent(messageId, true);
|
||||||
markAttachmentsUploaded(messageId, message.getAttachments());
|
markAttachmentsUploaded(messageId, message.getAttachments());
|
||||||
|
|
||||||
@ -91,7 +87,6 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
|||||||
|
|
||||||
database.addMismatchedIdentity(messageId, recipientId, uie.getIdentityKey());
|
database.addMismatchedIdentity(messageId, recipientId, uie.getIdentityKey());
|
||||||
database.markAsSentFailed(messageId);
|
database.markAsSentFailed(messageId);
|
||||||
// database.markAsPush(messageId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.jobs;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.TextSecureExpiredException;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
@ -12,6 +14,7 @@ import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
|||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
@ -48,6 +51,19 @@ public abstract class PushSendJob extends SendJob {
|
|||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void onSend(MasterSecret masterSecret) throws Exception {
|
||||||
|
if (TextSecurePreferences.getSignedPreKeyFailureCount(context) > 5) {
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new RotateSignedPreKeyJob(context));
|
||||||
|
|
||||||
|
throw new TextSecureExpiredException("Too many signed prekey rotation failures");
|
||||||
|
}
|
||||||
|
|
||||||
|
onPushSend(masterSecret);
|
||||||
|
}
|
||||||
|
|
||||||
protected SignalServiceAddress getPushAddress(String number) throws InvalidNumberException {
|
protected SignalServiceAddress getPushAddress(String number) throws InvalidNumberException {
|
||||||
String e164number = Util.canonicalizeNumber(context, number);
|
String e164number = Util.canonicalizeNumber(context, number);
|
||||||
String relay = TextSecureDirectory.getInstance(context).getRelay(e164number);
|
String relay = TextSecureDirectory.getInstance(context).getRelay(e164number);
|
||||||
@ -93,4 +109,6 @@ public abstract class PushSendJob extends SendJob {
|
|||||||
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
MessageNotifier.notifyMessageDeliveryFailed(context, recipients, threadId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void onPushSend(MasterSecret masterSecret) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
|||||||
public void onAdded() {}
|
public void onAdded() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSend(MasterSecret masterSecret) throws NoSuchMessageException, RetryLaterException {
|
public void onPushSend(MasterSecret masterSecret) throws NoSuchMessageException, RetryLaterException {
|
||||||
ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager();
|
ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager();
|
||||||
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
|
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||||
SmsMessageRecord record = database.getMessage(masterSecret, messageId);
|
SmsMessageRecord record = database.getMessage(masterSecret, messageId);
|
||||||
|
@ -60,12 +60,13 @@ public class RefreshPreKeysJob extends MasterSecretJob implements InjectableType
|
|||||||
List<PreKeyRecord> preKeyRecords = PreKeyUtil.generatePreKeys(context);
|
List<PreKeyRecord> preKeyRecords = PreKeyUtil.generatePreKeys(context);
|
||||||
PreKeyRecord lastResortKeyRecord = PreKeyUtil.generateLastResortKey(context);
|
PreKeyRecord lastResortKeyRecord = PreKeyUtil.generateLastResortKey(context);
|
||||||
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
|
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
|
||||||
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey);
|
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false);
|
||||||
|
|
||||||
Log.w(TAG, "Registering new prekeys...");
|
Log.w(TAG, "Registering new prekeys...");
|
||||||
|
|
||||||
accountManager.setPreKeys(identityKey.getPublicKey(), lastResortKeyRecord, signedPreKeyRecord, preKeyRecords);
|
accountManager.setPreKeys(identityKey.getPublicKey(), lastResortKeyRecord, signedPreKeyRecord, preKeyRecords);
|
||||||
|
|
||||||
|
PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId());
|
||||||
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
||||||
|
|
||||||
ApplicationContext.getInstance(context)
|
ApplicationContext.getInstance(context)
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package org.thoughtcrime.securesms.jobs;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||||
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
|
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
||||||
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
|
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
|
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||||
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||||
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class RotateSignedPreKeyJob extends MasterSecretJob implements InjectableType {
|
||||||
|
|
||||||
|
private static final String TAG = RotateSignedPreKeyJob.class.getName();
|
||||||
|
|
||||||
|
@Inject transient SignalServiceAccountManager accountManager;
|
||||||
|
|
||||||
|
public RotateSignedPreKeyJob(Context context) {
|
||||||
|
super(context, JobParameters.newBuilder()
|
||||||
|
.withRequirement(new NetworkRequirement(context))
|
||||||
|
.withRequirement(new MasterSecretRequirement(context))
|
||||||
|
.withRetryCount(5)
|
||||||
|
.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdded() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRun(MasterSecret masterSecret) throws Exception {
|
||||||
|
Log.w(TAG, "Rotating signed prekey...");
|
||||||
|
|
||||||
|
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
|
||||||
|
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false);
|
||||||
|
|
||||||
|
accountManager.setSignedPreKey(signedPreKeyRecord);
|
||||||
|
|
||||||
|
PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId());
|
||||||
|
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
|
||||||
|
TextSecurePreferences.setSignedPreKeyFailureCount(context, 0);
|
||||||
|
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new CleanPreKeysJob(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onShouldRetryThrowable(Exception exception) {
|
||||||
|
return exception instanceof PushNetworkException;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCanceled() {
|
||||||
|
TextSecurePreferences.setSignedPreKeyFailureCount(context, TextSecurePreferences.getSignedPreKeyFailureCount(context) + 1);
|
||||||
|
}
|
||||||
|
}
|
@ -1,64 +1,39 @@
|
|||||||
package org.thoughtcrime.securesms.service;
|
package org.thoughtcrime.securesms.service;
|
||||||
|
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
|
||||||
public class DirectoryRefreshListener extends BroadcastReceiver {
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
private static final String TAG = DirectoryRefreshListener.class.getSimpleName();
|
public class DirectoryRefreshListener extends PersistentAlarmManagerListener {
|
||||||
|
|
||||||
private static final String REFRESH_EVENT = "org.whispersystems.whisperpush.DIRECTORY_REFRESH";
|
private static final long INTERVAL = TimeUnit.HOURS.toMillis(12);
|
||||||
private static final String BOOT_EVENT = "android.intent.action.BOOT_COMPLETED";
|
|
||||||
|
|
||||||
private static final long INTERVAL = 12 * 60 * 60 * 1000; // 12 hours.
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
protected long getNextScheduledExecutionTime(Context context) {
|
||||||
if (REFRESH_EVENT.equals(intent.getAction())) handleRefreshAction(context);
|
return TextSecurePreferences.getDirectoryRefreshTime(context);
|
||||||
else if (BOOT_EVENT.equals(intent.getAction())) handleBootEvent(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleBootEvent(Context context) {
|
@Override
|
||||||
schedule(context);
|
protected long onAlarm(Context context, long scheduledTime) {
|
||||||
}
|
if (scheduledTime != 0 && TextSecurePreferences.isPushRegistered(context)) {
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new DirectoryRefreshJob(context));
|
||||||
|
}
|
||||||
|
|
||||||
private void handleRefreshAction(Context context) {
|
long newTime = System.currentTimeMillis() + INTERVAL;
|
||||||
schedule(context);
|
TextSecurePreferences.setDirectoryRefreshTime(context, newTime);
|
||||||
|
|
||||||
|
return newTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void schedule(Context context) {
|
public static void schedule(Context context) {
|
||||||
if (!TextSecurePreferences.isPushRegistered(context)) return;
|
new DirectoryRefreshListener().onReceive(context, new Intent());
|
||||||
|
|
||||||
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
Intent intent = new Intent(DirectoryRefreshListener.REFRESH_EVENT);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
|
||||||
long time = TextSecurePreferences.getDirectoryRefreshTime(context);
|
|
||||||
|
|
||||||
if (time <= System.currentTimeMillis()) {
|
|
||||||
if (time != 0) {
|
|
||||||
ApplicationContext.getInstance(context)
|
|
||||||
.getJobManager()
|
|
||||||
.add(new DirectoryRefreshJob(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
time = System.currentTimeMillis() + INTERVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.w(TAG, "Scheduling for: " + time);
|
|
||||||
|
|
||||||
alarmManager.cancel(pendingIntent);
|
|
||||||
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
|
|
||||||
|
|
||||||
TextSecurePreferences.setDirectoryRefreshTime(context, time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.thoughtcrime.securesms.service;
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public abstract class PersistentAlarmManagerListener extends BroadcastReceiver {
|
||||||
|
|
||||||
|
private static final String TAG = PersistentAlarmManagerListener.class.getSimpleName();
|
||||||
|
|
||||||
|
protected abstract long getNextScheduledExecutionTime(Context context);
|
||||||
|
protected abstract long onAlarm(Context context, long scheduledTime);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
long scheduledTime = getNextScheduledExecutionTime(context);
|
||||||
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
Intent alarmIntent = new Intent(context, getClass());
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
|
||||||
|
|
||||||
|
if (System.currentTimeMillis() >= scheduledTime) {
|
||||||
|
scheduledTime = onAlarm(context, scheduledTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.w(TAG, getClass() + " scheduling for: " + scheduledTime);
|
||||||
|
|
||||||
|
alarmManager.cancel(pendingIntent);
|
||||||
|
alarmManager.set(AlarmManager.RTC_WAKEUP, scheduledTime, pendingIntent);
|
||||||
|
}
|
||||||
|
}
|
@ -239,7 +239,7 @@ public class RegistrationService extends Service {
|
|||||||
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(this);
|
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(this);
|
||||||
List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(this);
|
List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(this);
|
||||||
PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this);
|
PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this);
|
||||||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(this, identityKey);
|
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(this, identityKey, true);
|
||||||
accountManager.setPreKeys(identityKey.getPublicKey(),lastResort, signedPreKey, records);
|
accountManager.setPreKeys(identityKey.getPublicKey(),lastResort, signedPreKey, records);
|
||||||
|
|
||||||
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
||||||
@ -261,6 +261,7 @@ public class RegistrationService extends Service {
|
|||||||
redPhoneAccountManager.createAccount(verificationToken, new RedPhoneAccountAttributes(signalingKey, gcmRegistrationId));
|
redPhoneAccountManager.createAccount(verificationToken, new RedPhoneAccountAttributes(signalingKey, gcmRegistrationId));
|
||||||
|
|
||||||
DirectoryRefreshListener.schedule(this);
|
DirectoryRefreshListener.schedule(this);
|
||||||
|
RotateSignedPreKeyListener.schedule(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized String waitForChallenge() throws AccountVerificationTimeoutException {
|
private synchronized String waitForChallenge() throws AccountVerificationTimeoutException {
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.thoughtcrime.securesms.service;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener {
|
||||||
|
|
||||||
|
private static final long INTERVAL = TimeUnit.DAYS.toMillis(2);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long getNextScheduledExecutionTime(Context context) {
|
||||||
|
return TextSecurePreferences.getSignedPreKeyRotationTime(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long onAlarm(Context context, long scheduledTime) {
|
||||||
|
if (scheduledTime != 0 && TextSecurePreferences.isPushRegistered(context)) {
|
||||||
|
ApplicationContext.getInstance(context)
|
||||||
|
.getJobManager()
|
||||||
|
.add(new RotateSignedPreKeyJob(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
long nextTime = System.currentTimeMillis() + INTERVAL;
|
||||||
|
TextSecurePreferences.setSignedPreKeyRotationTime(context, nextTime);
|
||||||
|
|
||||||
|
return nextTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void schedule(Context context) {
|
||||||
|
new RotateSignedPreKeyListener().onReceive(context, new Intent());
|
||||||
|
}
|
||||||
|
}
|
@ -72,6 +72,7 @@ public class TextSecurePreferences {
|
|||||||
private static final String PROMPTED_SHARE_PREF = "pref_prompted_share";
|
private static final String PROMPTED_SHARE_PREF = "pref_prompted_share";
|
||||||
private static final String SIGNALING_KEY_PREF = "pref_signaling_key";
|
private static final String SIGNALING_KEY_PREF = "pref_signaling_key";
|
||||||
private static final String DIRECTORY_FRESH_TIME_PREF = "pref_directory_refresh_time";
|
private static final String DIRECTORY_FRESH_TIME_PREF = "pref_directory_refresh_time";
|
||||||
|
private static final String SIGNED_PREKEY_ROTATION_TIME_PREF = "pref_signed_pre_key_rotation_time";
|
||||||
private static final String IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications";
|
private static final String IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications";
|
||||||
private static final String BLOCKING_IDENTITY_CHANGES_PREF = "pref_blocking_identity_changes";
|
private static final String BLOCKING_IDENTITY_CHANGES_PREF = "pref_blocking_identity_changes";
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ public class TextSecurePreferences {
|
|||||||
private static final String WEBSOCKET_REGISTERED_PREF = "pref_websocket_registered";
|
private static final String WEBSOCKET_REGISTERED_PREF = "pref_websocket_registered";
|
||||||
private static final String RATING_LATER_PREF = "pref_rating_later";
|
private static final String RATING_LATER_PREF = "pref_rating_later";
|
||||||
private static final String RATING_ENABLED_PREF = "pref_rating_enabled";
|
private static final String RATING_ENABLED_PREF = "pref_rating_enabled";
|
||||||
|
private static final String SIGNED_PREKEY_FAILURE_COUNT_PREF = "pref_signed_prekey_failure_count";
|
||||||
|
|
||||||
public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts";
|
public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts";
|
||||||
public static final String NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy";
|
public static final String NOTIFICATION_PRIVACY_PREF = "pref_notification_privacy";
|
||||||
@ -122,6 +124,14 @@ public class TextSecurePreferences {
|
|||||||
setBooleanPreference(context, BLOCKING_IDENTITY_CHANGES_PREF, value);
|
setBooleanPreference(context, BLOCKING_IDENTITY_CHANGES_PREF, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setSignedPreKeyFailureCount(Context context, int value) {
|
||||||
|
setIntegerPrefrence(context, SIGNED_PREKEY_FAILURE_COUNT_PREF, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getSignedPreKeyFailureCount(Context context) {
|
||||||
|
return getIntegerPreference(context, SIGNED_PREKEY_FAILURE_COUNT_PREF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public static NotificationPrivacyPreference getNotificationPrivacy(Context context) {
|
public static NotificationPrivacyPreference getNotificationPrivacy(Context context) {
|
||||||
return new NotificationPrivacyPreference(getStringPreference(context, NOTIFICATION_PRIVACY_PREF, "all"));
|
return new NotificationPrivacyPreference(getStringPreference(context, NOTIFICATION_PRIVACY_PREF, "all"));
|
||||||
}
|
}
|
||||||
@ -214,6 +224,14 @@ public class TextSecurePreferences {
|
|||||||
return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true);
|
return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getSignedPreKeyRotationTime(Context context) {
|
||||||
|
return getLongPreference(context, SIGNED_PREKEY_ROTATION_TIME_PREF, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setSignedPreKeyRotationTime(Context context, long value) {
|
||||||
|
setLongPreference(context, SIGNED_PREKEY_ROTATION_TIME_PREF, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static long getDirectoryRefreshTime(Context context) {
|
public static long getDirectoryRefreshTime(Context context) {
|
||||||
return getLongPreference(context, DIRECTORY_FRESH_TIME_PREF, 0L);
|
return getLongPreference(context, DIRECTORY_FRESH_TIME_PREF, 0L);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user