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.SortedSet;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
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.
|
* 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.
|
* 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 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) {
|
public boolean isPostponingPreKeyDeletion(OmemoDevice userDevice) {
|
||||||
synchronized (postponePreKeyDeletion) {
|
synchronized (postponePreKeyDeletion) {
|
||||||
Boolean postpone = postponePreKeyDeletion.get(userDevice);
|
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) {
|
public void postponePreKeyDeletion(OmemoDevice userDevice) {
|
||||||
|
LOGGER.log(Level.INFO, "Postponing prekey deletion for " + userDevice);
|
||||||
synchronized (postponePreKeyDeletion) {
|
synchronized (postponePreKeyDeletion) {
|
||||||
postponePreKeyDeletion.put(userDevice, Boolean.TRUE);
|
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) {
|
public void resumePreKeyDeletion(OmemoDevice userDevice) {
|
||||||
synchronized (postponePreKeyDeletion) {
|
synchronized (postponePreKeyDeletion) {
|
||||||
postponePreKeyDeletion.put(userDevice, Boolean.FALSE);
|
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);
|
Set<Integer> preKeyIds = preKeyDeletionQueues.get(userDevice);
|
||||||
if (preKeyIds == null) {
|
if (preKeyIds == null) {
|
||||||
preKeyIds = new HashSet<>();
|
preKeyIds = new HashSet<>();
|
||||||
preKeyDeletionQueues.put(userDevice, preKeyIds);
|
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) {
|
public void deleteQueuedPreKeys(OmemoDevice userDevice) {
|
||||||
Set<Integer> queuedPreKeys = preKeyDeletionQueues.get(userDevice);
|
Set<Integer> queuedPreKeys = preKeyDeletionQueues.get(userDevice);
|
||||||
if (queuedPreKeys == null) {
|
if (queuedPreKeys == null) {
|
||||||
|
|
Loading…
Reference in New Issue