Use Signal's job framework for background polling

This commit is contained in:
Niels Andriesse
2019-07-22 10:50:35 +10:00
parent 19cdf8068d
commit d6cf9b573e
6 changed files with 70 additions and 31 deletions

View File

@@ -53,6 +53,7 @@ import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.logging.PersistentLogger;
import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger;
import org.thoughtcrime.securesms.loki.BackgroundPollWorker;
import org.thoughtcrime.securesms.loki.LokiAPIDatabase;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.providers.BlobProvider;
@@ -152,7 +153,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
executePendingContactSync();
KeyCachingService.onAppForegrounded(this);
// Loki - Start long polling if needed
startLongPolling();
startLongPollingIfNeeded();
// Loki - Stop background poll worker if needed
stopBackgroundPollingIfNeeded();
}
@Override
@@ -162,6 +165,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
KeyCachingService.onAppBackgrounded(this);
// Loki - Stop long polling if needed
if (lokiLongPoller != null) { lokiLongPoller.stopIfNeeded(); }
// Loki - Start background poll worker if needed
startBackgroundPollingIfNeeded();
}
@Override
@@ -284,6 +289,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
DirectoryRefreshListener.schedule(this);
LocalBackupListener.schedule(this);
RotateSenderCertificateListener.schedule(this);
BackgroundPollWorker.schedule(this); // Loki
if (BuildConfig.PLAY_STORE_DISABLED) {
UpdateApkRefreshListener.schedule(this);
@@ -393,31 +399,23 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
// TODO: Implement
}
public void startLongPolling() {
public void startLongPollingIfNeeded() {
setUpLongPollingIfNeeded();
if (lokiLongPoller != null) { lokiLongPoller.startIfNeeded(); }
}
private void setUpLongPollingIfNeeded() {
if (lokiLongPoller != null) return;
String hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this);
if (hexEncodedPublicKey == null) return;
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this);
if (userHexEncodedPublicKey == null) return;
LokiAPIDatabase database = DatabaseFactory.getLokiAPIDatabase(this);
Context context = this;
lokiLongPoller = new LokiLongPoller(hexEncodedPublicKey, database, new Function1<List<SignalServiceProtos.Envelope>, Unit>() {
lokiLongPoller = new LokiLongPoller(userHexEncodedPublicKey, database, new Function1<List<SignalServiceProtos.Envelope>, Unit>() {
@Override
public Unit invoke(List<SignalServiceProtos.Envelope> envelopes) {
for (SignalServiceProtos.Envelope proto : envelopes) {
SignalServiceEnvelope envelope;
if (proto.getSource() != null && proto.getSourceDevice() > 0) {
envelope = new SignalServiceEnvelope(proto.getType().getNumber(), proto.getSource(), proto.getSourceDevice(), proto.getTimestamp(),
proto.getLegacyMessage().toByteArray(), proto.getContent().toByteArray(), proto.getServerTimestamp(), proto.getServerGuid());
} else {
envelope = new SignalServiceEnvelope(proto.getType().getNumber(), proto.getTimestamp(), proto.getLegacyMessage().toByteArray(),
proto.getContent().toByteArray(), proto.getServerTimestamp(), proto.getServerGuid());
}
new PushContentReceiveJob(context).processEnvelope(envelope);
public Unit invoke(List<SignalServiceProtos.Envelope> protos) {
for (SignalServiceProtos.Envelope proto : protos) {
new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto));
}
return Unit.INSTANCE;
}

View File

@@ -1,20 +1,44 @@
package org.thoughtcrime.securesms.loki
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import android.content.Intent
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.jobs.PushContentReceiveJob
import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
import org.whispersystems.signalservice.loki.api.LokiAPI
import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol
import java.util.concurrent.TimeUnit
class BackgroundPollWorker(private val userHexEncodedPublicKey: String, private val apiDatabase: LokiAPIDatabaseProtocol, context: Context, parameters: WorkerParameters) : Worker(context, parameters) {
class BackgroundPollWorker : PersistentAlarmManagerListener() {
override fun doWork(): Result {
return try {
LokiAPI(userHexEncodedPublicKey, apiDatabase).getMessages().get()
// TODO: Process envelopes
Result.success()
} catch (exception: Exception) {
Result.failure()
companion object {
private val pollInterval = TimeUnit.MINUTES.toMillis(5)
@JvmStatic
fun schedule(context: Context) {
BackgroundPollWorker().onReceive(context, Intent())
}
}
}
override fun getNextScheduledExecutionTime(context: Context): Long {
return TextSecurePreferences.getBackgroundPollTime(context)
}
override fun onAlarm(context: Context, scheduledTime: Long): Long {
if (scheduledTime != 0L) {
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val apiDatabase = DatabaseFactory.getLokiAPIDatabase(context)
try {
LokiAPI(userHexEncodedPublicKey, apiDatabase).getMessages().get().forEach {
PushContentReceiveJob(context).processEnvelope(SignalServiceEnvelope(it))
}
} catch (exception: Throwable) {
// Do nothing
}
}
val nextTime = System.currentTimeMillis() + pollInterval
TextSecurePreferences.setBackgroundPollTime(context, nextTime)
return nextTime
}
}

View File

@@ -144,7 +144,7 @@ class KeyPairActivity : BaseActionBarActivity() {
TextSecurePreferences.setPromptedPushRegistration(this, true)
val application = ApplicationContext.getInstance(this)
application.setUpP2PAPI()
application.startLongPolling()
application.startLongPollingIfNeeded()
startActivity(Intent(this, ConversationListActivity::class.java))
finish()
}

View File

@@ -1126,4 +1126,12 @@ public class TextSecurePreferences {
return defaultValues;
}
}
public static long getBackgroundPollTime(Context context) {
return getLongPreference(context, "background_poll_time", 0L);
}
public static void setBackgroundPollTime(Context context, long backgroundPollTime) {
setLongPreference(context, "background_poll_time", backgroundPollTime);
}
}