Add usermethod for postponing prekey deletion to OmemoManager
This commit is contained in:
parent
45574e6bbb
commit
a0838b99cd
|
@ -30,6 +30,8 @@ import java.util.Set;
|
|||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -272,6 +274,54 @@ public final class OmemoManager extends Manager {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily postpone the deletion of used PreKeys for {@code millis} milliseconds.
|
||||
* During that period, used preKeys will not be deleted immediately, but rather queued for later deletion.
|
||||
* Once the time period has past, queued preKeys are deleted and normal behaviour is resumed.
|
||||
*
|
||||
* Recommended values for {@code millis} are around 1000 * 60 * 3.
|
||||
*
|
||||
* @param millis period in milliseconds from now, in which preKeys are not deleted immediately.
|
||||
*/
|
||||
public void temporarilyPostponePreKeyDeletion(long millis) {
|
||||
final OmemoStore<?,?,?,?,?,?,?,?,?> store = getOmemoService().getOmemoStoreBackend();
|
||||
final OmemoDevice userDevice = getOwnDevice();
|
||||
|
||||
if (userDevice == null) {
|
||||
throw new IllegalStateException("No OmemoDevice has been determined yet. OmemoManager needs to be initialized.");
|
||||
}
|
||||
|
||||
store.postponePreKeyDeletion(userDevice);
|
||||
ScheduledFuture<?> result = schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Async.go(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Delete any queued preKeys and resume default deletion behaviour
|
||||
store.resumePreKeyDeletion(userDevice);
|
||||
|
||||
// Count preKeys and generate new ones
|
||||
int preKeyCount = store.loadOmemoPreKeys(userDevice).size();
|
||||
try {
|
||||
store.replenishKeys(userDevice);
|
||||
|
||||
// If necessary, publish new bundle
|
||||
if (preKeyCount != store.loadOmemoPreKeys(userDevice).size()) {
|
||||
OmemoBundleElement bundle = store.packOmemoBundle(userDevice);
|
||||
OmemoService.publishBundle(getConnection(), userDevice, bundle);
|
||||
}
|
||||
} catch (CorruptedOmemoKeyException e) {
|
||||
LOGGER.log(Level.SEVERE, "Omemo IdentityKey seems to be corrupted for " + userDevice, e);
|
||||
} catch (InterruptedException | SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while publishing OMEMO bundle.", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a set of all OMEMO capable devices of a contact.
|
||||
* Note, that this method does not explicitly refresh the device list of the contact, so it might be outdated.
|
||||
|
|
|
@ -129,6 +129,14 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
return cached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if we are currently postponing deletion of preKeys for messages that are addressed to
|
||||
* {@code userDevice}. In such case, used preKeys are not deleted immediately, but instead are queued for later
|
||||
* deletion.
|
||||
*
|
||||
* @param userDevice our device
|
||||
* @return true if prekey deletion is postponed, false if prekeys are deleted immediately
|
||||
*/
|
||||
public boolean isPostponingPreKeyDeletion(OmemoDevice userDevice) {
|
||||
synchronized (postponePreKeyDeletion) {
|
||||
Boolean postpone = postponePreKeyDeletion.get(userDevice);
|
||||
|
@ -140,12 +148,23 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Postpone preKey deletion for now. Used preKeys are queued for deletion at a later point in time.
|
||||
*
|
||||
* @param userDevice our device
|
||||
*/
|
||||
public void postponePreKeyDeletion(OmemoDevice userDevice) {
|
||||
LOGGER.log(Level.INFO, "Postponing prekey deletion for " + userDevice);
|
||||
synchronized (postponePreKeyDeletion) {
|
||||
postponePreKeyDeletion.put(userDevice, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume immediate preKey deletion. This immediately deletes all preKeys which have been queued for deletion.
|
||||
*
|
||||
* @param userDevice our device
|
||||
*/
|
||||
public void resumePreKeyDeletion(OmemoDevice userDevice) {
|
||||
synchronized (postponePreKeyDeletion) {
|
||||
postponePreKeyDeletion.put(userDevice, Boolean.FALSE);
|
||||
|
@ -153,15 +172,28 @@ public abstract class OmemoStore<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey, T_
|
|||
}
|
||||
}
|
||||
|
||||
public void queuePreKeyForDeletion(OmemoDevice userDevice, int deviceId) {
|
||||
/**
|
||||
* Queue a used preKey for later deletion. The key is not deleted immediately, but marked as "to be deleted".
|
||||
* Deletion takes place, once {@link #deleteQueuedPreKeys(OmemoDevice)} is called (for example via
|
||||
* {@link #resumePreKeyDeletion(OmemoDevice)}).
|
||||
*
|
||||
* @param userDevice our device
|
||||
* @param preKeyId id of the preKey which will be queued for later deletion
|
||||
*/
|
||||
public void queuePreKeyForDeletion(OmemoDevice userDevice, int preKeyId) {
|
||||
Set<Integer> preKeyIds = preKeyDeletionQueues.get(userDevice);
|
||||
if (preKeyIds == null) {
|
||||
preKeyIds = new HashSet<>();
|
||||
preKeyDeletionQueues.put(userDevice, preKeyIds);
|
||||
}
|
||||
preKeyIds.add(deviceId);
|
||||
preKeyIds.add(preKeyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all preKeys which have been queued for deletion via {@link #queuePreKeyForDeletion(OmemoDevice, int)}.
|
||||
*
|
||||
* @param userDevice our device
|
||||
*/
|
||||
public void deleteQueuedPreKeys(OmemoDevice userDevice) {
|
||||
Set<Integer> queuedPreKeys = preKeyDeletionQueues.get(userDevice);
|
||||
if (queuedPreKeys == null) {
|
||||
|
|
Loading…
Reference in New Issue