kopia lustrzana https://github.com/ryukoposting/Signal-Android
91 wiersze
3.1 KiB
Java
91 wiersze
3.1 KiB
Java
package org.thoughtcrime.securesms.messages;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import org.signal.core.util.logging.Log;
|
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
|
import org.thoughtcrime.securesms.jobs.PushProcessMessageJob;
|
|
import org.whispersystems.signalservice.api.SignalWebSocket;
|
|
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Iterator;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.concurrent.TimeoutException;
|
|
|
|
class WebsocketStrategy extends MessageRetrievalStrategy {
|
|
|
|
private static final String TAG = Log.tag(WebsocketStrategy.class);
|
|
|
|
private final SignalWebSocket signalWebSocket;
|
|
private final JobManager jobManager;
|
|
|
|
public WebsocketStrategy() {
|
|
this.signalWebSocket = ApplicationDependencies.getSignalWebSocket();
|
|
this.jobManager = ApplicationDependencies.getJobManager();
|
|
}
|
|
|
|
@Override
|
|
public boolean execute(long timeout) {
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
try {
|
|
Set<String> processJobQueues = drainWebsocket(timeout, startTime);
|
|
Iterator<String> queueIterator = processJobQueues.iterator();
|
|
long timeRemaining = Math.max(0, timeout - (System.currentTimeMillis() - startTime));
|
|
|
|
while (!isCanceled() && queueIterator.hasNext() && timeRemaining > 0) {
|
|
String queue = queueIterator.next();
|
|
|
|
blockUntilQueueDrained(TAG, queue, timeRemaining);
|
|
|
|
timeRemaining = Math.max(0, timeout - (System.currentTimeMillis() - startTime));
|
|
}
|
|
|
|
return true;
|
|
} catch (IOException e) {
|
|
Log.w(TAG, "Encountered an exception while draining the websocket.", e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private @NonNull Set<String> drainWebsocket(long timeout, long startTime) throws IOException {
|
|
QueueFindingJobListener queueListener = new QueueFindingJobListener();
|
|
|
|
jobManager.addListener(job -> job.getParameters().getQueue() != null && job.getParameters().getQueue().startsWith(PushProcessMessageJob.QUEUE_PREFIX), queueListener);
|
|
|
|
try {
|
|
signalWebSocket.connect();
|
|
while (shouldContinue()) {
|
|
try {
|
|
Optional<SignalServiceEnvelope> result = signalWebSocket.readOrEmpty(timeout, envelope -> {
|
|
Log.i(TAG, "Retrieved envelope! " + envelope.getTimestamp() + timeSuffix(startTime));
|
|
try (IncomingMessageProcessor.Processor processor = ApplicationDependencies.getIncomingMessageProcessor().acquire()) {
|
|
processor.processEnvelope(envelope);
|
|
}
|
|
});
|
|
|
|
if (!result.isPresent()) {
|
|
Log.i(TAG, "Hit an empty response. Finished." + timeSuffix(startTime));
|
|
break;
|
|
}
|
|
} catch (TimeoutException e) {
|
|
Log.w(TAG, "Websocket timeout." + timeSuffix(startTime));
|
|
}
|
|
}
|
|
} finally {
|
|
signalWebSocket.disconnect();
|
|
jobManager.removeListener(queueListener);
|
|
}
|
|
|
|
return queueListener.getQueues();
|
|
}
|
|
|
|
|
|
private boolean shouldContinue() {
|
|
return !isCanceled();
|
|
}
|
|
}
|