mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-14 03:03:39 +00:00
138 lines
4.7 KiB
Java
138 lines
4.7 KiB
Java
package org.thoughtcrime.securesms.jobs;
|
|
|
|
import android.content.Context;
|
|
import android.support.annotation.NonNull;
|
|
|
|
import org.thoughtcrime.securesms.jobmanager.SafeData;
|
|
import org.thoughtcrime.securesms.logging.Log;
|
|
|
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
|
import org.thoughtcrime.securesms.jobmanager.JobParameters;
|
|
import org.whispersystems.libsignal.InvalidKeyIdException;
|
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
|
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
|
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import androidx.work.Data;
|
|
import androidx.work.WorkerParameters;
|
|
|
|
import static org.thoughtcrime.securesms.dependencies.AxolotlStorageModule.SignedPreKeyStoreFactory;
|
|
|
|
public class CleanPreKeysJob extends ContextJob implements InjectableType {
|
|
|
|
private static final String TAG = CleanPreKeysJob.class.getSimpleName();
|
|
|
|
private static final long ARCHIVE_AGE = TimeUnit.DAYS.toMillis(7);
|
|
|
|
@Inject transient SignalServiceAccountManager accountManager;
|
|
@Inject transient SignedPreKeyStoreFactory signedPreKeyStoreFactory;
|
|
|
|
public CleanPreKeysJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
|
|
super(context, workerParameters);
|
|
}
|
|
|
|
public CleanPreKeysJob(Context context) {
|
|
super(context, JobParameters.newBuilder()
|
|
.withGroupId(CleanPreKeysJob.class.getSimpleName())
|
|
.withRetryCount(5)
|
|
.create());
|
|
}
|
|
|
|
@Override
|
|
protected void initialize(@NonNull SafeData data) {
|
|
}
|
|
|
|
@Override
|
|
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
|
|
return dataBuilder.build();
|
|
}
|
|
|
|
@Override
|
|
public void onRun() throws IOException {
|
|
try {
|
|
Log.i(TAG, "Cleaning prekeys...");
|
|
|
|
int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context);
|
|
SignedPreKeyStore signedPreKeyStore = signedPreKeyStoreFactory.create();
|
|
|
|
if (activeSignedPreKeyId < 0) return;
|
|
|
|
SignedPreKeyRecord currentRecord = signedPreKeyStore.loadSignedPreKey(activeSignedPreKeyId);
|
|
List<SignedPreKeyRecord> allRecords = signedPreKeyStore.loadSignedPreKeys();
|
|
LinkedList<SignedPreKeyRecord> oldRecords = removeRecordFrom(currentRecord, allRecords);
|
|
|
|
Collections.sort(oldRecords, new SignedPreKeySorter());
|
|
|
|
Log.i(TAG, "Active signed prekey: " + activeSignedPreKeyId);
|
|
Log.i(TAG, "Old signed prekey record count: " + oldRecords.size());
|
|
|
|
boolean foundAgedRecord = false;
|
|
|
|
for (SignedPreKeyRecord oldRecord : oldRecords) {
|
|
long archiveDuration = System.currentTimeMillis() - oldRecord.getTimestamp();
|
|
|
|
if (archiveDuration >= ARCHIVE_AGE) {
|
|
if (!foundAgedRecord) {
|
|
foundAgedRecord = true;
|
|
} else {
|
|
Log.i(TAG, "Removing signed prekey record: " + oldRecord.getId() + " with timestamp: " + oldRecord.getTimestamp());
|
|
signedPreKeyStore.removeSignedPreKey(oldRecord.getId());
|
|
}
|
|
}
|
|
}
|
|
} catch (InvalidKeyIdException e) {
|
|
Log.w(TAG, e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onShouldRetry(Exception throwable) {
|
|
if (throwable instanceof NonSuccessfulResponseCodeException) return false;
|
|
if (throwable instanceof PushNetworkException) return true;
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onCanceled() {
|
|
Log.w(TAG, "Failed to execute clean signed prekeys task.");
|
|
}
|
|
|
|
private LinkedList<SignedPreKeyRecord> removeRecordFrom(SignedPreKeyRecord currentRecord,
|
|
List<SignedPreKeyRecord> records)
|
|
|
|
{
|
|
LinkedList<SignedPreKeyRecord> others = new LinkedList<>();
|
|
|
|
for (SignedPreKeyRecord record : records) {
|
|
if (record.getId() != currentRecord.getId()) {
|
|
others.add(record);
|
|
}
|
|
}
|
|
|
|
return others;
|
|
}
|
|
|
|
private static class SignedPreKeySorter implements Comparator<SignedPreKeyRecord> {
|
|
@Override
|
|
public int compare(SignedPreKeyRecord lhs, SignedPreKeyRecord rhs) {
|
|
if (lhs.getTimestamp() > rhs.getTimestamp()) return -1;
|
|
else if (lhs.getTimestamp() < rhs.getTimestamp()) return 1;
|
|
else return 0;
|
|
}
|
|
}
|
|
|
|
}
|