diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1e4723557c..146151eee4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -541,8 +541,6 @@
-
-
UPGRADE_VERSIONS = new TreeSet() {{
add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
@@ -108,6 +114,7 @@ public class DatabaseUpgradeActivity extends BaseActivity {
add(FULL_TEXT_SEARCH);
add(BAD_IMPORT_CLEANUP);
add(IMAGE_CACHE_CLEANUP);
+ add(WORKMANAGER_MIGRATION);
}};
private MasterSecret masterSecret;
@@ -318,6 +325,18 @@ public class DatabaseUpgradeActivity extends BaseActivity {
}
}
+ if (params[0] < WORKMANAGER_MIGRATION) {
+ Log.i(TAG, "Beginning migration of existing jobs to WorkManager");
+
+ JobManager jobManager = ApplicationContext.getInstance(getApplicationContext()).getJobManager();
+ PersistentStorage storage = new PersistentStorage(getApplicationContext(), "TextSecureJobs", new JavaJobSerializer());
+
+ for (Job job : storage.getAllUnencrypted()) {
+ jobManager.add(job);
+ Log.i(TAG, "Migrated job with class '" + job.getClass().getSimpleName() + "' to run on new JobManager.");
+ }
+ }
+
return null;
}
diff --git a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java
index cbdb428dc2..eadc5cf896 100644
--- a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java
+++ b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java
@@ -254,7 +254,7 @@ public class QuickAttachmentDrawer extends ViewGroup implements InputView, Camer
@Override
protected boolean drawChild(@NonNull Canvas canvas, @NonNull View child, long drawingTime) {
boolean result;
- final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
+ final int save = canvas.save();
canvas.getClipBounds(drawChildrenRect);
if (child == coverView) {
diff --git a/src/org/thoughtcrime/securesms/jobmanager/Job.java b/src/org/thoughtcrime/securesms/jobmanager/Job.java
index 8735dd44da..b658b087b3 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/Job.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/Job.java
@@ -1,138 +1,139 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
package org.thoughtcrime.securesms.jobmanager;
-import android.os.PowerManager;
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
-import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
+import org.thoughtcrime.securesms.ApplicationContext;
+import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
+import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
+import org.thoughtcrime.securesms.logging.Log;
import java.io.Serializable;
-import java.util.List;
+import java.util.UUID;
-/**
- * An abstract class representing a unit of work that can be scheduled with
- * the JobManager. This should be extended to implement tasks.
- */
-public abstract class Job implements Serializable {
+import androidx.work.Data;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
- private final JobParameters parameters;
+public abstract class Job extends Worker implements Serializable {
- private transient long persistentId;
- private transient int runIteration;
- private transient long lastRunTime;
- private transient PowerManager.WakeLock wakeLock;
+ private static final long serialVersionUID = -4658540468214421276L;
- public Job(JobParameters parameters) {
- this.parameters = parameters;
- }
+ private static final String TAG = Job.class.getSimpleName();
- public List getRequirements() {
- return parameters.getRequirements();
- }
+ static final String KEY_RETRY_COUNT = "Job_retry_count";
+ static final String KEY_RETRY_UNTIL = "Job_retry_until";
+ static final String KEY_SUBMIT_TIME = "Job_submit_time";
+ static final String KEY_REQUIRES_MASTER_SECRET = "Job_requires_master_secret";
+ static final String KEY_REQUIRES_SQLCIPHER = "Job_requires_sqlcipher";
- public boolean isRequirementsMet() {
- for (Requirement requirement : parameters.getRequirements()) {
- if (!requirement.isPresent(this)) return false;
- }
+ private JobParameters parameters;
- return true;
- }
-
- public String getGroupId() {
- return parameters.getGroupId();
- }
-
- public boolean isPersistent() {
- return parameters.isPersistent();
- }
-
- public EncryptionKeys getEncryptionKeys() {
- return parameters.getEncryptionKeys();
- }
-
- public void setEncryptionKeys(EncryptionKeys keys) {
- parameters.setEncryptionKeys(keys);
- }
-
- public int getRetryCount() {
- return parameters.getRetryCount();
- }
-
- public long getRetryUntil() {
- return parameters.getRetryUntil();
- }
-
- public long getLastRunTime() {
- return lastRunTime;
- }
-
- public void resetRunStats() {
- runIteration = 0;
- lastRunTime = 0;
- }
-
- public void setPersistentId(long persistentId) {
- this.persistentId = persistentId;
- }
-
- public long getPersistentId() {
- return persistentId;
- }
-
- public int getRunIteration() {
- return runIteration;
- }
-
- public boolean needsWakeLock() {
- return parameters.needsWakeLock();
- }
-
- public long getWakeLockTimeout() {
- return parameters.getWakeLockTimeout();
- }
-
- public void setWakeLock(PowerManager.WakeLock wakeLock) {
- this.wakeLock = wakeLock;
- }
-
- public PowerManager.WakeLock getWakeLock() {
- return this.wakeLock;
- }
-
- public void onRetry() {
- runIteration++;
- lastRunTime = System.currentTimeMillis();
-
- for (Requirement requirement : parameters.getRequirements()) {
- requirement.onRetry(this);
- }
+ public Job(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
}
/**
- * Called after a job has been added to the JobManager queue. If it's a persistent job,
- * the state has been persisted to disk before this method is called.
+ * Invoked when a job is first created in our own codebase.
*/
- public abstract void onAdded();
+ protected Job(@Nullable JobParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @NonNull
+ @Override
+ public Result doWork() {
+ Data data = getInputData();
+
+ log("doWork()" + logSuffix());
+
+ ApplicationContext.getInstance(getApplicationContext()).ensureInitialized();
+ ApplicationContext.getInstance(getApplicationContext()).injectDependencies(this);
+
+ if (this instanceof ContextDependent) {
+ ((ContextDependent)this).setContext(getApplicationContext());
+ }
+
+ initialize(new SafeData(data));
+
+ try {
+ if (withinRetryLimits(data)) {
+ if (requirementsMet(data)) {
+ onRun();
+ log("Successfully completed." + logSuffix());
+ return Result.SUCCESS;
+ } else {
+ log("Retrying due to unmet requirements." + logSuffix());
+ return retry();
+ }
+ } else {
+ warn("Failing after hitting the retry limit." + logSuffix());
+ return cancel();
+ }
+ } catch (Exception e) {
+ if (onShouldRetry(e)) {
+ log("Retrying after a retryable exception." + logSuffix());
+ return retry();
+ }
+ warn("Failing due to an exception." + logSuffix(), e);
+ return cancel();
+ }
+ }
+
+ @Override
+ public void onStopped(boolean cancelled) {
+ if (cancelled) {
+ warn("onStopped() with cancellation signal." + logSuffix());
+ onCanceled();
+ }
+ }
+
+ final void onSubmit(UUID id) {
+ log(id, "onSubmit()");
+ onAdded();
+ }
+
+ /**
+ * Called after a run has finished and we've determined a retry is required, but before the next
+ * attempt is run.
+ */
+ protected void onRetry() { }
+
+ /**
+ * Called after a job has been added to the JobManager queue. Invoked off the main thread, so its
+ * safe to do longer-running work. However, work should finish relatively quickly, as it will
+ * block the submission of future tasks.
+ */
+ protected void onAdded() { }
+
+ /**
+ * All instance state needs to be persisted in the provided {@link Data.Builder} so that it can
+ * be restored in {@link #initialize(SafeData)}.
+ * @param dataBuilder The builder where you put your state.
+ * @return The result of {@code dataBuilder.build()}.
+ */
+ protected abstract @NonNull Data serialize(@NonNull Data.Builder dataBuilder);
+
+ /**
+ * Restore all of your instance state from the provided {@link Data}. It should contain all of
+ * the data put in during {@link #serialize(Data.Builder)}.
+ * @param data Where your data is stored.
+ */
+ protected abstract void initialize(@NonNull SafeData data);
/**
* Called to actually execute the job.
* @throws Exception
*/
- protected abstract void onRun() throws Exception;
+ public abstract void onRun() throws Exception;
+
+ /**
+ * Called if a job fails to run (onShouldRetry returned false, or the number of retries exceeded
+ * the job's configured retry count.
+ */
+ protected abstract void onCanceled();
/**
* If onRun() throws an exception, this method will be called to determine whether the
@@ -141,14 +142,69 @@ public abstract class Job implements Serializable {
* @param exception The exception onRun() threw.
* @return true if onRun() should be called again, false otherwise.
*/
- public abstract boolean onShouldRetry(Exception exception);
+ protected abstract boolean onShouldRetry(Exception exception);
- /**
- * Called if a job fails to run (onShouldRetry returned false, or the number of retries exceeded
- * the job's configured retry count.
- */
- public abstract void onCanceled();
+ @Nullable JobParameters getJobParameters() {
+ return parameters;
+ }
+ private Result retry() {
+ onRetry();
+ return Result.RETRY;
+ }
+ private Result cancel() {
+ onCanceled();
+ return Result.SUCCESS;
+ }
+ private boolean requirementsMet(Data data) {
+ boolean met = true;
+
+ if (data.getBoolean(KEY_REQUIRES_MASTER_SECRET, false)) {
+ met &= new MasterSecretRequirement(getApplicationContext()).isPresent();
+ }
+
+ if (data.getBoolean(KEY_REQUIRES_SQLCIPHER, false)) {
+ met &= new SqlCipherMigrationRequirement(getApplicationContext()).isPresent();
+ }
+
+ return met;
+ }
+
+ private boolean withinRetryLimits(Data data) {
+ int retryCount = data.getInt(KEY_RETRY_COUNT, 0);
+ long retryUntil = data.getLong(KEY_RETRY_UNTIL, 0);
+
+ if (retryCount > 0) {
+ return getRunAttemptCount() <= retryCount;
+ }
+
+ return System.currentTimeMillis() < retryUntil;
+ }
+
+ private void log(@NonNull String message) {
+ log(getId(), message);
+ }
+
+ private void log(@NonNull UUID id, @NonNull String message) {
+ Log.i(TAG, buildLog(id, message));
+ }
+
+ private void warn(@NonNull String message) {
+ warn(message, null);
+ }
+
+ private void warn(@NonNull String message, @Nullable Throwable t) {
+ Log.w(TAG, buildLog(getId(), message), t);
+ }
+
+ private String buildLog(@NonNull UUID id, @NonNull String message) {
+ return "[" + id + "] " + getClass().getSimpleName() + " :: " + message;
+ }
+
+ private String logSuffix() {
+ long timeSinceSubmission = System.currentTimeMillis() - getInputData().getLong(KEY_SUBMIT_TIME, 0);
+ return " (Time since submission: " + timeSinceSubmission + " ms, Run attempt: " + getRunAttemptCount() + ")";
+ }
}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/JobConsumer.java b/src/org/thoughtcrime/securesms/jobmanager/JobConsumer.java
deleted file mode 100644
index cbdb43be9e..0000000000
--- a/src/org/thoughtcrime/securesms/jobmanager/JobConsumer.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.jobmanager;
-
-import android.support.annotation.NonNull;
-import org.thoughtcrime.securesms.logging.Log;
-
-import org.thoughtcrime.securesms.jobmanager.persistence.PersistentStorage;
-
-class JobConsumer extends Thread {
-
- private static final String TAG = JobConsumer.class.getSimpleName();
-
- enum JobResult {
- SUCCESS,
- FAILURE,
- DEFERRED
- }
-
- private final JobQueue jobQueue;
- private final PersistentStorage persistentStorage;
-
- public JobConsumer(String name, JobQueue jobQueue, PersistentStorage persistentStorage) {
- super(name);
- this.jobQueue = jobQueue;
- this.persistentStorage = persistentStorage;
- }
-
- @Override
- public void run() {
- while (true) {
- Job job = jobQueue.getNext();
- JobResult result = runJob(job);
-
- if (result == JobResult.DEFERRED) {
- jobQueue.push(job);
- } else {
- if (result == JobResult.FAILURE) {
- job.onCanceled();
- }
-
- if (job.isPersistent()) {
- persistentStorage.remove(job.getPersistentId());
- }
-
- if (job.getWakeLock() != null && job.getWakeLockTimeout() == 0) {
- job.getWakeLock().release();
- }
-
- if (job.getGroupId() != null) {
- jobQueue.setGroupIdAvailable(job.getGroupId());
- }
- }
- }
- }
-
- private JobResult runJob(Job job) {
- while (canRetry(job)) {
- try {
- job.onRun();
- return JobResult.SUCCESS;
- } catch (Exception exception) {
- Log.w(TAG, exception);
- if (exception instanceof RuntimeException) {
- throw (RuntimeException)exception;
- } else if (!job.onShouldRetry(exception)) {
- return JobResult.FAILURE;
- }
-
- job.onRetry();
- if (!job.isRequirementsMet()) {
- return JobResult.DEFERRED;
- }
- }
- }
-
- return JobResult.FAILURE;
- }
-
- private boolean canRetry(@NonNull Job job) {
- if (job.getRetryCount() > 0) {
- return job.getRunIteration() < job.getRetryCount();
- }
- return System.currentTimeMillis() < job.getRetryUntil();
- }
-}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/JobManager.java b/src/org/thoughtcrime/securesms/jobmanager/JobManager.java
index c41956581f..c408d742ed 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/JobManager.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/JobManager.java
@@ -1,252 +1,69 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
package org.thoughtcrime.securesms.jobmanager;
-import android.content.Context;
-import android.os.PowerManager;
+import android.support.annotation.NonNull;
-import org.thoughtcrime.securesms.jobmanager.dependencies.AggregateDependencyInjector;
-import org.thoughtcrime.securesms.jobmanager.dependencies.DependencyInjector;
-import org.thoughtcrime.securesms.jobmanager.persistence.JobSerializer;
-import org.thoughtcrime.securesms.jobmanager.persistence.PersistentStorage;
-import org.thoughtcrime.securesms.jobmanager.requirements.RequirementListener;
-import org.thoughtcrime.securesms.jobmanager.requirements.RequirementProvider;
-import org.thoughtcrime.securesms.logging.Log;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.TimeUnit;
-/**
- * A JobManager allows you to enqueue {@link org.thoughtcrime.securesms.jobmanager.Job} tasks
- * that are executed once a Job's {@link org.thoughtcrime.securesms.jobmanager.requirements.Requirement}s
- * are met.
- */
-public class JobManager implements RequirementListener {
+import androidx.work.BackoffPolicy;
+import androidx.work.Constraints;
+import androidx.work.Data;
+import androidx.work.ExistingWorkPolicy;
+import androidx.work.NetworkType;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
- private final JobQueue jobQueue = new JobQueue();
- private final Executor eventExecutor = Executors.newSingleThreadExecutor();
- private final AtomicBoolean hasLoadedEncrypted = new AtomicBoolean(false);
+public class JobManager {
- private final Context context;
- private final PersistentStorage persistentStorage;
- private final List requirementProviders;
- private final AggregateDependencyInjector dependencyInjector;
+ private static final Constraints NETWORK_CONSTRAINT = new Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .build();
- private JobManager(Context context, String name,
- List requirementProviders,
- DependencyInjector dependencyInjector,
- JobSerializer jobSerializer, int consumers)
- {
- this.context = context;
- this.dependencyInjector = new AggregateDependencyInjector(dependencyInjector);
- this.persistentStorage = new PersistentStorage(context, name, jobSerializer, this.dependencyInjector);
- this.requirementProviders = requirementProviders;
+ private final Executor executor = Executors.newSingleThreadExecutor();
- eventExecutor.execute(new LoadTask(null));
+ private final WorkManager workManager;
- if (requirementProviders != null && !requirementProviders.isEmpty()) {
- for (RequirementProvider provider : requirementProviders) {
- provider.setListener(this);
+ public JobManager(@NonNull WorkManager workManager) {
+ this.workManager = workManager;
+ }
+
+ public void add(Job job) {
+ executor.execute(() -> {
+ workManager.synchronous().pruneWorkSync();
+
+ JobParameters jobParameters = job.getJobParameters();
+
+ if (jobParameters == null) {
+ throw new IllegalStateException("Jobs must have JobParameters at this stage.");
}
- }
- for (int i=0;i pendingJobs;
-
- if (keys == null) pendingJobs = persistentStorage.getAllUnencrypted();
- else pendingJobs = persistentStorage.getAllEncrypted(keys);
-
- jobQueue.addAll(pendingJobs);
- }
- }
-
- public static class Builder {
- private final Context context;
- private String name;
- private List requirementProviders;
- private DependencyInjector dependencyInjector;
- private JobSerializer jobSerializer;
- private int consumerThreads;
-
- Builder(Context context) {
- this.context = context;
- this.consumerThreads = 5;
- }
-
- /**
- * A name for the {@link org.thoughtcrime.securesms.jobmanager.JobManager}. This is a required parameter,
- * and is linked to the durable queue used by persistent jobs.
- *
- * @param name The name for the JobManager to build.
- * @return The builder.
- */
- public Builder withName(String name) {
- this.name = name;
- return this;
- }
-
- /**
- * The {@link org.thoughtcrime.securesms.jobmanager.requirements.RequirementProvider}s to register with this
- * JobManager. Optional. Each {@link org.thoughtcrime.securesms.jobmanager.requirements.Requirement} an
- * enqueued Job depends on should have a matching RequirementProvider registered here.
- *
- * @param requirementProviders The RequirementProviders
- * @return The builder.
- */
- public Builder withRequirementProviders(RequirementProvider... requirementProviders) {
- this.requirementProviders = Arrays.asList(requirementProviders);
- return this;
- }
-
- /**
- * The {@link org.thoughtcrime.securesms.jobmanager.dependencies.DependencyInjector} to use for injecting
- * dependencies into {@link Job}s. Optional. Injection occurs just before a Job's onAdded() callback, or
- * after deserializing a persistent job.
- *
- * @param dependencyInjector The injector to use.
- * @return The builder.
- */
- public Builder withDependencyInjector(DependencyInjector dependencyInjector) {
- this.dependencyInjector = dependencyInjector;
- return this;
- }
-
- /**
- * The {@link org.thoughtcrime.securesms.jobmanager.persistence.JobSerializer} to use for persistent Jobs.
- * Required if persistent Jobs are used.
- *
- * @param jobSerializer The serializer to use.
- * @return The builder.
- */
- public Builder withJobSerializer(JobSerializer jobSerializer) {
- this.jobSerializer = jobSerializer;
- return this;
- }
-
- /**
- * Set the number of threads dedicated to consuming Jobs from the queue and executing them.
- *
- * @param consumerThreads The number of threads.
- * @return The builder.
- */
- public Builder withConsumerThreads(int consumerThreads) {
- this.consumerThreads = consumerThreads;
- return this;
- }
-
- /**
- * @return A constructed JobManager.
- */
- public JobManager build() {
- if (name == null) {
- throw new IllegalArgumentException("You must specify a name!");
- }
-
- if (requirementProviders == null) {
- requirementProviders = new LinkedList<>();
- }
-
- return new JobManager(context, name, requirementProviders,
- dependencyInjector, jobSerializer,
- consumerThreads);
- }
- }
-
}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/JobParameters.java b/src/org/thoughtcrime/securesms/jobmanager/JobParameters.java
index 506747e4bd..910aea5839 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/JobParameters.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/JobParameters.java
@@ -16,12 +16,16 @@
*/
package org.thoughtcrime.securesms.jobmanager;
+import org.thoughtcrime.securesms.jobmanager.requirements.NetworkBackoffRequirement;
+import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
+import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobs.requirements.NetworkOrServiceRequirement;
+import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
import java.io.Serializable;
-import java.util.LinkedList;
+import java.util.Collections;
import java.util.List;
-import java.util.concurrent.TimeUnit;
/**
* The set of parameters that describe a {@link org.thoughtcrime.securesms.jobmanager.Job}.
@@ -30,46 +34,86 @@ public class JobParameters implements Serializable {
private static final long serialVersionUID = 4880456378402584584L;
- private transient EncryptionKeys encryptionKeys;
-
private final List requirements;
- private final boolean isPersistent;
+ private final boolean requiresNetwork;
+ private final boolean requiresMasterSecret;
+ private final boolean requiresSqlCipher;
private final int retryCount;
private final long retryUntil;
private final String groupId;
- private final boolean wakeLock;
- private final long wakeLockTimeout;
+ private final boolean ignoreDuplicates;
- private JobParameters(List requirements,
- boolean isPersistent, String groupId,
- EncryptionKeys encryptionKeys,
- int retryCount, long retryUntil, boolean wakeLock,
- long wakeLockTimeout)
+ private JobParameters(String groupId,
+ boolean ignoreDuplicates,
+ boolean requiresNetwork,
+ boolean requiresMasterSecret,
+ boolean requiresSqlCipher,
+ int retryCount,
+ long retryUntil)
{
- this.requirements = requirements;
- this.isPersistent = isPersistent;
- this.groupId = groupId;
- this.encryptionKeys = encryptionKeys;
- this.retryCount = retryCount;
- this.retryUntil = retryUntil;
- this.wakeLock = wakeLock;
- this.wakeLockTimeout = wakeLockTimeout;
+ this.groupId = groupId;
+ this.ignoreDuplicates = ignoreDuplicates;
+ this.requirements = Collections.emptyList();
+ this.requiresNetwork = requiresNetwork;
+ this.requiresMasterSecret = requiresMasterSecret;
+ this.requiresSqlCipher = requiresSqlCipher;
+ this.retryCount = retryCount;
+ this.retryUntil = retryUntil;
}
- public List getRequirements() {
- return requirements;
+ public boolean shouldIgnoreDuplicates() {
+ return ignoreDuplicates;
}
- public boolean isPersistent() {
- return isPersistent;
+ public boolean requiresNetwork() {
+ return requiresNetwork || hasNetworkRequirement(requirements);
}
- public EncryptionKeys getEncryptionKeys() {
- return encryptionKeys;
+ public boolean requiresMasterSecret() {
+ return requiresMasterSecret || hasMasterSecretRequirement(requirements);
}
- public void setEncryptionKeys(EncryptionKeys encryptionKeys) {
- this.encryptionKeys = encryptionKeys;
+ public boolean requiresSqlCipher() {
+ return requiresSqlCipher || hasSqlCipherRequirement(requirements);
+ }
+
+ private boolean hasNetworkRequirement(List requirements) {
+ if (requirements == null || requirements.size() == 0) return false;
+
+ for (Requirement requirement : requirements) {
+ if (requirement instanceof NetworkRequirement ||
+ requirement instanceof NetworkOrServiceRequirement ||
+ requirement instanceof NetworkBackoffRequirement)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasMasterSecretRequirement(List requirements) {
+ if (requirements == null || requirements.size() == 0) return false;
+
+ for (Requirement requirement : requirements) {
+ if (requirement instanceof MasterSecretRequirement) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasSqlCipherRequirement(List requirements) {
+ if (requirements == null || requirements.size() == 0) return false;
+
+ for (Requirement requirement : requirements) {
+ if (requirement instanceof SqlCipherMigrationRequirement) {
+ return true;
+ }
+ }
+
+ return false;
}
public int getRetryCount() {
@@ -91,52 +135,29 @@ public class JobParameters implements Serializable {
return groupId;
}
- public boolean needsWakeLock() {
- return wakeLock;
- }
-
- public long getWakeLockTimeout() {
- return wakeLockTimeout;
- }
-
public static class Builder {
- private List requirements = new LinkedList<>();
- private boolean isPersistent = false;
- private EncryptionKeys encryptionKeys = null;
- private int retryCount = 100;
- private long retryDuration = 0;
- private String groupId = null;
- private boolean wakeLock = false;
- private long wakeLockTimeout = 0;
+ private int retryCount = 100;
+ private long retryDuration = 0;
+ private String groupId = null;
+ private boolean ignoreDuplicates = false;
+ private boolean requiresNetwork = false;
+ private boolean requiresSqlCipher = false;
+ private boolean requiresMasterSecret = false;
- /**
- * Specify a {@link org.thoughtcrime.securesms.jobmanager.requirements.Requirement }that must be met
- * before the Job is executed. May be called multiple times to register multiple requirements.
- * @param requirement The Requirement that must be met.
- * @return the builder.
- */
- public Builder withRequirement(Requirement requirement) {
- this.requirements.add(requirement);
+ public Builder withNetworkRequirement() {
+ requiresNetwork = true;
return this;
}
- /**
- * Specify that the Job should be durably persisted to disk, so that it remains in the queue
- * across application restarts.
- * @return The builder.
- */
- public Builder withPersistence() {
- this.isPersistent = true;
+ @Deprecated
+ public Builder withMasterSecretRequirement() {
+ requiresMasterSecret = true;
return this;
}
- /**
- * Specify that the job should use encryption when durably persisted to disk.
- * @param encryptionKeys The keys to encrypt the serialized job with before persisting.
- * @return the builder.
- */
- public Builder withEncryption(EncryptionKeys encryptionKeys) {
- this.encryptionKeys = encryptionKeys;
+ @Deprecated
+ public Builder withSqlCipherRequirement() {
+ requiresSqlCipher = true;
return this;
}
@@ -153,6 +174,11 @@ public class JobParameters implements Serializable {
return this;
}
+ /**
+ * Specify for how long we should keep retrying this job. Ignored if retryCount is set.
+ * @param duration The duration (in ms) for how long we should keep retrying this job for.
+ * @return the builder
+ */
public Builder withRetryDuration(long duration) {
this.retryDuration = duration;
this.retryCount = 0;
@@ -172,35 +198,25 @@ public class JobParameters implements Serializable {
}
/**
- * Specify whether this job should hold a wake lock.
+ * If true, only one job with this groupId can be active at a time. If a job with the same
+ * groupId is already running, then subsequent jobs will be ignored silently. Only has an effect
+ * if a groupId has been specified via {@link #withGroupId(String)}.
+ *
+ * Defaults to false.
*
- * @param needsWakeLock If set, this job will acquire a wakelock on add(), and hold it until
- * run() completes, or cancel().
- * @param timeout Specify a timeout for the wakelock. A timeout of
- * 0 will result in no timeout.
- *
- * @return the builder.
+ * @param ignoreDuplicates Whether to ignore duplicates.
+ * @return the builder
*/
- public Builder withWakeLock(boolean needsWakeLock, long timeout, TimeUnit unit) {
- this.wakeLock = needsWakeLock;
- this.wakeLockTimeout = unit.toMillis(timeout);
+ public Builder withDuplicatesIgnored(boolean ignoreDuplicates) {
+ this.ignoreDuplicates = ignoreDuplicates;
return this;
}
- /**
- * Specify whether this job should hold a wake lock.
- *
- * @return the builder.
- */
- public Builder withWakeLock(boolean needsWakeLock) {
- return withWakeLock(needsWakeLock, 0, TimeUnit.MILLISECONDS);
- }
-
/**
* @return the JobParameters instance that describes a Job.
*/
public JobParameters create() {
- return new JobParameters(requirements, isPersistent, groupId, encryptionKeys, retryCount, System.currentTimeMillis() + retryDuration, wakeLock, wakeLockTimeout);
+ return new JobParameters(groupId, ignoreDuplicates, requiresNetwork, requiresMasterSecret, requiresSqlCipher, retryCount, System.currentTimeMillis() + retryDuration);
}
}
}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/JobQueue.java b/src/org/thoughtcrime/securesms/jobmanager/JobQueue.java
deleted file mode 100644
index 07d986e69d..0000000000
--- a/src/org/thoughtcrime/securesms/jobmanager/JobQueue.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.jobmanager;
-
-import android.support.annotation.NonNull;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-class JobQueue {
-
- private final Map activeGroupIds = new HashMap<>();
- private final LinkedList jobQueue = new LinkedList<>();
-
- synchronized void onRequirementStatusChanged() {
- notifyAll();
- }
-
- synchronized void add(Job job) {
- jobQueue.add(job);
- processJobAddition(job);
- notifyAll();
- }
-
- synchronized void addAll(List jobs) {
- jobQueue.addAll(jobs);
-
- for (Job job : jobs) {
- processJobAddition(job);
- }
-
- notifyAll();
- }
-
- private void processJobAddition(@NonNull Job job) {
- if (isJobActive(job) && isGroupIdAvailable(job)) {
- setGroupIdUnavailable(job);
- } else if (!isGroupIdAvailable(job)) {
- Job blockingJob = activeGroupIds.get(job.getGroupId());
- blockingJob.resetRunStats();
- }
- }
-
- synchronized void push(Job job) {
- jobQueue.addFirst(job);
- }
-
- synchronized Job getNext() {
- try {
- Job nextAvailableJob;
-
- while ((nextAvailableJob = getNextAvailableJob()) == null) {
- wait();
- }
-
- return nextAvailableJob;
- } catch (InterruptedException e) {
- throw new AssertionError(e);
- }
- }
-
- synchronized void setGroupIdAvailable(String groupId) {
- if (groupId != null) {
- activeGroupIds.remove(groupId);
- notifyAll();
- }
- }
-
- private Job getNextAvailableJob() {
- if (jobQueue.isEmpty()) return null;
-
- ListIterator iterator = jobQueue.listIterator();
- while (iterator.hasNext()) {
- Job job = iterator.next();
-
- if (job.isRequirementsMet() && isGroupIdAvailable(job)) {
- iterator.remove();
- setGroupIdUnavailable(job);
- return job;
- }
- }
-
- return null;
- }
-
- private boolean isJobActive(@NonNull Job job) {
- return job.getRetryUntil() > 0 && job.getRunIteration() > 0;
- }
-
- private boolean isGroupIdAvailable(@NonNull Job requester) {
- String groupId = requester.getGroupId();
- return groupId == null || !activeGroupIds.containsKey(groupId) || activeGroupIds.get(groupId).equals(requester);
- }
-
- private void setGroupIdUnavailable(@NonNull Job job) {
- String groupId = job.getGroupId();
- if (groupId != null) {
- activeGroupIds.put(groupId, job);
- }
- }
-}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/SafeData.java b/src/org/thoughtcrime/securesms/jobmanager/SafeData.java
new file mode 100644
index 0000000000..642ab84e0e
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/jobmanager/SafeData.java
@@ -0,0 +1,80 @@
+package org.thoughtcrime.securesms.jobmanager;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import androidx.work.Data;
+
+/**
+ * A wrapper around {@link Data} that does its best to throw an exception whenever a key isn't
+ * present in the {@link Data} object.
+ */
+public class SafeData {
+
+ private final static int INVALID_INT = Integer.MIN_VALUE;
+ private final static long INVALID_LONG = Long.MIN_VALUE;
+
+ private final Data data;
+
+ public SafeData(@NonNull Data data) {
+ this.data = data;
+ }
+
+ public int getInt(@NonNull String key) {
+ int value = data.getInt(key, INVALID_INT);
+
+ if (value == INVALID_INT) {
+ throw new IllegalStateException("Missing key: " + key);
+ }
+
+ return value;
+ }
+
+ public long getLong(@NonNull String key) {
+ long value = data.getLong(key, INVALID_LONG);
+
+ if (value == INVALID_LONG) {
+ throw new IllegalStateException("Missing key: " + key);
+ }
+
+ return value;
+ }
+
+ public @NonNull String getString(@NonNull String key) {
+ String value = data.getString(key);
+
+ if (value == null) {
+ throw new IllegalStateException("Missing key: " + key);
+ }
+
+ return value;
+ }
+
+ public @Nullable String getNullableString(@NonNull String key) {
+ return data.getString(key);
+ }
+
+ public @NonNull String[] getStringArray(@NonNull String key) {
+ String[] value = data.getStringArray(key);
+
+ if (value == null) {
+ throw new IllegalStateException("Missing key: " + key);
+ }
+
+ return value;
+ }
+
+ public @NonNull long[] getLongArray(@NonNull String key) {
+ long[] value = data.getLongArray(key);
+
+ if (value == null) {
+ throw new IllegalStateException("Missing key: " + key);
+ }
+
+ return value;
+ }
+
+ public boolean getBoolean(@NonNull String key, boolean defaultValue) {
+ return data.getBoolean(key, defaultValue);
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/dependencies/AggregateDependencyInjector.java b/src/org/thoughtcrime/securesms/jobmanager/dependencies/AggregateDependencyInjector.java
deleted file mode 100644
index c855314b7c..0000000000
--- a/src/org/thoughtcrime/securesms/jobmanager/dependencies/AggregateDependencyInjector.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.thoughtcrime.securesms.jobmanager.dependencies;
-
-import android.content.Context;
-
-import org.thoughtcrime.securesms.jobmanager.Job;
-import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
-
-public class AggregateDependencyInjector {
-
- private final DependencyInjector dependencyInjector;
-
- public AggregateDependencyInjector(DependencyInjector dependencyInjector) {
- this.dependencyInjector = dependencyInjector;
- }
-
- public void injectDependencies(Context context, Job job) {
- if (job instanceof ContextDependent) {
- ((ContextDependent)job).setContext(context);
- }
-
- for (Requirement requirement : job.getRequirements()) {
- if (requirement instanceof ContextDependent) {
- ((ContextDependent)requirement).setContext(context);
- }
- }
-
- if (dependencyInjector != null) {
- dependencyInjector.injectDependencies(job);
-
- for (Requirement requirement : job.getRequirements()) {
- dependencyInjector.injectDependencies(requirement);
- }
- }
- }
-
-}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/persistence/PersistentStorage.java b/src/org/thoughtcrime/securesms/jobmanager/persistence/PersistentStorage.java
index 7bd9ed6904..4da766f77f 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/persistence/PersistentStorage.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/persistence/PersistentStorage.java
@@ -16,7 +16,6 @@
*/
package org.thoughtcrime.securesms.jobmanager.persistence;
-import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
@@ -24,7 +23,6 @@ import android.database.sqlite.SQLiteOpenHelper;
import org.thoughtcrime.securesms.jobmanager.EncryptionKeys;
import org.thoughtcrime.securesms.jobmanager.Job;
-import org.thoughtcrime.securesms.jobmanager.dependencies.AggregateDependencyInjector;
import org.thoughtcrime.securesms.logging.Log;
import java.io.IOException;
@@ -43,38 +41,18 @@ public class PersistentStorage {
private static final String DATABASE_CREATE = String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s TEXT NOT NULL, %s INTEGER DEFAULT 0);",
TABLE_NAME, ID, ITEM, ENCRYPTED);
- private final Context context;
- private final DatabaseHelper databaseHelper;
- private final JobSerializer jobSerializer;
- private final AggregateDependencyInjector dependencyInjector;
+ private final DatabaseHelper databaseHelper;
+ private final JobSerializer jobSerializer;
- public PersistentStorage(Context context, String name,
- JobSerializer serializer,
- AggregateDependencyInjector dependencyInjector)
- {
+ public PersistentStorage(Context context, String name, JobSerializer serializer) {
this.databaseHelper = new DatabaseHelper(context, "_jobqueue-" + name);
- this.context = context;
this.jobSerializer = serializer;
- this.dependencyInjector = dependencyInjector;
- }
-
- public void store(Job job) throws IOException {
- ContentValues contentValues = new ContentValues();
- contentValues.put(ITEM, jobSerializer.serialize(job));
- contentValues.put(ENCRYPTED, job.getEncryptionKeys() != null);
-
- long id = databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, contentValues);
- job.setPersistentId(id);
}
public List getAllUnencrypted() {
return getJobs(null, ENCRYPTED + " = 0");
}
- public List getAllEncrypted(EncryptionKeys keys) {
- return getJobs(keys, ENCRYPTED + " = 1");
- }
-
private List getJobs(EncryptionKeys keys, String where) {
List results = new LinkedList<>();
SQLiteDatabase database = databaseHelper.getReadableDatabase();
@@ -90,11 +68,6 @@ public class PersistentStorage {
try{
Job job = jobSerializer.deserialize(keys, encrypted, item);
-
- job.setPersistentId(id);
- job.setEncryptionKeys(keys);
- dependencyInjector.injectDependencies(context, job);
-
results.add(job);
} catch (IOException e) {
Log.w("PersistentStore", e);
diff --git a/src/org/thoughtcrime/securesms/jobmanager/requirements/BackoffReceiver.java b/src/org/thoughtcrime/securesms/jobmanager/requirements/BackoffReceiver.java
deleted file mode 100644
index 203c93aeb7..0000000000
--- a/src/org/thoughtcrime/securesms/jobmanager/requirements/BackoffReceiver.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.thoughtcrime.securesms.jobmanager.requirements;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.support.annotation.NonNull;
-
-import org.thoughtcrime.securesms.ApplicationContext;
-import org.thoughtcrime.securesms.BuildConfig;
-import org.thoughtcrime.securesms.logging.Log;
-
-import java.util.UUID;
-
-public class BackoffReceiver extends BroadcastReceiver {
-
- private static final String TAG = BackoffReceiver.class.getSimpleName();
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i(TAG, "Received an alarm to retry a job with ID: " + intent.getAction());
- ApplicationContext.getInstance(context).getJobManager().onRequirementStatusChanged();
- }
-
- public static void setUniqueAlarm(@NonNull Context context, long time) {
- AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- Intent intent = new Intent(context, BackoffReceiver.class);
-
- intent.setAction(BuildConfig.APPLICATION_ID + UUID.randomUUID().toString());
- alarmManager.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(context, 0, intent, 0));
-
- Log.i(TAG, "Set an alarm to retry a job in " + (time - System.currentTimeMillis()) + " ms with ID: " + intent.getAction());
- }
-}
diff --git a/src/org/thoughtcrime/securesms/jobmanager/requirements/NetworkBackoffRequirement.java b/src/org/thoughtcrime/securesms/jobmanager/requirements/NetworkBackoffRequirement.java
index 5c5667cbc2..147f4342b7 100644
--- a/src/org/thoughtcrime/securesms/jobmanager/requirements/NetworkBackoffRequirement.java
+++ b/src/org/thoughtcrime/securesms/jobmanager/requirements/NetworkBackoffRequirement.java
@@ -31,15 +31,6 @@ public class NetworkBackoffRequirement implements Requirement, ContextDependent
@Override
public void onRetry(@NonNull Job job) {
- Log.i(TAG, "onRetry()");
-
- if (!(new NetworkRequirement(context).isPresent())) {
- Log.i(TAG, "No network. Resetting run stats.");
- job.resetRunStats();
- return;
- }
-
- BackoffReceiver.setUniqueAlarm(context, NetworkBackoffRequirement.calculateNextRunTime(job));
}
@Override
@@ -48,9 +39,6 @@ public class NetworkBackoffRequirement implements Requirement, ContextDependent
}
private static long calculateNextRunTime(@NonNull Job job) {
- long targetTime = job.getLastRunTime() + (long) (Math.pow(2, job.getRunIteration() - 1) * 1000);
- long furthestTime = System.currentTimeMillis() + MAX_WAIT;
-
- return Math.min(targetTime, Math.min(furthestTime, job.getRetryUntil()));
+ return 0;
}
}
diff --git a/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java
index 6099abad0b..deebfc252d 100644
--- a/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java
@@ -1,8 +1,11 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.greenrobot.eventbus.EventBus;
@@ -15,8 +18,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.util.AttachmentUtil;
@@ -36,24 +37,34 @@ import java.io.InputStream;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class AttachmentDownloadJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 2L;
private static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024;
private static final String TAG = AttachmentDownloadJob.class.getSimpleName();
+ private static final String KEY_MESSAGE_ID = "message_id";
+ private static final String KEY_PART_ROW_ID = "part_row_id";
+ private static final String KEY_PAR_UNIQUE_ID = "part_unique_id";
+ private static final String KEY_MANUAL = "part_manual";
+
@Inject transient SignalServiceMessageReceiver messageReceiver;
- private final long messageId;
- private final long partRowId;
- private final long partUniqueId;
- private final boolean manual;
+ private long messageId;
+ private long partRowId;
+ private long partUniqueId;
+ private boolean manual;
+
+ public AttachmentDownloadJob() {
+ super(null, null);
+ }
public AttachmentDownloadJob(Context context, long messageId, AttachmentId attachmentId, boolean manual) {
super(context, JobParameters.newBuilder()
.withGroupId(AttachmentDownloadJob.class.getCanonicalName())
- .withRequirement(new MasterSecretRequirement(context))
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withMasterSecretRequirement()
+ .withNetworkRequirement()
.create());
this.messageId = messageId;
@@ -62,6 +73,23 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
this.manual = manual;
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ partRowId = data.getLong(KEY_PART_ROW_ID);
+ partUniqueId = data.getLong(KEY_PAR_UNIQUE_ID);
+ manual = data.getBoolean(KEY_MANUAL, false);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
+ .putLong(KEY_PART_ROW_ID, partRowId)
+ .putLong(KEY_PAR_UNIQUE_ID, partUniqueId)
+ .putBoolean(KEY_MANUAL, manual)
+ .build();
+ }
+
@Override
public void onAdded() {
Log.i(TAG, "onAdded() messageId: " + messageId + " partRowId: " + partRowId + " partUniqueId: " + partUniqueId + " manual: " + manual);
diff --git a/src/org/thoughtcrime/securesms/jobs/AttachmentFileNameJob.java b/src/org/thoughtcrime/securesms/jobs/AttachmentFileNameJob.java
deleted file mode 100644
index a7d30e29f9..0000000000
--- a/src/org/thoughtcrime/securesms/jobs/AttachmentFileNameJob.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.thoughtcrime.securesms.jobs;
-
-
-import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import org.thoughtcrime.securesms.attachments.Attachment;
-import org.thoughtcrime.securesms.attachments.AttachmentId;
-import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
-import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher;
-import org.thoughtcrime.securesms.crypto.AsymmetricMasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.database.DatabaseFactory;
-import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
-import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
-import org.whispersystems.libsignal.InvalidMessageException;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-public class AttachmentFileNameJob extends MasterSecretJob {
-
- private static final long serialVersionUID = 1L;
-
- private final long attachmentRowId;
- private final long attachmentUniqueId;
- private final String encryptedFileName;
-
- public AttachmentFileNameJob(@NonNull Context context, @NonNull AsymmetricMasterSecret asymmetricMasterSecret,
- @NonNull DatabaseAttachment attachment, @NonNull IncomingMediaMessage message)
- {
- super(context, new JobParameters.Builder().withPersistence()
- .withRequirement(new MasterSecretRequirement(context))
- .create());
-
- this.attachmentRowId = attachment.getAttachmentId().getRowId();
- this.attachmentUniqueId = attachment.getAttachmentId().getUniqueId();
- this.encryptedFileName = getEncryptedFileName(asymmetricMasterSecret, attachment, message);
- }
-
- @Override
- public void onRun(MasterSecret masterSecret) throws IOException, InvalidMessageException {
- if (encryptedFileName == null) return;
-
- AttachmentId attachmentId = new AttachmentId(attachmentRowId, attachmentUniqueId);
- String plaintextFileName = new AsymmetricMasterCipher(MasterSecretUtil.getAsymmetricMasterSecret(context, masterSecret)).decryptBody(encryptedFileName);
-
- DatabaseFactory.getAttachmentDatabase(context).updateAttachmentFileName(attachmentId, plaintextFileName);
- }
-
- @Override
- public boolean onShouldRetryThrowable(Exception exception) {
- return false;
- }
-
- @Override
- public void onAdded() {
-
- }
-
- @Override
- public void onCanceled() {
-
- }
-
- private @Nullable String getEncryptedFileName(@NonNull AsymmetricMasterSecret asymmetricMasterSecret,
- @NonNull DatabaseAttachment attachment,
- @NonNull IncomingMediaMessage mediaMessage)
- {
- for (Attachment messageAttachment : mediaMessage.getAttachments()) {
- if (mediaMessage.getAttachments().size() == 1 ||
- (messageAttachment.getDigest() != null && Arrays.equals(messageAttachment.getDigest(), attachment.getDigest())))
- {
- if (messageAttachment.getFileName() == null) return null;
- else return new AsymmetricMasterCipher(asymmetricMasterSecret).encryptBody(messageAttachment.getFileName());
- }
- }
-
- return null;
- }
-
-
-}
diff --git a/src/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java
index 327504f1e5..3a07f1f079 100644
--- a/src/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java
@@ -10,8 +10,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
@@ -30,6 +29,8 @@ import java.io.InputStream;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class AvatarDownloadJob extends MasterSecretJob implements InjectableType {
private static final int MAX_AVATAR_SIZE = 20 * 1024 * 1024;
@@ -37,22 +38,38 @@ public class AvatarDownloadJob extends MasterSecretJob implements InjectableType
private static final String TAG = AvatarDownloadJob.class.getSimpleName();
+ private static final String KEY_GROUP_ID = "group_id";
+
@Inject transient SignalServiceMessageReceiver receiver;
- private final byte[] groupId;
+ private byte[] groupId;
+
+ public AvatarDownloadJob() {
+ super(null, null);
+ }
public AvatarDownloadJob(Context context, @NonNull byte[] groupId) {
super(context, JobParameters.newBuilder()
- .withRequirement(new MasterSecretRequirement(context))
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withMasterSecretRequirement()
+ .withNetworkRequirement()
.create());
this.groupId = groupId;
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ try {
+ groupId = GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false)).build();
+ }
@Override
public void onRun(MasterSecret masterSecret) throws IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java b/src/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java
index a78379584e..618567e6f8 100644
--- a/src/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java
@@ -1,13 +1,15 @@
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.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyStore;
@@ -24,6 +26,8 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
import static org.thoughtcrime.securesms.dependencies.AxolotlStorageModule.SignedPreKeyStoreFactory;
public class CleanPreKeysJob extends MasterSecretJob implements InjectableType {
@@ -35,17 +39,25 @@ public class CleanPreKeysJob extends MasterSecretJob implements InjectableType {
@Inject transient SignalServiceAccountManager accountManager;
@Inject transient SignedPreKeyStoreFactory signedPreKeyStoreFactory;
+ public CleanPreKeysJob() {
+ super(null, null);
+ }
+
public CleanPreKeysJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(CleanPreKeysJob.class.getSimpleName())
- .withRequirement(new MasterSecretRequirement(context))
+ .withMasterSecretRequirement()
.withRetryCount(5)
.create());
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java b/src/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java
index 153564872b..6e377b9d31 100644
--- a/src/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java
@@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
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.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -20,6 +20,8 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class CreateSignedPreKeyJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 1L;
@@ -28,17 +30,26 @@ public class CreateSignedPreKeyJob extends MasterSecretJob implements Injectable
@Inject transient SignalServiceAccountManager accountManager;
+ public CreateSignedPreKeyJob() {
+ super(null, null);
+ }
+
public CreateSignedPreKeyJob(Context context) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withGroupId(CreateSignedPreKeyJob.class.getSimpleName())
.create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun(MasterSecret masterSecret) throws IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java b/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
index f03362461d..20409eaa01 100644
--- a/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/DirectoryRefreshJob.java
@@ -1,26 +1,36 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
-import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+
+import org.thoughtcrime.securesms.database.Address;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
+import androidx.work.Data;
+
public class DirectoryRefreshJob extends ContextJob {
private static final String TAG = DirectoryRefreshJob.class.getSimpleName();
+ private static final String KEY_ADDRESS = "address";
+ private static final String KEY_NOTIFY_OF_NEW_USERS = "notify_of_new_users";
+
@Nullable private transient Recipient recipient;
private transient boolean notifyOfNewUsers;
+ public DirectoryRefreshJob() {
+ super(null, null);
+ }
+
public DirectoryRefreshJob(@NonNull Context context, boolean notifyOfNewUsers) {
this(context, null, notifyOfNewUsers);
}
@@ -31,7 +41,7 @@ public class DirectoryRefreshJob extends ContextJob {
{
super(context, JobParameters.newBuilder()
.withGroupId(DirectoryRefreshJob.class.getSimpleName())
- .withRequirement(new NetworkRequirement(context))
+ .withNetworkRequirement()
.create());
this.recipient = recipient;
@@ -39,23 +49,29 @@ public class DirectoryRefreshJob extends ContextJob {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ String serializedAddress = data.getNullableString(KEY_ADDRESS);
+ Address address = serializedAddress != null ? Address.fromSerialized(serializedAddress) : null;
+
+ recipient = address != null ? Recipient.from(context, address, true) : null;
+ notifyOfNewUsers = data.getBoolean(KEY_NOTIFY_OF_NEW_USERS, false);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_ADDRESS, recipient != null ? recipient.getAddress().serialize() : null)
+ .putBoolean(KEY_NOTIFY_OF_NEW_USERS, notifyOfNewUsers)
+ .build();
+ }
@Override
public void onRun() throws IOException {
Log.i(TAG, "DirectoryRefreshJob.onRun()");
- PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Directory Refresh");
- try {
- wakeLock.acquire();
- if (recipient == null) {
- DirectoryHelper.refreshDirectory(context, notifyOfNewUsers);
- } else {
- DirectoryHelper.refreshDirectoryFor(context, recipient);
- }
- } finally {
- if (wakeLock.isHeld()) wakeLock.release();
+ if (recipient == null) {
+ DirectoryHelper.refreshDirectory(context, notifyOfNewUsers);
+ } else {
+ DirectoryHelper.refreshDirectoryFor(context, recipient);
}
}
diff --git a/src/org/thoughtcrime/securesms/jobs/GcmRefreshJob.java b/src/org/thoughtcrime/securesms/jobs/GcmRefreshJob.java
index 11663b51eb..561014dcfa 100644
--- a/src/org/thoughtcrime/securesms/jobs/GcmRefreshJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/GcmRefreshJob.java
@@ -21,7 +21,10 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
+import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import com.google.android.gms.common.ConnectionResult;
@@ -32,7 +35,6 @@ import org.thoughtcrime.securesms.PlayServicesProblemActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
@@ -41,6 +43,8 @@ import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulRespons
import javax.inject.Inject;
+import androidx.work.Data;
+
public class GcmRefreshJob extends ContextJob implements InjectableType {
private static final String TAG = GcmRefreshJob.class.getSimpleName();
@@ -49,15 +53,27 @@ public class GcmRefreshJob extends ContextJob implements InjectableType {
@Inject transient SignalServiceAccountManager textSecureAccountManager;
+ public GcmRefreshJob() {
+ super(null, null);
+ }
+
public GcmRefreshJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
+ .withGroupId(GcmRefreshJob.class.getSimpleName())
+ .withDuplicatesIgnored(true)
+ .withNetworkRequirement()
.withRetryCount(1)
.create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun() throws Exception {
diff --git a/src/org/thoughtcrime/securesms/jobs/LocalBackupJob.java b/src/org/thoughtcrime/securesms/jobs/LocalBackupJob.java
index d8faf1fd84..72d1558e4f 100644
--- a/src/org/thoughtcrime/securesms/jobs/LocalBackupJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/LocalBackupJob.java
@@ -4,6 +4,8 @@ package org.thoughtcrime.securesms.jobs;
import android.Manifest;
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.R;
@@ -24,21 +26,32 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
-import java.util.concurrent.TimeUnit;
+
+import androidx.work.Data;
public class LocalBackupJob extends ContextJob {
private static final String TAG = LocalBackupJob.class.getSimpleName();
+ public LocalBackupJob() {
+ super(null, null);
+ }
+
public LocalBackupJob(@NonNull Context context) {
super(context, JobParameters.newBuilder()
.withGroupId("__LOCAL_BACKUP__")
- .withWakeLock(true, 10, TimeUnit.SECONDS)
+ .withDuplicatesIgnored(true)
.create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun() throws NoExternalStorageException, IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java
index 23b38f8ad3..fa50125167 100644
--- a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java
@@ -2,7 +2,10 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.net.Uri;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import com.google.android.mms.pdu_alt.CharacterSets;
@@ -20,8 +23,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.ApnUnavailableException;
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
@@ -45,7 +46,8 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
+
+import androidx.work.Data;
public class MmsDownloadJob extends MasterSecretJob {
@@ -53,17 +55,23 @@ public class MmsDownloadJob extends MasterSecretJob {
private static final String TAG = MmsDownloadJob.class.getSimpleName();
- private final long messageId;
- private final long threadId;
- private final boolean automatic;
+ private static final String KEY_MESSAGE_ID = "message_id";
+ private static final String KEY_THREAD_ID = "thread_id";
+ private static final String KEY_AUTOMATIC = "automatic";
+
+ private long messageId;
+ private long threadId;
+ private boolean automatic;
+
+ public MmsDownloadJob() {
+ super(null, null);
+ }
public MmsDownloadJob(Context context, long messageId, long threadId, boolean automatic) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new MasterSecretRequirement(context))
- .withRequirement(new NetworkRequirement(context))
+ .withMasterSecretRequirement()
+ .withMasterSecretRequirement()
.withGroupId("mms-operation")
- .withWakeLock(true, 30, TimeUnit.SECONDS)
.create());
this.messageId = messageId;
@@ -71,6 +79,21 @@ public class MmsDownloadJob extends MasterSecretJob {
this.automatic = automatic;
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ threadId = data.getLong(KEY_THREAD_ID);
+ automatic = data.getBoolean(KEY_AUTOMATIC, false);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
+ .putLong(KEY_THREAD_ID, threadId)
+ .putBoolean(KEY_AUTOMATIC, automatic)
+ .build();
+ }
+
@Override
public void onAdded() {
if (automatic && KeyCachingService.getMasterSecret(context) == null) {
diff --git a/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java
index 5efa378ce0..18e6f1a1bf 100644
--- a/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java
@@ -1,7 +1,11 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
+
+import android.support.annotation.NonNull;
import android.util.Pair;
import com.google.android.mms.pdu_alt.GenericPdu;
@@ -15,29 +19,51 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.recipients.Recipient;
+import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.Util;
+import java.io.IOException;
+
+import androidx.work.Data;
+
public class MmsReceiveJob extends ContextJob {
private static final long serialVersionUID = 1L;
private static final String TAG = MmsReceiveJob.class.getSimpleName();
- private final byte[] data;
- private final int subscriptionId;
+ private static final String KEY_DATA = "data";
+ private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
+
+ private byte[] data;
+ private int subscriptionId;
+
+ public MmsReceiveJob() {
+ super(null, null);
+ }
public MmsReceiveJob(Context context, byte[] data, int subscriptionId) {
- super(context, JobParameters.newBuilder()
- .withWakeLock(true)
- .withPersistence().create());
+ super(context, JobParameters.newBuilder().create());
this.data = data;
this.subscriptionId = subscriptionId;
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ try {
+ this.data = Base64.decode(data.getString(KEY_DATA));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ subscriptionId = data.getInt(KEY_SUBSCRIPTION_ID);
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_DATA, Base64.encodeBytes(data))
+ .putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
+ .build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java b/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java
index c203237efa..0c6d70b800 100644
--- a/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java
@@ -1,7 +1,10 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.text.TextUtils;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import android.webkit.MimeTypeMap;
@@ -27,8 +30,6 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MmsException;
@@ -49,28 +50,41 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+import androidx.work.Data;
+
public class MmsSendJob extends SendJob {
private static final long serialVersionUID = 0L;
private static final String TAG = MmsSendJob.class.getSimpleName();
- private final long messageId;
+ private static final String KEY_MESSAGE_ID = "message_id";
+
+ private long messageId;
+
+ public MmsSendJob() {
+ super(null, null);
+ }
public MmsSendJob(Context context, long messageId) {
super(context, JobParameters.newBuilder()
.withGroupId("mms-operation")
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
+ .withRetryCount(15)
.create());
this.messageId = messageId;
}
@Override
- public void onAdded() {
- Log.i(TAG, "onAdded() messageId: " + messageId);
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java
index 93a1e8ca4a..25c7f70ab2 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
@@ -8,8 +9,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientReader;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -24,6 +24,8 @@ import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 1L;
@@ -32,15 +34,27 @@ public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements Inje
@Inject transient SignalServiceMessageSender messageSender;
+ public MultiDeviceBlockedUpdateJob() {
+ super(null, null);
+ }
+
public MultiDeviceBlockedUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withGroupId(MultiDeviceBlockedUpdateJob.class.getSimpleName())
- .withPersistence()
.create());
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
+
@Override
public void onRun(MasterSecret masterSecret)
throws IOException, UntrustedIdentityException
@@ -71,11 +85,6 @@ public class MultiDeviceBlockedUpdateJob extends MasterSecretJob implements Inje
return false;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java
index 9a11b4b08d..bef0c9ac65 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java
@@ -20,8 +20,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -50,6 +49,8 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceContactUpdateJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 2L;
@@ -58,12 +59,19 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
private static final long FULL_SYNC_TIME = TimeUnit.HOURS.toMillis(6);
+ private static final String KEY_ADDRESS = "address";
+ private static final String KEY_FORCE_SYNC = "force_sync";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final @Nullable String address;
+ private @Nullable String address;
private boolean forceSync;
+ public MultiDeviceContactUpdateJob() {
+ super(null, null);
+ }
+
public MultiDeviceContactUpdateJob(@NonNull Context context) {
this(context, false);
}
@@ -78,10 +86,9 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address, boolean forceSync) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withGroupId(MultiDeviceContactUpdateJob.class.getSimpleName())
- .withPersistence()
.create());
this.forceSync = forceSync;
@@ -90,6 +97,19 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
else this.address = null;
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ address = data.getNullableString(KEY_ADDRESS);
+ forceSync = data.getBoolean(KEY_FORCE_SYNC, false);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_ADDRESS, address)
+ .putBoolean(KEY_FORCE_SYNC, forceSync)
+ .build();
+ }
+
@Override
public void onRun(MasterSecret masterSecret)
throws IOException, UntrustedIdentityException, NetworkException
@@ -201,11 +221,6 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
return false;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java
index 3d1119b0ff..ca7de5f49d 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.crypto.MasterSecret;
@@ -8,12 +9,11 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.dependencies.InjectableType;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -34,6 +34,8 @@ import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceGroupUpdateJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 1L;
@@ -41,15 +43,27 @@ public class MultiDeviceGroupUpdateJob extends MasterSecretJob implements Inject
@Inject transient SignalServiceMessageSender messageSender;
+ public MultiDeviceGroupUpdateJob() {
+ super(null, null);
+ }
+
public MultiDeviceGroupUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withGroupId(MultiDeviceGroupUpdateJob.class.getSimpleName())
- .withPersistence()
.create());
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
+
@Override
public void onRun(MasterSecret masterSecret) throws Exception {
File contactDataFile = createTempFile("multidevice-contact-update");
@@ -102,11 +116,6 @@ public class MultiDeviceGroupUpdateJob extends MasterSecretJob implements Inject
return false;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java
index 897c9131d4..270e22653d 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java
@@ -2,13 +2,15 @@ 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.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -27,6 +29,8 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceProfileKeyUpdateJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 1L;
@@ -34,14 +38,26 @@ public class MultiDeviceProfileKeyUpdateJob extends MasterSecretJob implements I
@Inject transient SignalServiceMessageSender messageSender;
+ public MultiDeviceProfileKeyUpdateJob() {
+ super(null, null);
+ }
+
public MultiDeviceProfileKeyUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
.withGroupId(MultiDeviceProfileKeyUpdateJob.class.getSimpleName())
.create());
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
+
@Override
public void onRun(MasterSecret masterSecret) throws IOException, UntrustedIdentityException {
if (!TextSecurePreferences.isMultiDevice(getContext())) {
@@ -79,11 +95,6 @@ public class MultiDeviceProfileKeyUpdateJob extends MasterSecretJob implements I
return false;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
Log.w(TAG, "Profile key sync failed!");
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadReceiptUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadReceiptUpdateJob.java
index e5bf04ce63..f0ae033109 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadReceiptUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadReceiptUpdateJob.java
@@ -2,10 +2,11 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -18,28 +19,42 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceReadReceiptUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceReadReceiptUpdateJob.class.getSimpleName();
+ private static final String KEY_ENABLED = "enabled";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final boolean enabled;
+ private boolean enabled;
+
+ public MultiDeviceReadReceiptUpdateJob() {
+ super(null, null);
+ }
public MultiDeviceReadReceiptUpdateJob(Context context, boolean enabled) {
super(context, JobParameters.newBuilder()
- .withPersistence()
.withGroupId("__MULTI_DEVICE_READ_RECEIPT_UPDATE_JOB__")
- .withRequirement(new NetworkRequirement(context))
+ .withNetworkRequirement()
.create());
this.enabled = enabled;
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ enabled = data.getBoolean(KEY_ENABLED, false);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putBoolean(KEY_ENABLED, enabled).build();
+ }
@Override
public void onRun() throws IOException, UntrustedIdentityException {
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java
index 764817b671..a2cf7fafd0 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java
@@ -1,14 +1,18 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -18,25 +22,33 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import java.io.IOException;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceReadUpdateJob extends MasterSecretJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceReadUpdateJob.class.getSimpleName();
- private final List messageIds;
+ private static final String KEY_MESSAGE_IDS = "message_ids";
+
+ private List messageIds;
@Inject transient SignalServiceMessageSender messageSender;
+ public MultiDeviceReadUpdateJob() {
+ super(null, null);
+ }
+
public MultiDeviceReadUpdateJob(Context context, List messageIds) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.create());
this.messageIds = new LinkedList<>();
@@ -46,6 +58,34 @@ public class MultiDeviceReadUpdateJob extends MasterSecretJob implements Injecta
}
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ String[] ids = data.getStringArray(KEY_MESSAGE_IDS);
+
+ messageIds = new ArrayList<>(ids.length);
+ for (String id : ids) {
+ try {
+ messageIds.add(JsonUtils.fromJson(id, SerializableSyncMessageId.class));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ String[] ids = new String[messageIds.size()];
+
+ for (int i = 0; i < ids.length; i++) {
+ try {
+ ids[i] = JsonUtils.toJson(messageIds.get(i));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ return dataBuilder.putStringArray(KEY_MESSAGE_IDS, ids).build();
+ }
@Override
public void onRun(MasterSecret masterSecret) throws IOException, UntrustedIdentityException {
@@ -68,11 +108,6 @@ public class MultiDeviceReadUpdateJob extends MasterSecretJob implements Injecta
return exception instanceof PushNetworkException;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
@@ -82,10 +117,13 @@ public class MultiDeviceReadUpdateJob extends MasterSecretJob implements Injecta
private static final long serialVersionUID = 1L;
+ @JsonProperty
private final String sender;
+
+ @JsonProperty
private final long timestamp;
- private SerializableSyncMessageId(String sender, long timestamp) {
+ private SerializableSyncMessageId(@JsonProperty("sender") String sender, @JsonProperty("timestamp") long timestamp) {
this.sender = sender;
this.timestamp = timestamp;
}
diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java
index aaf4a687e2..0a3c7ed709 100644
--- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java
@@ -2,13 +2,16 @@ 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.database.Address;
import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.InvalidKeyException;
@@ -22,24 +25,34 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class MultiDeviceVerifiedUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceVerifiedUpdateJob.class.getSimpleName();
+ private static final String KEY_DESTINATION = "destination";
+ private static final String KEY_IDENTITY_KEY = "identity_key";
+ private static final String KEY_VERIFIED_STATUS = "verified_status";
+ private static final String KEY_TIMESTAMP = "timestamp";
+
@Inject
transient SignalServiceMessageSender messageSender;
- private final String destination;
- private final byte[] identityKey;
- private final VerifiedStatus verifiedStatus;
- private final long timestamp;
+ private String destination;
+ private byte[] identityKey;
+ private VerifiedStatus verifiedStatus;
+ private long timestamp;
+
+ public MultiDeviceVerifiedUpdateJob() {
+ super(null, null);
+ }
public MultiDeviceVerifiedUpdateJob(Context context, Address destination, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
.withGroupId("__MULTI_DEVICE_VERIFIED_UPDATE__")
.create());
@@ -49,6 +62,28 @@ public class MultiDeviceVerifiedUpdateJob extends ContextJob implements Injectab
this.timestamp = System.currentTimeMillis();
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ destination = data.getString(KEY_DESTINATION);
+ verifiedStatus = VerifiedStatus.forState(data.getInt(KEY_VERIFIED_STATUS));
+ timestamp = data.getLong(KEY_TIMESTAMP);
+
+ try {
+ identityKey = Base64.decode(data.getString(KEY_IDENTITY_KEY));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_DESTINATION, destination)
+ .putString(KEY_IDENTITY_KEY, Base64.encodeBytes(identityKey))
+ .putInt(KEY_VERIFIED_STATUS, verifiedStatus.toInt())
+ .putLong(KEY_TIMESTAMP, timestamp)
+ .build();
+ }
+
@Override
public void onRun() throws IOException, UntrustedIdentityException {
try {
@@ -90,11 +125,6 @@ public class MultiDeviceVerifiedUpdateJob extends ContextJob implements Injectab
return exception instanceof PushNetworkException;
}
- @Override
- public void onAdded() {
-
- }
-
@Override
public void onCanceled() {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushContentReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/PushContentReceiveJob.java
index 393a77798b..bd9aa10d58 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushContentReceiveJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushContentReceiveJob.java
@@ -1,6 +1,9 @@
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.jobmanager.JobParameters;
@@ -10,12 +13,20 @@ import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import java.io.IOException;
+import androidx.work.Data;
+
public class PushContentReceiveJob extends PushReceivedJob {
private static final long serialVersionUID = 5685475456901715638L;
private static final String TAG = PushContentReceiveJob.class.getSimpleName();
- private final String data;
+ private static final String KEY_DATA = "data";
+
+ private String data;
+
+ public PushContentReceiveJob() {
+ super(null, null);
+ }
public PushContentReceiveJob(Context context) {
super(context, JobParameters.newBuilder().create());
@@ -23,16 +34,19 @@ public class PushContentReceiveJob extends PushReceivedJob {
}
public PushContentReceiveJob(Context context, String data) {
- super(context, JobParameters.newBuilder()
- .withPersistence()
- .withWakeLock(true)
- .create());
-
+ super(context, JobParameters.newBuilder().create());
this.data = data;
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ this.data = data.getNullableString(KEY_DATA);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_DATA, data).build();
+ }
@Override
public void onRun() {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
index 21df44055e..9487c8cd8a 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
@@ -7,6 +7,8 @@ import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import android.util.Pair;
@@ -98,7 +100,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.TimeUnit;
+
+import androidx.work.Data;
public class PushDecryptJob extends ContextJob {
@@ -106,8 +109,15 @@ public class PushDecryptJob extends ContextJob {
public static final String TAG = PushDecryptJob.class.getSimpleName();
- private final long messageId;
- private final long smsMessageId;
+ private static final String KEY_MESSAGE_ID = "message_id";
+ private static final String KEY_SMS_MESSAGE_ID = "sms_message_id";
+
+ private long messageId;
+ private long smsMessageId;
+
+ public PushDecryptJob() {
+ super(null, null);
+ }
public PushDecryptJob(Context context, long pushMessageId) {
this(context, pushMessageId, -1);
@@ -115,16 +125,24 @@ public class PushDecryptJob extends ContextJob {
public PushDecryptJob(Context context, long pushMessageId, long smsMessageId) {
super(context, JobParameters.newBuilder()
- .withPersistence()
.withGroupId("__PUSH_DECRYPT_JOB__")
- .withWakeLock(true, 5, TimeUnit.SECONDS)
.create());
this.messageId = pushMessageId;
this.smsMessageId = smsMessageId;
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ smsMessageId = data.getLong(KEY_SMS_MESSAGE_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
+ .putLong(KEY_SMS_MESSAGE_ID, smsMessageId)
+ .build();
+ }
@Override
public void onRun() throws NoSuchMessageException {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java
index 77ef8fa1e6..45f6841bc2 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java
@@ -16,8 +16,7 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkBackoffRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MmsException;
@@ -48,6 +47,8 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class PushGroupSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
@@ -56,16 +57,22 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
@Inject transient SignalServiceMessageSender messageSender;
- private final long messageId;
- private final long filterRecipientId; // Deprecated
- private final String filterAddress;
+ private static final String KEY_MESSAGE_ID = "message_id";
+ private static final String KEY_FILTER_ADDRESS = "filter_address";
+
+ private long messageId;
+ private long filterRecipientId; // Deprecated
+ private String filterAddress;
+
+ public PushGroupSendJob() {
+ super(null, null);
+ }
public PushGroupSendJob(Context context, long messageId, @NonNull Address destination, @Nullable Address filterAddress) {
super(context, JobParameters.newBuilder()
- .withPersistence()
.withGroupId(destination.toGroupString())
- .withRequirement(new MasterSecretRequirement(context))
- .withRequirement(new NetworkBackoffRequirement(context))
+ .withMasterSecretRequirement()
+ .withNetworkRequirement()
.withRetryDuration(TimeUnit.DAYS.toMillis(1))
.create());
@@ -75,8 +82,16 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
}
@Override
- public void onAdded() {
- Log.i(TAG, "onAdded() messageId: " + messageId);
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ filterAddress = data.getNullableString(KEY_FILTER_ADDRESS);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
+ .putString(KEY_FILTER_ADDRESS, filterAddress)
+ .build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java
index 097f171427..c9cf823031 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushGroupUpdateJob.java
@@ -2,6 +2,9 @@ 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.database.Address;
@@ -10,7 +13,6 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.libsignal.util.guava.Optional;
@@ -28,26 +30,34 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class PushGroupUpdateJob extends ContextJob implements InjectableType {
private static final String TAG = PushGroupUpdateJob.class.getSimpleName();
private static final long serialVersionUID = 0L;
+ private static final String KEY_SOURCE = "source";
+ private static final String KEY_GROUP_ID = "group_id";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final String source;
- private final byte[] groupId;
+ private String source;
+ private byte[] groupId;
+ public PushGroupUpdateJob() {
+ super(null, null);
+ }
public PushGroupUpdateJob(Context context, String source, byte[] groupId) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new NetworkRequirement(context))
- .withRetryCount(50)
+ .withNetworkRequirement()
+ .withRetryDuration(TimeUnit.DAYS.toMillis(1))
.create());
this.source = source;
@@ -55,7 +65,21 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ source = data.getString(KEY_SOURCE);
+ try {
+ groupId = GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_SOURCE, source)
+ .putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
+ .build();
+ }
@Override
public void onRun() throws IOException, UntrustedIdentityException {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
index 94473aa5da..940d8dfb3e 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java
@@ -1,6 +1,9 @@
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.ApplicationContext;
@@ -32,24 +35,37 @@ import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class PushMediaSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = PushMediaSendJob.class.getSimpleName();
+ private static final String KEY_MESSAGE_ID = "message_id";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final long messageId;
+ private long messageId;
+
+ public PushMediaSendJob() {
+ super(null, null);
+ }
public PushMediaSendJob(Context context, long messageId, Address destination) {
- super(context, constructParameters(context, destination));
+ super(context, constructParameters(destination));
this.messageId = messageId;
}
@Override
- public void onAdded() {
- Log.i(TAG, "onAdded() messageId: " + messageId);
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/PushNotificationReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/PushNotificationReceiveJob.java
index 87b301462f..a8d4331b2a 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushNotificationReceiveJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushNotificationReceiveJob.java
@@ -1,35 +1,47 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
-import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class PushNotificationReceiveJob extends PushReceivedJob implements InjectableType {
private static final String TAG = PushNotificationReceiveJob.class.getSimpleName();
@Inject transient SignalServiceMessageReceiver receiver;
+ public PushNotificationReceiveJob() {
+ super(null, null);
+ }
+
public PushNotificationReceiveJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
+ .withNetworkRequirement()
.withGroupId("__notification_received")
- .withWakeLock(true, 30, TimeUnit.SECONDS).create());
+ .create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun() throws IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java
index 97088d9a71..a74a77d970 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java
@@ -15,8 +15,6 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkBackoffRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
@@ -49,12 +47,11 @@ public abstract class PushSendJob extends SendJob {
super(context, parameters);
}
- protected static JobParameters constructParameters(Context context, Address destination) {
+ protected static JobParameters constructParameters(Address destination) {
JobParameters.Builder builder = JobParameters.newBuilder();
- builder.withPersistence();
builder.withGroupId(destination.serialize());
- builder.withRequirement(new MasterSecretRequirement(context));
- builder.withRequirement(new NetworkBackoffRequirement(context));
+ builder.withMasterSecretRequirement();
+ builder.withNetworkRequirement();
builder.withRetryDuration(TimeUnit.DAYS.toMillis(1));
return builder.create();
@@ -80,7 +77,7 @@ public abstract class PushSendJob extends SendJob {
super.onRetry();
Log.i(TAG, "onRetry()");
- if (getRunIteration() > 1) {
+ if (getRunAttemptCount() > 1) {
Log.i(TAG, "Scheduling service outage detection job.");
ApplicationContext.getInstance(context).getJobManager().add(new ServiceOutageDetectionJob(context));
}
diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
index 1b880aa132..1076376674 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java
@@ -1,6 +1,9 @@
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.ApplicationContext;
@@ -26,21 +29,39 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class PushTextSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = PushTextSendJob.class.getSimpleName();
+ private static final String KEY_MESSAGE_ID = "message_id";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final long messageId;
+ private long messageId;
+
+ public PushTextSendJob() {
+ super(null, null);
+ }
public PushTextSendJob(Context context, long messageId, Address destination) {
- super(context, constructParameters(context, destination));
+ super(context, constructParameters(destination));
this.messageId = messageId;
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
+ }
+
@Override
public void onAdded() {
Log.i(TAG, "onAdded() messageId: " + messageId);
diff --git a/src/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java b/src/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
index 7227e5c81b..70952e881b 100644
--- a/src/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
@@ -1,20 +1,23 @@
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.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureException;
import java.io.IOException;
-import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RefreshAttributesJob extends ContextJob implements InjectableType {
public static final long serialVersionUID = 1L;
@@ -23,17 +26,25 @@ public class RefreshAttributesJob extends ContextJob implements InjectableType {
@Inject transient SignalServiceAccountManager signalAccountManager;
+ public RefreshAttributesJob() {
+ super(null, null);
+ }
+
public RefreshAttributesJob(Context context) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new NetworkRequirement(context))
- .withWakeLock(true, 30, TimeUnit.SECONDS)
+ .withNetworkRequirement()
.withGroupId(RefreshAttributesJob.class.getName())
.create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun() throws IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java b/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
index 1ebd5243c4..67723201c1 100644
--- a/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
@@ -8,8 +9,7 @@ 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.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -24,6 +24,8 @@ import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RefreshPreKeysJob extends MasterSecretJob implements InjectableType {
private static final String TAG = RefreshPreKeysJob.class.getSimpleName();
@@ -32,18 +34,26 @@ public class RefreshPreKeysJob extends MasterSecretJob implements InjectableType
@Inject transient SignalServiceAccountManager accountManager;
+ public RefreshPreKeysJob() {
+ super(null, null);
+ }
+
public RefreshPreKeysJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(RefreshPreKeysJob.class.getSimpleName())
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withRetryCount(5)
.create());
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/RequestGroupInfoJob.java b/src/org/thoughtcrime/securesms/jobs/RequestGroupInfoJob.java
index 290de287d7..7846d971f7 100644
--- a/src/org/thoughtcrime/securesms/jobs/RequestGroupInfoJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RequestGroupInfoJob.java
@@ -5,7 +5,8 @@ import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
+import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
@@ -18,21 +19,29 @@ import java.io.IOException;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RequestGroupInfoJob extends ContextJob implements InjectableType {
private static final String TAG = RequestGroupInfoJob.class.getSimpleName();
private static final long serialVersionUID = 0L;
+ private static final String KEY_SOURCE = "source";
+ private static final String KEY_GROUP_ID = "group_id";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final String source;
- private final byte[] groupId;
+ private String source;
+ private byte[] groupId;
+
+ public RequestGroupInfoJob() {
+ super(null, null);
+ }
public RequestGroupInfoJob(@NonNull Context context, @NonNull String source, @NonNull byte[] groupId) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
.withRetryCount(50)
.create());
@@ -41,7 +50,21 @@ public class RequestGroupInfoJob extends ContextJob implements InjectableType {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ source = data.getString(KEY_SOURCE);
+ try {
+ groupId = GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_SOURCE, source)
+ .putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
+ .build();
+ }
@Override
public void onRun() throws IOException, UntrustedIdentityException {
diff --git a/src/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java b/src/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java
index 5ef2c7d1e9..7d8ee23711 100644
--- a/src/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java
@@ -2,14 +2,17 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.text.TextUtils;
+
+import org.thoughtcrime.securesms.database.Address;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Util;
@@ -23,21 +26,31 @@ import java.io.InputStream;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RetrieveProfileAvatarJob extends ContextJob implements InjectableType {
private static final String TAG = RetrieveProfileAvatarJob.class.getSimpleName();
private static final int MAX_PROFILE_SIZE_BYTES = 20 * 1024 * 1024;
+ private static final String KEY_PROFILE_AVATAR = "profile_avatar";
+ private static final String KEY_ADDRESS = "address";
+
@Inject SignalServiceMessageReceiver receiver;
- private final String profileAvatar;
- private final Recipient recipient;
+ private String profileAvatar;
+ private Recipient recipient;
+
+ public RetrieveProfileAvatarJob() {
+ super(null, null);
+ }
public RetrieveProfileAvatarJob(Context context, Recipient recipient, String profileAvatar) {
super(context, JobParameters.newBuilder()
.withGroupId(RetrieveProfileAvatarJob.class.getSimpleName() + recipient.getAddress().serialize())
- .withRequirement(new NetworkRequirement(context))
+ .withDuplicatesIgnored(true)
+ .withNetworkRequirement()
.create());
this.recipient = recipient;
@@ -45,7 +58,17 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ profileAvatar = data.getString(KEY_PROFILE_AVATAR);
+ recipient = Recipient.from(context, Address.fromSerialized(data.getString(KEY_ADDRESS)), true);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_PROFILE_AVATAR, profileAvatar)
+ .putString(KEY_ADDRESS, recipient.getAddress().serialize())
+ .build();
+ }
@Override
public void onRun() throws IOException {
diff --git a/src/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java b/src/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java
index 96b6f26962..baf554299a 100644
--- a/src/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java
@@ -4,6 +4,9 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import android.text.TextUtils;
+
+import org.thoughtcrime.securesms.database.Address;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.ApplicationContext;
@@ -29,16 +32,25 @@ import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RetrieveProfileJob extends ContextJob implements InjectableType {
private static final String TAG = RetrieveProfileJob.class.getSimpleName();
+ private static final String KEY_ADDRESS = "address";
+
@Inject transient SignalServiceMessageReceiver receiver;
- private final Recipient recipient;
+ private Recipient recipient;
+
+ public RetrieveProfileJob() {
+ super(null, null);
+ }
public RetrieveProfileJob(Context context, Recipient recipient) {
super(context, JobParameters.newBuilder()
+ .withNetworkRequirement()
.withRetryCount(3)
.create());
@@ -46,7 +58,14 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ recipient = Recipient.from(context, Address.fromSerialized(data.getString(KEY_ADDRESS)), true);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putString(KEY_ADDRESS, recipient.getAddress().serialize()).build();
+ }
@Override
public void onRun() throws IOException, InvalidKeyException {
diff --git a/src/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java b/src/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java
index c23bd42bfb..2ecef2e7ba 100644
--- a/src/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
@@ -9,8 +10,7 @@ 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.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -20,23 +20,33 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import javax.inject.Inject;
+import androidx.work.Data;
+
public class RotateSignedPreKeyJob extends MasterSecretJob implements InjectableType {
private static final String TAG = RotateSignedPreKeyJob.class.getName();
@Inject transient SignalServiceAccountManager accountManager;
+ public RotateSignedPreKeyJob() {
+ super(null, null);
+ }
+
public RotateSignedPreKeyJob(Context context) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withRequirement(new MasterSecretRequirement(context))
+ .withNetworkRequirement()
+ .withMasterSecretRequirement()
.withRetryCount(5)
.create());
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java b/src/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
index 41333b2339..bed3982340 100644
--- a/src/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java
@@ -2,11 +2,12 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -16,26 +17,36 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
+import androidx.work.Data;
+
public class SendReadReceiptJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
private static final String TAG = SendReadReceiptJob.class.getSimpleName();
+ private static final String KEY_ADDRESS = "address";
+ private static final String KEY_MESSAGE_IDS = "message_ids";
+ private static final String KEY_TIMESTAMP = "timestamp";
+
@Inject transient SignalServiceMessageSender messageSender;
- private final String address;
- private final List messageIds;
- private final long timestamp;
+ private String address;
+ private List messageIds;
+ private long timestamp;
+
+ public SendReadReceiptJob() {
+ super(null, null);
+ }
public SendReadReceiptJob(Context context, Address address, List messageIds) {
super(context, JobParameters.newBuilder()
- .withRequirement(new NetworkRequirement(context))
- .withPersistence()
+ .withNetworkRequirement()
.create());
this.address = address.serialize();
@@ -44,7 +55,29 @@ public class SendReadReceiptJob extends ContextJob implements InjectableType {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ address = data.getString(KEY_ADDRESS);
+ timestamp = data.getLong(KEY_TIMESTAMP);
+
+ long[] ids = data.getLongArray(KEY_MESSAGE_IDS);
+ messageIds = new ArrayList<>(ids.length);
+ for (long id : ids) {
+ messageIds.add(id);
+ }
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ long[] ids = new long[messageIds.size()];
+ for (int i = 0; i < ids.length; i++) {
+ ids[i] = messageIds.get(i);
+ }
+
+ return dataBuilder.putString(KEY_ADDRESS, address)
+ .putLongArray(KEY_MESSAGE_IDS, ids)
+ .putLong(KEY_TIMESTAMP, timestamp)
+ .build();
+ }
@Override
public void onRun() throws IOException, UntrustedIdentityException {
diff --git a/src/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java b/src/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java
index 4735669127..4a4c1a511a 100644
--- a/src/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/ServiceOutageDetectionJob.java
@@ -1,12 +1,13 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.greenrobot.eventbus.EventBus;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -14,6 +15,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import androidx.work.Data;
+
public class ServiceOutageDetectionJob extends ContextJob {
private static final String TAG = ServiceOutageDetectionJob.class.getSimpleName();
@@ -22,16 +25,26 @@ public class ServiceOutageDetectionJob extends ContextJob {
private static final String IP_FAILURE = "127.0.0.2";
private static final long CHECK_TIME = 1000 * 60;
+ public ServiceOutageDetectionJob() {
+ super(null, null);
+ }
+
public ServiceOutageDetectionJob(Context context) {
super(context, new JobParameters.Builder()
.withGroupId(ServiceOutageDetectionJob.class.getSimpleName())
- .withRequirement(new NetworkRequirement(context))
+ .withDuplicatesIgnored(true)
+ .withNetworkRequirement()
.withRetryCount(5)
.create());
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java
index f11113580e..83d0aecb3a 100644
--- a/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java
@@ -4,36 +4,47 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.telephony.SmsMessage;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
+import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
+import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
+import androidx.work.Data;
+
public class SmsReceiveJob extends ContextJob {
private static final long serialVersionUID = 1L;
private static final String TAG = SmsReceiveJob.class.getSimpleName();
- private final @Nullable Object[] pdus;
- private final int subscriptionId;
+ private static final String KEY_PDUS = "pdus";
+ private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
+
+ private @Nullable Object[] pdus;
+
+ private int subscriptionId;
+
+ public SmsReceiveJob() {
+ super(null, null);
+ }
public SmsReceiveJob(@NonNull Context context, @Nullable Object[] pdus, int subscriptionId) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withWakeLock(true)
- .withRequirement(new SqlCipherMigrationRequirement(context))
+ .withSqlCipherRequirement()
.create());
this.pdus = pdus;
@@ -41,7 +52,31 @@ public class SmsReceiveJob extends ContextJob {
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ String[] encoded = data.getStringArray(KEY_PDUS);
+ pdus = new Object[encoded.length];
+ try {
+ for (int i = 0; i < encoded.length; i++) {
+ pdus[i] = Base64.decode(encoded[i]);
+ }
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+
+ subscriptionId = data.getInt(KEY_SUBSCRIPTION_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ String[] encoded = new String[pdus.length];
+ for (int i = 0; i < pdus.length; i++) {
+ encoded[i] = Base64.encodeBytes((byte[]) pdus[i]);
+ }
+
+ return dataBuilder.putStringArray(KEY_PDUS, encoded)
+ .putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
+ .build();
+ }
@Override
public void onRun() throws MigrationPendingException {
diff --git a/src/org/thoughtcrime/securesms/jobs/SmsSendJob.java b/src/org/thoughtcrime/securesms/jobs/SmsSendJob.java
index f01d613056..0452924ec5 100644
--- a/src/org/thoughtcrime/securesms/jobs/SmsSendJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/SmsSendJob.java
@@ -5,8 +5,11 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
+import android.support.annotation.NonNull;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
@@ -14,9 +17,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.NetworkOrServiceRequirement;
-import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirement;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
@@ -27,18 +27,35 @@ import org.thoughtcrime.securesms.jobmanager.JobParameters;
import java.util.ArrayList;
+import androidx.work.Data;
+
public class SmsSendJob extends SendJob {
private static final long serialVersionUID = -5118520036244759718L;
private static final String TAG = SmsSendJob.class.getSimpleName();
+ private static final String KEY_MESSAGE_ID = "message_id";
- private final long messageId;
+ private long messageId;
+
+ public SmsSendJob() {
+ super(null, null);
+ }
public SmsSendJob(Context context, long messageId, String name) {
- super(context, constructParameters(context, name));
+ super(context, constructParameters(name));
this.messageId = messageId;
}
+ @Override
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
+ }
+
@Override
public void onAdded() {
Log.i(TAG, "onAdded() messageId: " + messageId);
@@ -190,19 +207,11 @@ public class SmsSendJob extends SendJob {
}
}
- private static JobParameters constructParameters(Context context, String name) {
+ private static JobParameters constructParameters(String name) {
JobParameters.Builder builder = JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new MasterSecretRequirement(context))
+ .withMasterSecretRequirement()
.withRetryCount(15)
.withGroupId(name);
-
- if (TextSecurePreferences.isWifiSmsEnabled(context)) {
- builder.withRequirement(new NetworkOrServiceRequirement(context));
- } else {
- builder.withRequirement(new ServiceRequirement(context));
- }
-
return builder.create();
}
diff --git a/src/org/thoughtcrime/securesms/jobs/SmsSentJob.java b/src/org/thoughtcrime/securesms/jobs/SmsSentJob.java
index a086d7d45d..b335022448 100644
--- a/src/org/thoughtcrime/securesms/jobs/SmsSentJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/SmsSentJob.java
@@ -2,7 +2,10 @@ package org.thoughtcrime.securesms.jobs;
import android.app.Activity;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.telephony.SmsManager;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.ApplicationContext;
@@ -12,23 +15,31 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
+import androidx.work.Data;
+
public class SmsSentJob extends MasterSecretJob {
private static final long serialVersionUID = -2624694558755317560L;
private static final String TAG = SmsSentJob.class.getSimpleName();
- private final long messageId;
- private final String action;
- private final int result;
+ private static final String KEY_MESSAGE_ID = "message_id";
+ private static final String KEY_ACTION = "action";
+ private static final String KEY_RESULT = "result";
+
+ private long messageId;
+ private String action;
+ private int result;
+
+ public SmsSentJob() {
+ super(null, null);
+ }
public SmsSentJob(Context context, long messageId, String action, int result) {
super(context, JobParameters.newBuilder()
- .withPersistence()
- .withRequirement(new MasterSecretRequirement(context))
+ .withMasterSecretRequirement()
.create());
this.messageId = messageId;
@@ -37,8 +48,18 @@ public class SmsSentJob extends MasterSecretJob {
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ messageId = data.getLong(KEY_MESSAGE_ID);
+ action = data.getString(KEY_ACTION);
+ result = data.getInt(KEY_RESULT);
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
+ .putString(KEY_ACTION, action)
+ .putInt(KEY_RESULT, result)
+ .build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/TrimThreadJob.java b/src/org/thoughtcrime/securesms/jobs/TrimThreadJob.java
index 15c843ed3b..790eef6142 100644
--- a/src/org/thoughtcrime/securesms/jobs/TrimThreadJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/TrimThreadJob.java
@@ -17,29 +17,42 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
+import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.database.DatabaseFactory;
-import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
-public class TrimThreadJob extends Job {
+import androidx.work.Data;
+
+public class TrimThreadJob extends ContextJob {
private static final String TAG = TrimThreadJob.class.getSimpleName();
- private final Context context;
- private final long threadId;
+ private static final String KEY_THREAD_ID = "thread_id";
+
+ private long threadId;
+
+ public TrimThreadJob() {
+ super(null, null);
+ }
public TrimThreadJob(Context context, long threadId) {
- super(JobParameters.newBuilder().withGroupId(TrimThreadJob.class.getSimpleName()).create());
+ super(context, JobParameters.newBuilder().withGroupId(TrimThreadJob.class.getSimpleName()).create());
this.context = context;
this.threadId = threadId;
}
@Override
- public void onAdded() {
+ protected void initialize(@NonNull SafeData data) {
+ threadId = data.getLong(KEY_THREAD_ID);
+ }
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.putLong(KEY_THREAD_ID, threadId).build();
}
@Override
diff --git a/src/org/thoughtcrime/securesms/jobs/UpdateApkJob.java b/src/org/thoughtcrime/securesms/jobs/UpdateApkJob.java
index 9650e750ed..c435bb501b 100644
--- a/src/org/thoughtcrime/securesms/jobs/UpdateApkJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/UpdateApkJob.java
@@ -9,14 +9,16 @@ import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+
+import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
-import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.service.UpdateApkReadyListener;
import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.Hex;
@@ -26,8 +28,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
-import java.util.concurrent.TimeUnit;
+import androidx.work.Data;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@@ -36,17 +38,26 @@ public class UpdateApkJob extends ContextJob {
private static final String TAG = UpdateApkJob.class.getSimpleName();
+ public UpdateApkJob() {
+ super(null, null);
+ }
+
public UpdateApkJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(UpdateApkJob.class.getSimpleName())
- .withRequirement(new NetworkRequirement(context))
- .withWakeLock(true, 30, TimeUnit.SECONDS)
+ .withNetworkRequirement()
.withRetryCount(2)
.create());
}
@Override
- public void onAdded() {}
+ protected void initialize(@NonNull SafeData data) {
+ }
+
+ @Override
+ protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
+ return dataBuilder.build();
+ }
@Override
public void onRun() throws IOException, PackageManager.NameNotFoundException {