Migrated to new JobManager.

This commit is contained in:
Greyson Parrelli
2019-03-28 08:56:35 -07:00
parent 8cf3ba424a
commit 4a3c173adb
162 changed files with 5360 additions and 3574 deletions

View File

@@ -1,23 +1,22 @@
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.greenrobot.eventbus.EventBus;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
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.mms.MmsException;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.util.AttachmentUtil;
@@ -37,11 +36,10 @@ import java.io.InputStream;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class AttachmentDownloadJob extends BaseJob implements InjectableType {
public static final String KEY = "AttachmentDownloadJob";
public class AttachmentDownloadJob extends ContextJob 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();
@@ -50,22 +48,27 @@ public class AttachmentDownloadJob extends ContextJob implements InjectableType
private static final String KEY_PAR_UNIQUE_ID = "part_unique_id";
private static final String KEY_MANUAL = "part_manual";
@Inject transient SignalServiceMessageReceiver messageReceiver;
@Inject SignalServiceMessageReceiver messageReceiver;
private long messageId;
private long partRowId;
private long partUniqueId;
private boolean manual;
public AttachmentDownloadJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public AttachmentDownloadJob(long messageId, AttachmentId attachmentId, boolean manual) {
this(new Job.Parameters.Builder()
.setQueue("AttachmentDownloadJob" + attachmentId.getRowId() + "-" + attachmentId.getUniqueId())
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(25)
.build(),
messageId,
attachmentId,
manual);
}
public AttachmentDownloadJob(Context context, long messageId, AttachmentId attachmentId, boolean manual) {
super(context, JobParameters.newBuilder()
.withGroupId(AttachmentDownloadJob.class.getSimpleName() + attachmentId.getRowId() + "-" + attachmentId.getUniqueId())
.withNetworkRequirement()
.create());
private AttachmentDownloadJob(@NonNull Job.Parameters parameters, long messageId, AttachmentId attachmentId, boolean manual) {
super(parameters);
this.messageId = messageId;
this.partRowId = attachmentId.getRowId();
@@ -74,20 +77,17 @@ public class AttachmentDownloadJob extends ContextJob implements InjectableType
}
@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);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_PART_ROW_ID, partRowId)
.putLong(KEY_PAR_UNIQUE_ID, partUniqueId)
.putBoolean(KEY_MANUAL, manual)
.build();
}
@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();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -242,4 +242,13 @@ public class AttachmentDownloadJob extends ContextJob implements InjectableType
InvalidPartException(Exception e) {super(e);}
}
public static final class Factory implements Job.Factory<AttachmentDownloadJob> {
@Override
public @NonNull AttachmentDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new AttachmentDownloadJob(parameters,
data.getLong(KEY_MESSAGE_ID),
new AttachmentId(data.getLong(KEY_PART_ROW_ID), data.getLong(KEY_PAR_UNIQUE_ID)),
data.getBoolean(KEY_MANUAL));
}
}
}

View File

@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.greenrobot.eventbus.EventBus;
@@ -12,8 +11,9 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MediaStream;
@@ -35,10 +35,9 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.net.ssl.SSLException;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class AttachmentUploadJob extends BaseJob implements InjectableType {
public class AttachmentUploadJob extends ContextJob implements InjectableType {
public static final String KEY = "AttachmentUploadJob";
private static final String TAG = AttachmentUploadJob.class.getSimpleName();
@@ -48,29 +47,30 @@ public class AttachmentUploadJob extends ContextJob implements InjectableType {
private AttachmentId attachmentId;
@Inject SignalServiceMessageSender messageSender;
public AttachmentUploadJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public AttachmentUploadJob(AttachmentId attachmentId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
attachmentId);
}
protected AttachmentUploadJob(@NonNull Context context, AttachmentId attachmentId) {
super(context, new JobParameters.Builder()
.withNetworkRequirement()
.withRetryDuration(TimeUnit.DAYS.toMillis(1))
.create());
private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId) {
super(parameters);
this.attachmentId = attachmentId;
}
@Override
protected void initialize(@NonNull SafeData data) {
this.attachmentId = new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID));
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId())
.putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId())
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_ROW_ID, attachmentId.getRowId())
.putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId())
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -92,7 +92,7 @@ public class AttachmentUploadJob extends ContextJob implements InjectableType {
}
@Override
protected void onCanceled() { }
public void onCanceled() { }
@Override
protected boolean onShouldRetry(Exception exception) {
@@ -145,4 +145,11 @@ public class AttachmentUploadJob extends ContextJob implements InjectableType {
throw new UndeliverableMessageException(e);
}
}
public static final class Factory implements Job.Factory<AttachmentUploadJob> {
@Override
public @NonNull AttachmentUploadJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)));
}
}
}

View File

@@ -1,16 +1,15 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
@@ -29,46 +28,41 @@ import java.io.InputStream;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class AvatarDownloadJob extends BaseJob implements InjectableType {
public class AvatarDownloadJob extends ContextJob implements InjectableType {
private static final int MAX_AVATAR_SIZE = 20 * 1024 * 1024;
private static final long serialVersionUID = 1L;
public static final String KEY = "AvatarDownloadJob";
private static final String TAG = AvatarDownloadJob.class.getSimpleName();
private static final int MAX_AVATAR_SIZE = 20 * 1024 * 1024;
private static final String KEY_GROUP_ID = "group_id";
@Inject transient SignalServiceMessageReceiver receiver;
@Inject SignalServiceMessageReceiver receiver;
private byte[] groupId;
public AvatarDownloadJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public AvatarDownloadJob(@NonNull byte[] groupId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(10)
.build(),
groupId);
}
public AvatarDownloadJob(Context context, @NonNull byte[] groupId) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.create());
private AvatarDownloadJob(@NonNull Job.Parameters parameters, @NonNull byte[] groupId) {
super(parameters);
this.groupId = groupId;
}
@Override
protected void initialize(@NonNull SafeData data) {
try {
groupId = GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID));
} catch (IOException e) {
throw new AssertionError(e);
}
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false)).build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false)).build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -122,4 +116,14 @@ public class AvatarDownloadJob extends ContextJob implements InjectableType {
return false;
}
public static final class Factory implements Job.Factory<AvatarDownloadJob> {
@Override
public @NonNull AvatarDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) {
try {
return new AvatarDownloadJob(parameters, GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -0,0 +1,36 @@
package org.thoughtcrime.securesms.jobs;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobLogger;
import org.thoughtcrime.securesms.logging.Log;
public abstract class BaseJob extends Job {
private static final String TAG = BaseJob.class.getSimpleName();
public BaseJob(@NonNull Parameters parameters) {
super(parameters);
}
@Override
public @NonNull Result run() {
try {
onRun();
return Result.SUCCESS;
} catch (Exception e) {
if (onShouldRetry(e)) {
Log.i(TAG, JobLogger.format(this, "Encountered a retryable exception."), e);
return Result.RETRY;
} else {
Log.w(TAG, JobLogger.format(this, "Encountered a failing exception."), e);
return Result.FAILURE;
}
}
}
protected abstract void onRun() throws Exception;
protected abstract boolean onShouldRetry(@NonNull Exception e);
}

View File

@@ -1,15 +1,13 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
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.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyStore;
@@ -26,38 +24,38 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
import static org.thoughtcrime.securesms.dependencies.AxolotlStorageModule.SignedPreKeyStoreFactory;
public class CleanPreKeysJob extends ContextJob implements InjectableType {
public class CleanPreKeysJob extends BaseJob implements InjectableType {
public static final String KEY = "CleanPreKeysJob";
private static final String TAG = CleanPreKeysJob.class.getSimpleName();
private static final long ARCHIVE_AGE = TimeUnit.DAYS.toMillis(7);
@Inject transient SignalServiceAccountManager accountManager;
@Inject transient SignedPreKeyStoreFactory signedPreKeyStoreFactory;
@Inject SignalServiceAccountManager accountManager;
@Inject SignedPreKeyStoreFactory signedPreKeyStoreFactory;
public CleanPreKeysJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public CleanPreKeysJob() {
this(new Job.Parameters.Builder()
.setQueue("CleanPreKeysJob")
.setMaxAttempts(5)
.build());
}
public CleanPreKeysJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(CleanPreKeysJob.class.getSimpleName())
.withRetryCount(5)
.create());
private CleanPreKeysJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -134,4 +132,10 @@ public class CleanPreKeysJob extends ContextJob implements InjectableType {
}
}
public static final class Factory implements Job.Factory<CleanPreKeysJob> {
@Override
public @NonNull CleanPreKeysJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new CleanPreKeysJob(parameters);
}
}
}

View File

@@ -1,32 +0,0 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
import androidx.work.WorkerParameters;
public abstract class ContextJob extends Job implements ContextDependent {
protected transient Context context;
public ContextJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
protected ContextJob(@NonNull Context context, @NonNull JobParameters parameters) {
super(context, parameters);
this.context = context;
}
public void setContext(Context context) {
this.context = context;
}
protected Context getContext() {
return context;
}
}

View File

@@ -4,11 +4,11 @@ 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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -20,35 +20,35 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class CreateSignedPreKeyJob extends ContextJob implements InjectableType {
public class CreateSignedPreKeyJob extends BaseJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "CreateSignedPreKeyJob";
private static final String TAG = CreateSignedPreKeyJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager accountManager;
public CreateSignedPreKeyJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
@Inject SignalServiceAccountManager accountManager;
public CreateSignedPreKeyJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(CreateSignedPreKeyJob.class.getSimpleName())
.create());
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("CreateSignedPreKeyJob")
.setMaxAttempts(25)
.build());
}
private CreateSignedPreKeyJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -78,4 +78,11 @@ public class CreateSignedPreKeyJob extends ContextJob implements InjectableType
if (exception instanceof PushNetworkException) return true;
return false;
}
public static final class Factory implements Job.Factory<CreateSignedPreKeyJob> {
@Override
public @NonNull CreateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new CreateSignedPreKeyJob(parameters);
}
}
}

View File

@@ -1,68 +1,66 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.app.Application;
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
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;
import androidx.work.WorkerParameters;
public class DirectoryRefreshJob extends BaseJob {
public class DirectoryRefreshJob extends ContextJob {
public static final String KEY = "DirectoryRefreshJob";
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;
@Nullable private Recipient recipient;
private boolean notifyOfNewUsers;
public DirectoryRefreshJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public DirectoryRefreshJob(boolean notifyOfNewUsers) {
this(null, notifyOfNewUsers);
}
public DirectoryRefreshJob(@NonNull Context context, boolean notifyOfNewUsers) {
this(context, null, notifyOfNewUsers);
}
public DirectoryRefreshJob(@NonNull Context context,
@Nullable Recipient recipient,
boolean notifyOfNewUsers)
public DirectoryRefreshJob(@Nullable Recipient recipient,
boolean notifyOfNewUsers)
{
super(context, JobParameters.newBuilder()
.withGroupId(DirectoryRefreshJob.class.getSimpleName())
.withNetworkRequirement()
.create());
this(new Job.Parameters.Builder()
.setQueue("DirectoryRefreshJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(10)
.build(),
recipient,
notifyOfNewUsers);
}
private DirectoryRefreshJob(@NonNull Job.Parameters parameters, @Nullable Recipient recipient, boolean notifyOfNewUsers) {
super(parameters);
this.recipient = recipient;
this.notifyOfNewUsers = notifyOfNewUsers;
}
@Override
protected void initialize(@NonNull SafeData data) {
String serializedAddress = data.getString(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);
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_ADDRESS, recipient != null ? recipient.getAddress().serialize() : null)
.putBoolean(KEY_NOTIFY_OF_NEW_USERS, notifyOfNewUsers)
.build();
}
@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();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -84,4 +82,23 @@ public class DirectoryRefreshJob extends ContextJob {
@Override
public void onCanceled() {}
public static final class Factory implements Job.Factory<DirectoryRefreshJob> {
private final Application application;
public Factory(@NonNull Application application) {
this.application = application;
}
@Override
public @NonNull DirectoryRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) {
String serializedAddress = data.getString(KEY_ADDRESS);
Address address = serializedAddress != null ? Address.fromSerialized(serializedAddress) : null;
Recipient recipient = address != null ? Recipient.from(application, address, true) : null;
boolean notifyOfNewUsers = data.getBoolean(KEY_NOTIFY_OF_NEW_USERS);
return new DirectoryRefreshJob(parameters, recipient, notifyOfNewUsers);
}
}
}

View File

@@ -0,0 +1,259 @@
package org.thoughtcrime.securesms.jobs;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.database.JobDatabase;
import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec;
import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage;
import org.thoughtcrime.securesms.util.Util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
public class FastJobStorage implements JobStorage {
private final JobDatabase jobDatabase;
private final List<JobSpec> jobs;
private final Map<String, List<ConstraintSpec>> constraintsByJobId;
private final Map<String, List<DependencySpec>> dependenciesByJobId;
public FastJobStorage(@NonNull JobDatabase jobDatabase) {
this.jobDatabase = jobDatabase;
this.jobs = new ArrayList<>();
this.constraintsByJobId = new HashMap<>();
this.dependenciesByJobId = new HashMap<>();
}
@Override
public synchronized void init() {
List<JobSpec> jobSpecs = jobDatabase.getAllJobSpecs();
List<ConstraintSpec> constraintSpecs = jobDatabase.getAllConstraintSpecs();
List<DependencySpec> dependencySpecs = jobDatabase.getAllDependencySpecs();
jobs.addAll(jobSpecs);
for (ConstraintSpec constraintSpec: constraintSpecs) {
List<ConstraintSpec> jobConstraints = Util.getOrDefault(constraintsByJobId, constraintSpec.getJobSpecId(), new LinkedList<>());
jobConstraints.add(constraintSpec);
constraintsByJobId.put(constraintSpec.getJobSpecId(), jobConstraints);
}
for (DependencySpec dependencySpec : dependencySpecs) {
List<DependencySpec> jobDependencies = Util.getOrDefault(dependenciesByJobId, dependencySpec.getJobId(), new LinkedList<>());
jobDependencies.add(dependencySpec);
dependenciesByJobId.put(dependencySpec.getJobId(), jobDependencies);
}
}
@Override
public synchronized void insertJobs(@NonNull List<FullSpec> fullSpecs) {
jobDatabase.insertJobs(fullSpecs);
for (FullSpec fullSpec : fullSpecs) {
jobs.add(fullSpec.getJobSpec());
constraintsByJobId.put(fullSpec.getJobSpec().getId(), fullSpec.getConstraintSpecs());
dependenciesByJobId.put(fullSpec.getJobSpec().getId(), fullSpec.getDependencySpecs());
}
}
@Override
public synchronized @Nullable JobSpec getJobSpec(@NonNull String id) {
for (JobSpec jobSpec : jobs) {
if (jobSpec.getId().equals(id)) {
return jobSpec;
}
}
return null;
}
@Override
public synchronized @NonNull List<JobSpec> getAllJobSpecs() {
return new ArrayList<>(jobs);
}
@Override
public synchronized @NonNull List<JobSpec> getPendingJobsWithNoDependenciesInCreatedOrder(long currentTime) {
return Stream.of(jobs)
.filterNot(JobSpec::isRunning)
.filter(this::firstInQueue)
.filter(j -> !dependenciesByJobId.containsKey(j.getId()) || dependenciesByJobId.get(j.getId()).isEmpty())
.filter(j -> j.getNextRunAttemptTime() <= currentTime)
.sorted((j1, j2) -> Long.compare(j1.getCreateTime(), j2.getCreateTime()))
.toList();
}
private boolean firstInQueue(@NonNull JobSpec job) {
if (job.getQueueKey() == null) {
return true;
}
return Stream.of(jobs)
.filter(j -> Util.equals(j.getQueueKey(), job.getQueueKey()))
.sorted((j1, j2) -> Long.compare(j1.getCreateTime(), j2.getCreateTime()))
.toList()
.get(0)
.equals(job);
}
@Override
public synchronized int getJobInstanceCount(@NonNull String factoryKey) {
return (int) Stream.of(jobs)
.filter(j -> j.getFactoryKey().equals(factoryKey))
.count();
}
@Override
public synchronized void updateJobRunningState(@NonNull String id, boolean isRunning) {
jobDatabase.updateJobRunningState(id, isRunning);
ListIterator<JobSpec> iter = jobs.listIterator();
while (iter.hasNext()) {
JobSpec existing = iter.next();
if (existing.getId().equals(id)) {
JobSpec updated = new JobSpec(existing.getId(),
existing.getFactoryKey(),
existing.getQueueKey(),
existing.getCreateTime(),
existing.getNextRunAttemptTime(),
existing.getRunAttempt(),
existing.getMaxAttempts(),
existing.getMaxBackoff(),
existing.getLifespan(),
existing.getMaxInstances(),
existing.getSerializedData(),
isRunning);
iter.set(updated);
}
}
}
@Override
public synchronized void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime) {
jobDatabase.updateJobAfterRetry(id, isRunning, runAttempt, nextRunAttemptTime);
ListIterator<JobSpec> iter = jobs.listIterator();
while (iter.hasNext()) {
JobSpec existing = iter.next();
if (existing.getId().equals(id)) {
JobSpec updated = new JobSpec(existing.getId(),
existing.getFactoryKey(),
existing.getQueueKey(),
existing.getCreateTime(),
nextRunAttemptTime,
runAttempt,
existing.getMaxAttempts(),
existing.getMaxBackoff(),
existing.getLifespan(),
existing.getMaxInstances(),
existing.getSerializedData(),
isRunning);
iter.set(updated);
}
}
}
@Override
public synchronized void updateAllJobsToBePending() {
jobDatabase.updateAllJobsToBePending();
ListIterator<JobSpec> iter = jobs.listIterator();
while (iter.hasNext()) {
JobSpec existing = iter.next();
JobSpec updated = new JobSpec(existing.getId(),
existing.getFactoryKey(),
existing.getQueueKey(),
existing.getCreateTime(),
existing.getNextRunAttemptTime(),
existing.getRunAttempt(),
existing.getMaxAttempts(),
existing.getMaxBackoff(),
existing.getLifespan(),
existing.getMaxInstances(),
existing.getSerializedData(),
false);
iter.set(updated);
}
}
@Override
public synchronized void deleteJob(@NonNull String jobId) {
deleteJobs(Collections.singletonList(jobId));
}
@Override
public synchronized void deleteJobs(@NonNull List<String> jobIds) {
jobDatabase.deleteJobs(jobIds);
Set<String> deleteIds = new HashSet<>(jobIds);
Iterator<JobSpec> jobIter = jobs.iterator();
while (jobIter.hasNext()) {
if (deleteIds.contains(jobIter.next().getId())) {
jobIter.remove();
}
}
for (String jobId : jobIds) {
constraintsByJobId.remove(jobId);
dependenciesByJobId.remove(jobId);
for (Map.Entry<String, List<DependencySpec>> entry : dependenciesByJobId.entrySet()) {
Iterator<DependencySpec> depedencyIter = entry.getValue().iterator();
while (depedencyIter.hasNext()) {
if (depedencyIter.next().getDependsOnJobId().equals(jobId)) {
depedencyIter.remove();
}
}
}
}
}
@Override
public synchronized @NonNull List<ConstraintSpec> getConstraintSpecs(@NonNull String jobId) {
return Util.getOrDefault(constraintsByJobId, jobId, new LinkedList<>());
}
@Override
public synchronized @NonNull List<ConstraintSpec> getAllConstraintSpecs() {
return Stream.of(constraintsByJobId)
.map(Map.Entry::getValue)
.flatMap(Stream::of)
.toList();
}
@Override
public synchronized @NonNull List<DependencySpec> getDependencySpecsThatDependOnJob(@NonNull String jobSpecId) {
return Stream.of(dependenciesByJobId.entrySet())
.map(Map.Entry::getValue)
.flatMap(Stream::of)
.filter(j -> j.getDependsOnJobId().equals(jobSpecId))
.toList();
}
@Override
public @NonNull List<DependencySpec> getAllDependencySpecs() {
return Stream.of(dependenciesByJobId)
.map(Map.Entry::getValue)
.flatMap(Stream::of)
.toList();
}
}

View File

@@ -28,13 +28,14 @@ import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import org.thoughtcrime.securesms.gcm.FcmUtil;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
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.notifications.NotificationChannels;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -43,38 +44,40 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class FcmRefreshJob extends BaseJob implements InjectableType {
public class FcmRefreshJob extends ContextJob implements InjectableType {
public static final String KEY = "FcmRefreshJob";
private static final String TAG = FcmRefreshJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager textSecureAccountManager;
@Inject SignalServiceAccountManager textSecureAccountManager;
public FcmRefreshJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public FcmRefreshJob() {
this(new Job.Parameters.Builder()
.setQueue("FcmRefreshJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(1)
.setLifespan(TimeUnit.MINUTES.toMillis(5))
.setMaxInstances(1)
.build());
}
public FcmRefreshJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(FcmRefreshJob.class.getSimpleName())
.withDuplicatesIgnored(true)
.withNetworkRequirement()
.withRetryCount(1)
.create());
private FcmRefreshJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -139,4 +142,10 @@ public class FcmRefreshJob extends ContextJob implements InjectableType {
.notify(12, builder.build());
}
public static final class Factory implements Job.Factory<FcmRefreshJob> {
@Override
public @NonNull FcmRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new FcmRefreshJob(parameters);
}
}
}

View File

@@ -0,0 +1,86 @@
package org.thoughtcrime.securesms.jobs;
import android.app.Application;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.Constraint;
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class JobManagerFactories {
public static Map<String, Job.Factory> getJobFactories(@NonNull Application application) {
return new HashMap<String, Job.Factory>() {{
put(AttachmentDownloadJob.KEY, new AttachmentDownloadJob.Factory());
put(AttachmentUploadJob.KEY, new AttachmentUploadJob.Factory());
put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory());
put(CleanPreKeysJob.KEY, new CleanPreKeysJob.Factory());
put(CreateSignedPreKeyJob.KEY, new CreateSignedPreKeyJob.Factory());
put(DirectoryRefreshJob.KEY, new DirectoryRefreshJob.Factory(application));
put(FcmRefreshJob.KEY, new FcmRefreshJob.Factory());
put(LocalBackupJob.KEY, new LocalBackupJob.Factory());
put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory());
put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory());
put(MmsSendJob.KEY, new MmsSendJob.Factory());
put(MultiDeviceBlockedUpdateJob.KEY, new MultiDeviceBlockedUpdateJob.Factory());
put(MultiDeviceConfigurationUpdateJob.KEY, new MultiDeviceConfigurationUpdateJob.Factory());
put(MultiDeviceContactUpdateJob.KEY, new MultiDeviceContactUpdateJob.Factory());
put(MultiDeviceGroupUpdateJob.KEY, new MultiDeviceGroupUpdateJob.Factory());
put(MultiDeviceProfileKeyUpdateJob.KEY, new MultiDeviceProfileKeyUpdateJob.Factory());
put(MultiDeviceReadUpdateJob.KEY, new MultiDeviceReadUpdateJob.Factory());
put(MultiDeviceVerifiedUpdateJob.KEY, new MultiDeviceVerifiedUpdateJob.Factory());
put(PushContentReceiveJob.KEY, new PushContentReceiveJob.Factory());
put(PushDecryptJob.KEY, new PushDecryptJob.Factory());
put(PushGroupSendJob.KEY, new PushGroupSendJob.Factory());
put(PushGroupUpdateJob.KEY, new PushGroupUpdateJob.Factory());
put(PushMediaSendJob.KEY, new PushMediaSendJob.Factory());
put(PushNotificationReceiveJob.KEY, new PushNotificationReceiveJob.Factory());
put(PushTextSendJob.KEY, new PushTextSendJob.Factory());
put(RefreshAttributesJob.KEY, new RefreshAttributesJob.Factory());
put(RefreshPreKeysJob.KEY, new RefreshPreKeysJob.Factory());
put(RefreshUnidentifiedDeliveryAbilityJob.KEY, new RefreshUnidentifiedDeliveryAbilityJob.Factory());
put(RequestGroupInfoJob.KEY, new RequestGroupInfoJob.Factory());
put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application));
put(RetrieveProfileJob.KEY, new RetrieveProfileJob.Factory(application));
put(RotateCertificateJob.KEY, new RotateCertificateJob.Factory());
put(RotateProfileKeyJob.KEY, new RotateProfileKeyJob.Factory());
put(RotateSignedPreKeyJob.KEY, new RotateSignedPreKeyJob.Factory());
put(SendDeliveryReceiptJob.KEY, new SendDeliveryReceiptJob.Factory());
put(SendReadReceiptJob.KEY, new SendReadReceiptJob.Factory());
put(ServiceOutageDetectionJob.KEY, new ServiceOutageDetectionJob.Factory());
put(SmsReceiveJob.KEY, new SmsReceiveJob.Factory());
put(SmsSendJob.KEY, new SmsSendJob.Factory());
put(SmsSentJob.KEY, new SmsSentJob.Factory());
put(TrimThreadJob.KEY, new TrimThreadJob.Factory());
put(TypingSendJob.KEY, new TypingSendJob.Factory());
put(UpdateApkJob.KEY, new UpdateApkJob.Factory());
}};
}
public static Map<String, Constraint.Factory> getConstraintFactories(@NonNull Application application) {
return new HashMap<String, Constraint.Factory>() {{
put(CellServiceConstraint.KEY, new CellServiceConstraint.Factory(application));
put(NetworkConstraint.KEY, new NetworkConstraint.Factory(application));
put(NetworkOrCellServiceConstraint.KEY, new NetworkOrCellServiceConstraint.Factory(application));
put(SqlCipherMigrationConstraint.KEY, new SqlCipherMigrationConstraint.Factory(application));
}};
}
public static List<ConstraintObserver> getConstraintObservers(@NonNull Application application) {
return Arrays.asList(new CellServiceConstraintObserver(application),
new NetworkConstraintObserver(application),
new SqlCipherMigrationConstraintObserver());
}
}

View File

@@ -2,11 +2,11 @@ package org.thoughtcrime.securesms.jobs;
import android.Manifest;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.backup.BackupPassphrase;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.R;
@@ -14,13 +14,11 @@ import org.thoughtcrime.securesms.backup.FullBackupExporter;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.NoExternalStorageException;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.service.GenericForegroundService;
import org.thoughtcrime.securesms.util.BackupUtil;
import org.thoughtcrime.securesms.util.StorageUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.io.File;
import java.io.IOException;
@@ -28,31 +26,32 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class LocalBackupJob extends BaseJob {
public class LocalBackupJob extends ContextJob {
public static final String KEY = "LocalBackupJob";
private static final String TAG = LocalBackupJob.class.getSimpleName();
public LocalBackupJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public LocalBackupJob() {
this(new Job.Parameters.Builder()
.setQueue("__LOCAL_BACKUP__")
.setMaxInstances(1)
.setMaxAttempts(3)
.build());
}
public LocalBackupJob(@NonNull Context context) {
super(context, JobParameters.newBuilder()
.withGroupId("__LOCAL_BACKUP__")
.withDuplicatesIgnored(true)
.create());
private LocalBackupJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -109,6 +108,12 @@ public class LocalBackupJob extends ContextJob {
@Override
public void onCanceled() {
}
public static class Factory implements Job.Factory<LocalBackupJob> {
@Override
public @NonNull LocalBackupJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new LocalBackupJob(parameters);
}
}
}

View File

@@ -1,11 +1,11 @@
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import com.google.android.mms.pdu_alt.CharacterSets;
@@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase;
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.mms.ApnUnavailableException;
import org.thoughtcrime.securesms.mms.CompatMmsConnection;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
@@ -46,12 +45,9 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MmsDownloadJob extends BaseJob {
public class MmsDownloadJob extends ContextJob {
private static final long serialVersionUID = 1L;
public static final String KEY = "MmsDownloadJob";
private static final String TAG = MmsDownloadJob.class.getSimpleName();
@@ -63,14 +59,19 @@ public class MmsDownloadJob extends ContextJob {
private long threadId;
private boolean automatic;
public MmsDownloadJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MmsDownloadJob(long messageId, long threadId, boolean automatic) {
this(new Job.Parameters.Builder()
.setQueue("mms-operation")
.setMaxAttempts(25)
.build(),
messageId,
threadId,
automatic);
}
public MmsDownloadJob(Context context, long messageId, long threadId, boolean automatic) {
super(context, JobParameters.newBuilder()
.withGroupId("mms-operation")
.create());
private MmsDownloadJob(@NonNull Job.Parameters parameters, long messageId, long threadId, boolean automatic) {
super(parameters);
this.messageId = messageId;
this.threadId = threadId;
@@ -78,18 +79,16 @@ public class MmsDownloadJob extends ContextJob {
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
threadId = data.getLong(KEY_THREAD_ID);
automatic = data.getBoolean(KEY_AUTOMATIC);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_THREAD_ID, threadId)
.putBoolean(KEY_AUTOMATIC, automatic)
.build();
}
@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();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -269,4 +268,14 @@ public class MmsDownloadJob extends ContextJob {
MessageNotifier.updateNotification(context, threadId);
}
}
public static final class Factory implements Job.Factory<MmsDownloadJob> {
@Override
public @NonNull MmsDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MmsDownloadJob(parameters,
data.getLong(KEY_MESSAGE_ID),
data.getLong(KEY_THREAD_ID),
data.getBoolean(KEY_AUTOMATIC));
}
}
}

View File

@@ -1,8 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import android.support.annotation.NonNull;
@@ -17,19 +16,15 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.database.Address;
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;
import androidx.work.WorkerParameters;
public class MmsReceiveJob extends BaseJob {
public class MmsReceiveJob extends ContextJob {
private static final long serialVersionUID = 1L;
public static final String KEY = "MmsReceiveJob";
private static final String TAG = MmsReceiveJob.class.getSimpleName();
@@ -39,32 +34,27 @@ public class MmsReceiveJob extends ContextJob {
private byte[] data;
private int subscriptionId;
public MmsReceiveJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MmsReceiveJob(byte[] data, int subscriptionId) {
this(new Job.Parameters.Builder().setMaxAttempts(25).build(), data, subscriptionId);
}
public MmsReceiveJob(Context context, byte[] data, int subscriptionId) {
super(context, JobParameters.newBuilder().create());
private MmsReceiveJob(@NonNull Job.Parameters parameters, byte[] data, int subscriptionId) {
super(parameters);
this.data = data;
this.subscriptionId = subscriptionId;
}
@Override
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);
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_DATA, Base64.encodeBytes(data))
.putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_DATA, Base64.encodeBytes(data))
.putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -91,8 +81,7 @@ public class MmsReceiveJob extends ContextJob {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MmsDownloadJob(context,
messageAndThreadId.first,
.add(new MmsDownloadJob(messageAndThreadId.first,
messageAndThreadId.second,
true));
} else if (isNotification(pdu)) {
@@ -122,4 +111,15 @@ public class MmsReceiveJob extends ContextJob {
private boolean isNotification(GenericPdu pdu) {
return pdu != null && pdu.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
}
public static final class Factory implements Job.Factory<MmsReceiveJob> {
@Override
public @NonNull MmsReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) {
try {
return new MmsReceiveJob(parameters, Base64.decode(data.getString(KEY_DATA)), data.getInt(KEY_SUBSCRIPTION_ID));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -4,7 +4,9 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import android.webkit.MimeTypeMap;
@@ -28,7 +30,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
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.mms.CompatMmsConnection;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MmsException;
@@ -49,12 +50,9 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MmsSendJob extends SendJob {
private static final long serialVersionUID = 0L;
public static final String KEY = "MmsSendJob";
private static final String TAG = MmsSendJob.class.getSimpleName();
@@ -62,28 +60,28 @@ public class MmsSendJob extends SendJob {
private long messageId;
public MmsSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MmsSendJob(long messageId) {
this(new Job.Parameters.Builder()
.setQueue("mms-operation")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(15)
.build(),
messageId);
}
public MmsSendJob(Context context, long messageId) {
super(context, JobParameters.newBuilder()
.withGroupId("mms-operation")
.withNetworkRequirement()
.withRetryCount(15)
.create());
private MmsSendJob(@NonNull Job.Parameters parameters, long messageId) {
super(parameters);
this.messageId = messageId;
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId).build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -318,4 +316,11 @@ public class MmsSendJob extends SendJob {
throw new UndeliverableMessageException(e);
}
}
public static class Factory implements Job.Factory<MmsSendJob> {
@Override
public @NonNull MmsSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MmsSendJob(parameters, data.getLong(KEY_MESSAGE_ID));
}
}
}

View File

@@ -1,16 +1,15 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
@@ -24,39 +23,40 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
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;
import androidx.work.WorkerParameters;
public class MultiDeviceBlockedUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceBlockedUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "MultiDeviceBlockedUpdateJob";
@SuppressWarnings("unused")
private static final String TAG = MultiDeviceBlockedUpdateJob.class.getSimpleName();
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
public MultiDeviceBlockedUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MultiDeviceBlockedUpdateJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("MultiDeviceBlockedUpdateJob")
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build());
}
public MultiDeviceBlockedUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(MultiDeviceBlockedUpdateJob.class.getSimpleName())
.create());
private MultiDeviceBlockedUpdateJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -97,6 +97,12 @@ public class MultiDeviceBlockedUpdateJob extends ContextJob implements Injectabl
@Override
public void onCanceled() {
}
public static final class Factory implements Job.Factory<MultiDeviceBlockedUpdateJob> {
@Override
public @NonNull MultiDeviceBlockedUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MultiDeviceBlockedUpdateJob(parameters);
}
}
}

View File

@@ -1,13 +1,13 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
@@ -21,12 +21,9 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MultiDeviceConfigurationUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceConfigurationUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "MultiDeviceConfigurationUpdateJob";
private static final String TAG = MultiDeviceConfigurationUpdateJob.class.getSimpleName();
@@ -35,27 +32,37 @@ public class MultiDeviceConfigurationUpdateJob extends ContextJob implements Inj
private static final String KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED = "unidentified_delivery_indicators_enabled";
private static final String KEY_LINK_PREVIEWS_ENABLED = "link_previews_enabled";
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private boolean readReceiptsEnabled;
private boolean typingIndicatorsEnabled;
private boolean unidentifiedDeliveryIndicatorsEnabled;
private boolean linkPreviewsEnabled;
public MultiDeviceConfigurationUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public MultiDeviceConfigurationUpdateJob(Context context,
boolean readReceiptsEnabled,
public MultiDeviceConfigurationUpdateJob(boolean readReceiptsEnabled,
boolean typingIndicatorsEnabled,
boolean unidentifiedDeliveryIndicatorsEnabled,
boolean linkPreviewsEnabled)
{
super(context, JobParameters.newBuilder()
.withGroupId("__MULTI_DEVICE_CONFIGURATION_UPDATE_JOB__")
.withNetworkRequirement()
.create());
this(new Job.Parameters.Builder()
.setQueue("__MULTI_DEVICE_CONFIGURATION_UPDATE_JOB__")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(10)
.build(),
readReceiptsEnabled,
typingIndicatorsEnabled,
unidentifiedDeliveryIndicatorsEnabled,
linkPreviewsEnabled);
}
private MultiDeviceConfigurationUpdateJob(@NonNull Job.Parameters parameters,
boolean readReceiptsEnabled,
boolean typingIndicatorsEnabled,
boolean unidentifiedDeliveryIndicatorsEnabled,
boolean linkPreviewsEnabled)
{
super(parameters);
this.readReceiptsEnabled = readReceiptsEnabled;
this.typingIndicatorsEnabled = typingIndicatorsEnabled;
@@ -64,20 +71,17 @@ public class MultiDeviceConfigurationUpdateJob extends ContextJob implements Inj
}
@Override
protected void initialize(@NonNull SafeData data) {
readReceiptsEnabled = data.getBoolean(KEY_READ_RECEIPTS_ENABLED);
typingIndicatorsEnabled = data.getBoolean(KEY_TYPING_INDICATORS_ENABLED);
unidentifiedDeliveryIndicatorsEnabled = data.getBoolean(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED);
linkPreviewsEnabled = data.getBoolean(KEY_LINK_PREVIEWS_ENABLED);
public @NonNull Data serialize() {
return new Data.Builder().putBoolean(KEY_READ_RECEIPTS_ENABLED, readReceiptsEnabled)
.putBoolean(KEY_TYPING_INDICATORS_ENABLED, typingIndicatorsEnabled)
.putBoolean(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED, unidentifiedDeliveryIndicatorsEnabled)
.putBoolean(KEY_LINK_PREVIEWS_ENABLED, linkPreviewsEnabled)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putBoolean(KEY_READ_RECEIPTS_ENABLED, readReceiptsEnabled)
.putBoolean(KEY_TYPING_INDICATORS_ENABLED, typingIndicatorsEnabled)
.putBoolean(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED, unidentifiedDeliveryIndicatorsEnabled)
.putBoolean(KEY_LINK_PREVIEWS_ENABLED, linkPreviewsEnabled)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -103,4 +107,15 @@ public class MultiDeviceConfigurationUpdateJob extends ContextJob implements Inj
public void onCanceled() {
Log.w(TAG, "**** Failed to synchronize read receipts state!");
}
public static final class Factory implements Job.Factory<MultiDeviceConfigurationUpdateJob> {
@Override
public @NonNull MultiDeviceConfigurationUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MultiDeviceConfigurationUpdateJob(parameters,
data.getBooleanOrDefault(KEY_READ_RECEIPTS_ENABLED, false),
data.getBooleanOrDefault(KEY_TYPING_INDICATORS_ENABLED, false),
data.getBooleanOrDefault(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED, false),
data.getBooleanOrDefault(KEY_LINK_PREVIEWS_ENABLED, false));
}
}
}

View File

@@ -5,7 +5,6 @@ import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -19,8 +18,9 @@ import org.thoughtcrime.securesms.database.Address;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -49,12 +49,9 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceContactUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 2L;
public static final String KEY = "MultiDeviceContactUpdateJob";
private static final String TAG = MultiDeviceContactUpdateJob.class.getSimpleName();
@@ -63,16 +60,12 @@ public class MultiDeviceContactUpdateJob extends ContextJob implements Injectabl
private static final String KEY_ADDRESS = "address";
private static final String KEY_FORCE_SYNC = "force_sync";
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private @Nullable String address;
private boolean forceSync;
public MultiDeviceContactUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public MultiDeviceContactUpdateJob(@NonNull Context context) {
this(context, false);
}
@@ -86,10 +79,18 @@ public class MultiDeviceContactUpdateJob extends ContextJob implements Injectabl
}
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address, boolean forceSync) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(MultiDeviceContactUpdateJob.class.getSimpleName())
.create());
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("MultiDeviceContactUpdateJob")
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
address,
forceSync);
}
private MultiDeviceContactUpdateJob(@NonNull Job.Parameters parameters, @Nullable Address address, boolean forceSync) {
super(parameters);
this.forceSync = forceSync;
@@ -98,16 +99,15 @@ public class MultiDeviceContactUpdateJob extends ContextJob implements Injectabl
}
@Override
protected void initialize(@NonNull SafeData data) {
address = data.getString(KEY_ADDRESS);
forceSync = data.getBoolean(KEY_FORCE_SYNC);
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_ADDRESS, address)
.putBoolean(KEY_FORCE_SYNC, forceSync)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_ADDRESS, address)
.putBoolean(KEY_FORCE_SYNC, forceSync)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -335,4 +335,13 @@ public class MultiDeviceContactUpdateJob extends ContextJob implements Injectabl
}
}
public static final class Factory implements Job.Factory<MultiDeviceContactUpdateJob> {
@Override
public @NonNull MultiDeviceContactUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
String serialized = data.getString(KEY_ADDRESS);
Address address = serialized != null ? Address.fromSerialized(serialized) : null;
return new MultiDeviceContactUpdateJob(parameters, address, data.getBoolean(KEY_FORCE_SYNC));
}
}
}

View File

@@ -1,20 +1,19 @@
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;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
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.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
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.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -33,37 +32,39 @@ import java.io.FileOutputStream;
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;
import androidx.work.WorkerParameters;
public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceGroupUpdateJob extends ContextJob implements InjectableType {
public static final String KEY = "MultiDeviceGroupUpdateJob";
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceGroupUpdateJob.class.getSimpleName();
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
public MultiDeviceGroupUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MultiDeviceGroupUpdateJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("MultiDeviceGroupUpdateJob")
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build());
}
public MultiDeviceGroupUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(MultiDeviceGroupUpdateJob.class.getSimpleName())
.create());
private MultiDeviceGroupUpdateJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
@@ -160,5 +161,10 @@ public class MultiDeviceGroupUpdateJob extends ContextJob implements InjectableT
return file;
}
public static final class Factory implements Job.Factory<MultiDeviceGroupUpdateJob> {
@Override
public @NonNull MultiDeviceGroupUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MultiDeviceGroupUpdateJob(parameters);
}
}
}

View File

@@ -1,17 +1,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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -27,51 +26,53 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MultiDeviceProfileKeyUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceProfileKeyUpdateJob extends ContextJob implements InjectableType {
public static String KEY = "MultiDeviceProfileKeyUpdateJob";
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceProfileKeyUpdateJob.class.getSimpleName();
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
public MultiDeviceProfileKeyUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MultiDeviceProfileKeyUpdateJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("MultiDeviceProfileKeyUpdateJob")
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build());
}
public MultiDeviceProfileKeyUpdateJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(MultiDeviceProfileKeyUpdateJob.class.getSimpleName())
.create());
private MultiDeviceProfileKeyUpdateJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
if (!TextSecurePreferences.isMultiDevice(getContext())) {
if (!TextSecurePreferences.isMultiDevice(context)) {
Log.i(TAG, "Not multi device...");
return;
}
Optional<byte[]> profileKey = Optional.of(ProfileKeyUtil.getProfileKey(getContext()));
Optional<byte[]> profileKey = Optional.of(ProfileKeyUtil.getProfileKey(context));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos);
out.write(new DeviceContact(TextSecurePreferences.getLocalNumber(getContext()),
out.write(new DeviceContact(TextSecurePreferences.getLocalNumber(context),
Optional.absent(),
Optional.absent(),
Optional.absent(),
@@ -101,4 +102,11 @@ public class MultiDeviceProfileKeyUpdateJob extends ContextJob implements Inject
public void onCanceled() {
Log.w(TAG, "Profile key sync failed!");
}
public static final class Factory implements Job.Factory<MultiDeviceProfileKeyUpdateJob> {
@Override
public @NonNull MultiDeviceProfileKeyUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new MultiDeviceProfileKeyUpdateJob(parameters);
}
}
}

View File

@@ -1,86 +0,0 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
/**
* Use {@link MultiDeviceConfigurationUpdateJob}.
*/
@Deprecated
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 boolean enabled;
public MultiDeviceReadReceiptUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public MultiDeviceReadReceiptUpdateJob(Context context, boolean enabled) {
super(context, JobParameters.newBuilder()
.withGroupId("__MULTI_DEVICE_READ_RECEIPT_UPDATE_JOB__")
.withNetworkRequirement()
.create());
this.enabled = enabled;
}
@Override
protected void initialize(@NonNull SafeData data) {
enabled = data.getBoolean(KEY_ENABLED);
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putBoolean(KEY_ENABLED, enabled).build();
}
@Override
public void onRun() throws IOException, UntrustedIdentityException {
if (!TextSecurePreferences.isMultiDevice(context)) {
Log.i(TAG, "Not multi device, aborting...");
return;
}
messageSender.sendMessage(SignalServiceSyncMessage.forConfiguration(new ConfigurationMessage(Optional.of(enabled), Optional.absent(), Optional.absent(), Optional.absent())),
UnidentifiedAccessUtil.getAccessForSync(context));
}
@Override
public boolean onShouldRetry(Exception e) {
return e instanceof PushNetworkException;
}
@Override
public void onCanceled() {
Log.w(TAG, "**** Failed to synchronize read receipts state!");
}
}

View File

@@ -1,21 +1,21 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import com.annimon.stream.Stream;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
@@ -24,34 +24,35 @@ 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 java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class MultiDeviceReadUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceReadUpdateJob extends ContextJob implements InjectableType {
public static final String KEY = "MultiDeviceReadUpdateJob";
private static final long serialVersionUID = 1L;
private static final String TAG = MultiDeviceReadUpdateJob.class.getSimpleName();
private static final String KEY_MESSAGE_IDS = "message_ids";
private List<SerializableSyncMessageId> messageIds;
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
public MultiDeviceReadUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MultiDeviceReadUpdateJob(List<SyncMessageId> messageIds) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
messageIds);
}
public MultiDeviceReadUpdateJob(Context context, List<SyncMessageId> messageIds) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.create());
private MultiDeviceReadUpdateJob(@NonNull Job.Parameters parameters, @NonNull List<SyncMessageId> messageIds) {
super(parameters);
this.messageIds = new LinkedList<>();
@@ -61,21 +62,7 @@ public class MultiDeviceReadUpdateJob extends ContextJob implements InjectableTy
}
@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) {
public @NonNull Data serialize() {
String[] ids = new String[messageIds.size()];
for (int i = 0; i < ids.length; i++) {
@@ -86,7 +73,12 @@ public class MultiDeviceReadUpdateJob extends ContextJob implements InjectableTy
}
}
return dataBuilder.putStringArray(KEY_MESSAGE_IDS, ids).build();
return new Data.Builder().putStringArray(KEY_MESSAGE_IDS, ids).build();
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -130,4 +122,23 @@ public class MultiDeviceReadUpdateJob extends ContextJob implements InjectableTy
this.timestamp = timestamp;
}
}
public static final class Factory implements Job.Factory<MultiDeviceReadUpdateJob> {
@Override
public @NonNull MultiDeviceReadUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
List<SyncMessageId> ids = Stream.of(data.getStringArray(KEY_MESSAGE_IDS))
.map(id -> {
try {
return JsonUtils.fromJson(id, SerializableSyncMessageId.class);
} catch (IOException e) {
throw new AssertionError(e);
}
})
.map(id -> new SyncMessageId(Address.fromSerialized(id.sender), id.timestamp))
.toList();
return new MultiDeviceReadUpdateJob(parameters, ids);
}
}
}

View File

@@ -1,19 +1,18 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
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.util.Base64;
import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKey;
@@ -25,15 +24,13 @@ import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage
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;
import androidx.work.WorkerParameters;
public class MultiDeviceVerifiedUpdateJob extends BaseJob implements InjectableType {
public class MultiDeviceVerifiedUpdateJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "MultiDeviceVerifiedUpdateJob";
private static final String TAG = MultiDeviceVerifiedUpdateJob.class.getSimpleName();
@@ -42,50 +39,52 @@ public class MultiDeviceVerifiedUpdateJob extends ContextJob implements Injectab
private static final String KEY_VERIFIED_STATUS = "verified_status";
private static final String KEY_TIMESTAMP = "timestamp";
@Inject
transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private String destination;
private byte[] identityKey;
private VerifiedStatus verifiedStatus;
private long timestamp;
public MultiDeviceVerifiedUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public MultiDeviceVerifiedUpdateJob(Address destination, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("__MULTI_DEVICE_VERIFIED_UPDATE__")
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
destination,
identityKey.serialize(),
verifiedStatus,
System.currentTimeMillis());
}
public MultiDeviceVerifiedUpdateJob(Context context, Address destination, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId("__MULTI_DEVICE_VERIFIED_UPDATE__")
.create());
private MultiDeviceVerifiedUpdateJob(@NonNull Job.Parameters parameters,
@NonNull Address destination,
@NonNull byte[] identityKey,
@NonNull VerifiedStatus verifiedStatus,
long timestamp)
{
super(parameters);
this.destination = destination.serialize();
this.identityKey = identityKey.serialize();
this.identityKey = identityKey;
this.verifiedStatus = verifiedStatus;
this.timestamp = System.currentTimeMillis();
this.timestamp = timestamp;
}
@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);
}
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_DESTINATION, destination)
.putString(KEY_IDENTITY_KEY, Base64.encodeBytes(identityKey))
.putInt(KEY_VERIFIED_STATUS, verifiedStatus.toInt())
.putLong(KEY_TIMESTAMP, timestamp)
.build();
}
@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();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -134,4 +133,20 @@ public class MultiDeviceVerifiedUpdateJob extends ContextJob implements Injectab
public void onCanceled() {
}
public static final class Factory implements Job.Factory<MultiDeviceVerifiedUpdateJob> {
@Override
public @NonNull MultiDeviceVerifiedUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) {
try {
Address destination = Address.fromSerialized(data.getString(KEY_DESTINATION));
VerifiedStatus verifiedStatus = VerifiedStatus.forState(data.getInt(KEY_VERIFIED_STATUS));
long timestamp = data.getLong(KEY_TIMESTAMP);
byte[] identityKey = Base64.decode(data.getString(KEY_IDENTITY_KEY));
return new MultiDeviceVerifiedUpdateJob(parameters, destination, identityKey, verifiedStatus, timestamp);
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -3,37 +3,30 @@ 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;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.InvalidVersionException;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import java.io.IOException;
import androidx.work.Data;
import androidx.work.WorkerParameters;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
public class PushContentReceiveJob extends PushReceivedJob {
private static final long serialVersionUID = 5685475456901715638L;
public PushContentReceiveJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public static final String KEY = "PushContentReceiveJob";
public PushContentReceiveJob(Context context) {
super(context, JobParameters.newBuilder().create());
this(new Job.Parameters.Builder().build());
setContext(context);
}
private PushContentReceiveJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) { }
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -46,4 +39,11 @@ public class PushContentReceiveJob extends PushReceivedJob {
public boolean onShouldRetry(Exception exception) {
return false;
}
public static final class Factory implements Job.Factory<PushContentReceiveJob> {
@Override
public @NonNull PushContentReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PushContentReceiveJob(parameters);
}
}
}

View File

@@ -55,8 +55,8 @@ import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.linkpreview.Link;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
@@ -112,12 +112,9 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushDecryptJob extends BaseJob {
public class PushDecryptJob extends ContextJob {
private static final long serialVersionUID = 2L;
public static final String KEY = "PushDecryptJob";
public static final String TAG = PushDecryptJob.class.getSimpleName();
@@ -127,10 +124,6 @@ public class PushDecryptJob extends ContextJob {
private long messageId;
private long smsMessageId;
public PushDecryptJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public PushDecryptJob(Context context) {
this(context, -1);
}
@@ -140,24 +133,32 @@ public class PushDecryptJob extends ContextJob {
}
public PushDecryptJob(Context context, long pushMessageId, long smsMessageId) {
super(context, JobParameters.newBuilder()
.withGroupId("__PUSH_DECRYPT_JOB__")
.create());
this(new Job.Parameters.Builder()
.setQueue("__PUSH_DECRYPT_JOB__")
.setMaxAttempts(10)
.build(),
pushMessageId,
smsMessageId);
setContext(context);
}
private PushDecryptJob(@NonNull Job.Parameters parameters, long pushMessageId, long smsMessageId) {
super(parameters);
this.messageId = pushMessageId;
this.smsMessageId = smsMessageId;
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
smsMessageId = data.getLong(KEY_SMS_MESSAGE_ID);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_SMS_MESSAGE_ID, smsMessageId)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_SMS_MESSAGE_ID, smsMessageId)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -287,7 +288,7 @@ public class PushDecryptJob extends ContextJob {
resetRecipientToPush(Recipient.from(context, Address.fromExternal(context, content.getSender()), false));
if (envelope.isPreKeySignalMessage()) {
ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob(context));
ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob());
}
} catch (ProtocolInvalidVersionException e) {
Log.w(TAG, e);
@@ -475,7 +476,7 @@ public class PushDecryptJob extends ContextJob {
{
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RequestGroupInfoJob(context, content.getSender(), group.getGroupId()));
.add(new RequestGroupInfoJob(content.getSender(), group.getGroupId()));
}
private void handleExpirationUpdate(@NonNull SignalServiceContent content,
@@ -552,8 +553,8 @@ public class PushDecryptJob extends ContextJob {
}
if (threadId != null) {
DatabaseFactory.getThreadDatabase(getContext()).setRead(threadId, true);
MessageNotifier.updateNotification(getContext());
DatabaseFactory.getThreadDatabase(context).setRead(threadId, true);
MessageNotifier.updateNotification(context);
}
MessageNotifier.setLastDesktopActivityTimestamp(message.getTimestamp());
@@ -567,33 +568,32 @@ public class PushDecryptJob extends ContextJob {
if (message.isContactsRequest()) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MultiDeviceContactUpdateJob(getContext(), true));
.add(new MultiDeviceContactUpdateJob(context, true));
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RefreshUnidentifiedDeliveryAbilityJob(context));
.add(new RefreshUnidentifiedDeliveryAbilityJob());
}
if (message.isGroupsRequest()) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MultiDeviceGroupUpdateJob(getContext()));
.add(new MultiDeviceGroupUpdateJob());
}
if (message.isBlockedListRequest()) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MultiDeviceBlockedUpdateJob(getContext()));
.add(new MultiDeviceBlockedUpdateJob());
}
if (message.isConfigurationRequest()) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new MultiDeviceConfigurationUpdateJob(getContext(),
TextSecurePreferences.isReadReceiptsEnabled(getContext()),
TextSecurePreferences.isTypingIndicatorsEnabled(getContext()),
TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()),
TextSecurePreferences.isLinkPreviewsEnabled(getContext())));
.add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(context),
TextSecurePreferences.isTypingIndicatorsEnabled(context),
TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context),
TextSecurePreferences.isLinkPreviewsEnabled(context)));
}
}
@@ -652,7 +652,7 @@ public class PushDecryptJob extends ContextJob {
for (DatabaseAttachment attachment : attachments) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new AttachmentDownloadJob(context, insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
.add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
}
if (smsMessageId.isPresent()) {
@@ -725,7 +725,7 @@ public class PushDecryptJob extends ContextJob {
for (DatabaseAttachment attachment : DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageId)) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new AttachmentDownloadJob(context, messageId, attachment.getAttachmentId(), false));
.add(new AttachmentDownloadJob(messageId, attachment.getAttachmentId(), false));
}
if (message.getMessage().getExpiresInSeconds() > 0) {
@@ -938,7 +938,7 @@ public class PushDecryptJob extends ContextJob {
if (recipient.getProfileKey() == null || !MessageDigest.isEqual(recipient.getProfileKey(), message.getProfileKey().get())) {
database.setProfileKey(recipient, message.getProfileKey().get());
database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN);
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileJob(context, recipient));
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileJob(recipient));
}
}
@@ -947,7 +947,7 @@ public class PushDecryptJob extends ContextJob {
{
ApplicationContext.getInstance(context)
.getJobManager()
.add(new SendDeliveryReceiptJob(context, Address.fromExternal(context, content.getSender()), message.getTimestamp()));
.add(new SendDeliveryReceiptJob(Address.fromExternal(context, content.getSender()), message.getTimestamp()));
}
@SuppressLint("DefaultLocale")
@@ -1191,4 +1191,10 @@ public class PushDecryptJob extends ContextJob {
}
}
public static final class Factory implements Job.Factory<PushDecryptJob> {
@Override
public @NonNull PushDecryptJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PushDecryptJob(parameters, data.getLong(KEY_MESSAGE_ID), data.getLong(KEY_SMS_MESSAGE_ID));
}
}
}

View File

@@ -20,17 +20,15 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.ChainParameters;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.GroupUtil;
@@ -46,7 +44,6 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Qu
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
import java.io.IOException;
@@ -58,38 +55,36 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushGroupSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "PushGroupSendJob";
private static final String TAG = PushGroupSendJob.class.getSimpleName();
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
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(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public PushGroupSendJob(long messageId, @NonNull Address destination, @Nullable Address filterAddress) {
this(new Job.Parameters.Builder()
.setQueue(destination.toGroupString())
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
messageId, filterAddress);
}
public PushGroupSendJob(Context context, long messageId, @NonNull Address destination, @Nullable Address filterAddress) {
super(context, JobParameters.newBuilder()
.withGroupId(destination.toGroupString())
.withNetworkRequirement()
.withRetryDuration(TimeUnit.DAYS.toMillis(1))
.create());
private PushGroupSendJob(@NonNull Job.Parameters parameters, long messageId, @Nullable Address filterAddress) {
super(parameters);
this.messageId = messageId;
this.filterAddress = filterAddress == null ? null :filterAddress.toPhoneString();
this.filterRecipientId = -1;
this.messageId = messageId;
this.filterAddress = filterAddress == null ? null :filterAddress.toPhoneString();
}
@WorkerThread
@@ -103,15 +98,14 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(context, ((DatabaseAttachment) a).getAttachmentId())).toList();
ChainParameters chainParams = new ChainParameters.Builder().setGroupId(destination.serialize()).build();
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId())).toList();
if (attachmentJobs.isEmpty()) {
jobManager.add(new PushGroupSendJob(context, messageId, destination, filterAddress));
jobManager.add(new PushGroupSendJob(messageId, destination, filterAddress));
} else {
jobManager.startChain(attachmentJobs)
.then(new PushGroupSendJob(context, messageId, destination, filterAddress))
.enqueue(chainParams);
.then(new PushGroupSendJob(messageId, destination, filterAddress))
.enqueue();
}
} catch (NoSuchMessageException | MmsException e) {
@@ -122,20 +116,19 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
filterAddress = data.getString(KEY_FILTER_ADDRESS);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_FILTER_ADDRESS, filterAddress)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_FILTER_ADDRESS, filterAddress)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
protected void onAdded() {
public void onAdded() {
DatabaseFactory.getMmsDatabase(context).markAsSending(messageId);
}
@@ -287,4 +280,14 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
List<Recipient> members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
return Stream.of(members).map(Recipient::getAddress).toList();
}
public static class Factory implements Job.Factory<PushGroupSendJob> {
@Override
public @NonNull PushGroupSendJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
String address = data.getString(KEY_FILTER_ADDRESS);
Address filter = address != null ? Address.fromSerialized(data.getString(KEY_FILTER_ADDRESS)) : null;
return new PushGroupSendJob(parameters, data.getLong(KEY_MESSAGE_ID), filter);
}
}
}

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
@@ -10,8 +9,9 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
@@ -34,52 +34,47 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushGroupUpdateJob extends BaseJob implements InjectableType {
public class PushGroupUpdateJob extends ContextJob implements InjectableType {
public static final String KEY = "PushGroupUpdateJob";
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;
@Inject SignalServiceMessageSender messageSender;
private String source;
private byte[] groupId;
public PushGroupUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public PushGroupUpdateJob(String source, byte[] groupId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
source,
groupId);
}
public PushGroupUpdateJob(Context context, String source, byte[] groupId) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withRetryDuration(TimeUnit.DAYS.toMillis(1))
.create());
private PushGroupUpdateJob(@NonNull Job.Parameters parameters, String source, byte[] groupId) {
super(parameters);
this.source = source;
this.groupId = groupId;
}
@Override
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);
}
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_SOURCE, source)
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_SOURCE, source)
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -138,4 +133,17 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
public void onCanceled() {
}
public static final class Factory implements Job.Factory<PushGroupUpdateJob> {
@Override
public @NonNull PushGroupUpdateJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
try {
return new PushGroupUpdateJob(parameters,
data.getString(KEY_SOURCE),
GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -17,9 +17,9 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.ChainParameters;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
@@ -48,27 +48,24 @@ import java.util.List;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushMediaSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "PushMediaSendJob";
private static final String TAG = PushMediaSendJob.class.getSimpleName();
private static final String KEY_MESSAGE_ID = "message_id";
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private long messageId;
public PushMediaSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public PushMediaSendJob(long messageId, Address destination) {
this(constructParameters(destination), messageId);
}
public PushMediaSendJob(Context context, long messageId, Address destination) {
super(context, constructParameters(destination));
private PushMediaSendJob(Job.Parameters parameters, long messageId) {
super(parameters);
this.messageId = messageId;
}
@@ -83,15 +80,14 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
attachments.addAll(Stream.of(message.getLinkPreviews()).filter(p -> p.getThumbnail().isPresent()).map(p -> p.getThumbnail().get()).toList());
attachments.addAll(Stream.of(message.getSharedContacts()).filter(c -> c.getAvatar() != null).map(c -> c.getAvatar().getAttachment()).withoutNulls().toList());
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(context, ((DatabaseAttachment) a).getAttachmentId())).toList();
ChainParameters chainParams = new ChainParameters.Builder().setGroupId(destination.serialize()).build();
List<AttachmentUploadJob> attachmentJobs = Stream.of(attachments).map(a -> new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId())).toList();
if (attachmentJobs.isEmpty()) {
jobManager.add(new PushMediaSendJob(context, messageId, destination));
jobManager.add(new PushMediaSendJob(messageId, destination));
} else {
jobManager.startChain(attachmentJobs)
.then(new PushMediaSendJob(context, messageId, destination))
.enqueue(chainParams);
.then(new PushMediaSendJob(messageId, destination))
.enqueue();
}
} catch (NoSuchMessageException | MmsException e) {
@@ -102,17 +98,17 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId).build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
protected void onAdded() {
public void onAdded() {
DatabaseFactory.getMmsDatabase(context).markAsSending(messageId);
}
@@ -173,7 +169,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
warn(TAG, "Failure", ifae);
database.markAsPendingInsecureSmsFallback(messageId);
notifyMediaMessageDeliveryFailed(context, messageId);
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, false));
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(false));
} catch (UntrustedIdentityException uie) {
warn(TAG, "Failure", uie);
database.addMismatchedIdentity(messageId, Address.fromSerialized(uie.getE164Number()), uie.getIdentityKey());
@@ -242,4 +238,11 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
throw new RetryLaterException(e);
}
}
public static final class Factory implements Job.Factory<PushMediaSendJob> {
@Override
public @NonNull PushMediaSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PushMediaSendJob(parameters, data.getLong(KEY_MESSAGE_ID));
}
}
}

View File

@@ -3,10 +3,10 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
@@ -16,33 +16,36 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushNotificationReceiveJob extends PushReceivedJob implements InjectableType {
public static final String KEY = "PushNotificationReceiveJob";
private static final String TAG = PushNotificationReceiveJob.class.getSimpleName();
@Inject transient SignalServiceMessageReceiver receiver;
public PushNotificationReceiveJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
@Inject SignalServiceMessageReceiver receiver;
public PushNotificationReceiveJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId("__notification_received")
.create());
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("__notification_received")
.setMaxAttempts(3)
.setMaxInstances(1)
.build());
setContext(context);
}
private PushNotificationReceiveJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -75,4 +78,11 @@ public class PushNotificationReceiveJob extends PushReceivedJob implements Injec
private static String timeSuffix(long startTime) {
return " (" + (System.currentTimeMillis() - startTime) + " ms elapsed)";
}
public static final class Factory implements Job.Factory<PushNotificationReceiveJob> {
@Override
public @NonNull PushNotificationReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PushNotificationReceiveJob(parameters);
}
}
}

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.jobs;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.ApplicationContext;
@@ -9,25 +8,19 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import androidx.work.WorkerParameters;
public abstract class PushReceivedJob extends ContextJob {
public abstract class PushReceivedJob extends BaseJob {
private static final String TAG = PushReceivedJob.class.getSimpleName();
public static final Object RECEIVE_LOCK = new Object();
protected PushReceivedJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
protected PushReceivedJob(Context context, JobParameters parameters) {
super(context, parameters);
protected PushReceivedJob(Job.Parameters parameters) {
super(parameters);
}
public void processEnvelope(@NonNull SignalServiceEnvelope envelope) {
@@ -38,7 +31,7 @@ public abstract class PushReceivedJob extends ContextJob {
if (!isActiveNumber(recipient)) {
DatabaseFactory.getRecipientDatabase(context).setRegistered(recipient, RecipientDatabase.RegisteredState.REGISTERED);
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, recipient, false));
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(recipient, false));
}
}

View File

@@ -19,7 +19,8 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
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.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
@@ -51,29 +52,22 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import androidx.work.WorkerParameters;
public abstract class PushSendJob extends SendJob {
private static final long serialVersionUID = 5906098204770900739L;
private static final String TAG = PushSendJob.class.getSimpleName();
private static final long CERTIFICATE_EXPIRATION_BUFFER = TimeUnit.DAYS.toMillis(1);
public PushSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
protected PushSendJob(Job.Parameters parameters) {
super(parameters);
}
protected PushSendJob(Context context, JobParameters parameters) {
super(context, parameters);
}
protected static JobParameters constructParameters(Address destination) {
JobParameters.Builder builder = JobParameters.newBuilder();
builder.withGroupId(destination.serialize());
builder.withNetworkRequirement();
builder.withRetryDuration(TimeUnit.DAYS.toMillis(1));
return builder.create();
protected static Job.Parameters constructParameters(Address destination) {
return new Parameters.Builder()
.setQueue(destination.serialize())
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build();
}
@Override
@@ -81,7 +75,7 @@ public abstract class PushSendJob extends SendJob {
if (TextSecurePreferences.getSignedPreKeyFailureCount(context) > 5) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RotateSignedPreKeyJob(context));
.add(new RotateSignedPreKeyJob());
throw new TextSecureExpiredException("Too many signed prekey rotation failures");
}
@@ -94,9 +88,9 @@ public abstract class PushSendJob extends SendJob {
super.onRetry();
Log.i(TAG, "onRetry()");
if (getRunAttemptCount() > 1) {
if (getRunAttempt() > 1) {
Log.i(TAG, "Scheduling service outage detection job.");
ApplicationContext.getInstance(context).getJobManager().add(new ServiceOutageDetectionJob(context));
ApplicationContext.getInstance(context).getJobManager().add(new ServiceOutageDetectionJob());
}
}
@@ -278,7 +272,6 @@ public abstract class PushSendJob extends SendJob {
Log.w(TAG, "Certificate was invalid at send time. Fetching a new one.", e);
RotateCertificateJob certificateJob = new RotateCertificateJob(context);
ApplicationContext.getInstance(context).injectDependencies(certificateJob);
certificateJob.setContext(context);
certificateJob.onRun();
}
}

View File

@@ -1,11 +1,9 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
@@ -15,6 +13,8 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
@@ -34,38 +34,36 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class PushTextSendJob extends PushSendJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "PushTextSendJob";
private static final String TAG = PushTextSendJob.class.getSimpleName();
private static final String KEY_MESSAGE_ID = "message_id";
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private long messageId;
public PushTextSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public PushTextSendJob(long messageId, Address destination) {
this(constructParameters(destination), messageId);
}
public PushTextSendJob(Context context, long messageId, Address destination) {
super(context, constructParameters(destination));
private PushTextSendJob(@NonNull Job.Parameters parameters, long messageId) {
super(parameters);
this.messageId = messageId;
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId).build();
}
@NonNull
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId).build();
public String getFactoryKey() {
return KEY;
}
@Override
@@ -126,7 +124,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
warn(TAG, "Failure", e);
database.markAsPendingInsecureSmsFallback(record.getId());
MessageNotifier.notifyMessageDeliveryFailed(context, record.getRecipient(), record.getThreadId());
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(context, false));
ApplicationContext.getInstance(context).getJobManager().add(new DirectoryRefreshJob(false));
} catch (UntrustedIdentityException e) {
warn(TAG, "Failure", e);
database.addMismatchedIdentity(record.getId(), Address.fromSerialized(e.getE164Number()), e.getIdentityKey());
@@ -191,4 +189,11 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
throw new RetryLaterException(e);
}
}
public static class Factory implements Job.Factory<PushTextSendJob> {
@Override
public @NonNull PushTextSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PushTextSendJob(parameters, data.getLong(KEY_MESSAGE_ID));
}
}
}

View File

@@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -19,35 +19,33 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RefreshAttributesJob extends BaseJob implements InjectableType {
public class RefreshAttributesJob extends ContextJob implements InjectableType {
public static final long serialVersionUID = 1L;
public static final String KEY = "RefreshAttributesJob";
private static final String TAG = RefreshAttributesJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager signalAccountManager;
@Inject SignalServiceAccountManager signalAccountManager;
public RefreshAttributesJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RefreshAttributesJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue("RefreshAttributesJob")
.build());
}
public RefreshAttributesJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withGroupId(RefreshAttributesJob.class.getName())
.create());
private RefreshAttributesJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -63,7 +61,7 @@ public class RefreshAttributesJob extends ContextJob implements InjectableType {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RefreshUnidentifiedDeliveryAbilityJob(context));
.add(new RefreshUnidentifiedDeliveryAbilityJob());
}
@Override
@@ -75,4 +73,11 @@ public class RefreshAttributesJob extends ContextJob implements InjectableType {
public void onCanceled() {
Log.w(TAG, "Failed to update account attributes!");
}
public static class Factory implements Job.Factory<RefreshAttributesJob> {
@Override
public @NonNull RefreshAttributesJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
return new RefreshAttributesJob(parameters);
}
}
}

View File

@@ -1,15 +1,14 @@
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;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -24,36 +23,36 @@ import java.util.List;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RefreshPreKeysJob extends BaseJob implements InjectableType {
public class RefreshPreKeysJob extends ContextJob implements InjectableType {
public static final String KEY = "RefreshPreKeysJob";
private static final String TAG = RefreshPreKeysJob.class.getSimpleName();
private static final int PREKEY_MINIMUM = 10;
@Inject transient SignalServiceAccountManager accountManager;
@Inject SignalServiceAccountManager accountManager;
public RefreshPreKeysJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RefreshPreKeysJob() {
this(new Job.Parameters.Builder()
.setQueue("RefreshPreKeysJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(5)
.build());
}
public RefreshPreKeysJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(RefreshPreKeysJob.class.getSimpleName())
.withNetworkRequirement()
.withRetryCount(5)
.create());
private RefreshPreKeysJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -80,7 +79,7 @@ public class RefreshPreKeysJob extends ContextJob implements InjectableType {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new CleanPreKeysJob(context));
.add(new CleanPreKeysJob());
}
@Override
@@ -93,7 +92,12 @@ public class RefreshPreKeysJob extends ContextJob implements InjectableType {
@Override
public void onCanceled() {
}
public static final class Factory implements Job.Factory<RefreshPreKeysJob> {
@Override
public @NonNull RefreshPreKeysJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RefreshPreKeysJob(parameters);
}
}
}

View File

@@ -1,12 +1,12 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
import org.thoughtcrime.securesms.util.Base64;
@@ -23,31 +23,33 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RefreshUnidentifiedDeliveryAbilityJob extends BaseJob implements InjectableType {
public class RefreshUnidentifiedDeliveryAbilityJob extends ContextJob implements InjectableType {
public static final String KEY = "RefreshUnidentifiedDeliveryAbilityJob";
private static final String TAG = RefreshUnidentifiedDeliveryAbilityJob.class.getSimpleName();
@Inject transient SignalServiceMessageReceiver receiver;
@Inject SignalServiceMessageReceiver receiver;
public RefreshUnidentifiedDeliveryAbilityJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RefreshUnidentifiedDeliveryAbilityJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(10)
.build());
}
public RefreshUnidentifiedDeliveryAbilityJob(Context context) {
super(context, new JobParameters.Builder()
.withNetworkRequirement()
.create());
private RefreshUnidentifiedDeliveryAbilityJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) { }
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -62,8 +64,7 @@ public class RefreshUnidentifiedDeliveryAbilityJob extends ContextJob implements
}
@Override
protected void onCanceled() {
public void onCanceled() {
}
@Override
@@ -94,4 +95,11 @@ public class RefreshUnidentifiedDeliveryAbilityJob extends ContextJob implements
return false;
}
}
public static class Factory implements Job.Factory<RefreshUnidentifiedDeliveryAbilityJob> {
@Override
public @NonNull RefreshUnidentifiedDeliveryAbilityJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RefreshUnidentifiedDeliveryAbilityJob(parameters);
}
}
}

View File

@@ -1,15 +1,14 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -20,56 +19,53 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
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;
import androidx.work.WorkerParameters;
public class RequestGroupInfoJob extends BaseJob implements InjectableType {
public class RequestGroupInfoJob extends ContextJob implements InjectableType {
public static final String KEY = "RequestGroupInfoJob";
@SuppressWarnings("unused")
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;
@Inject SignalServiceMessageSender messageSender;
private String source;
private byte[] groupId;
public RequestGroupInfoJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RequestGroupInfoJob(@NonNull String source, @NonNull byte[] groupId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
source,
groupId);
}
public RequestGroupInfoJob(@NonNull Context context, @NonNull String source, @NonNull byte[] groupId) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withRetryCount(50)
.create());
private RequestGroupInfoJob(@NonNull Job.Parameters parameters, @NonNull String source, @NonNull byte[] groupId) {
super(parameters);
this.source = source;
this.groupId = groupId;
}
@Override
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);
}
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_SOURCE, source)
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_SOURCE, source)
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -97,4 +93,18 @@ public class RequestGroupInfoJob extends ContextJob implements InjectableType {
public void onCanceled() {
}
public static final class Factory implements Job.Factory<RequestGroupInfoJob> {
@Override
public @NonNull RequestGroupInfoJob create(@NonNull Parameters parameters, @NonNull Data data) {
try {
return new RequestGroupInfoJob(parameters,
data.getString(KEY_SOURCE),
GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -1,18 +1,19 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.app.Application;
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
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.profiles.AvatarHelper;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Util;
@@ -23,13 +24,13 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RetrieveProfileAvatarJob extends BaseJob implements InjectableType {
public class RetrieveProfileAvatarJob extends ContextJob implements InjectableType {
public static final String KEY = "RetrieveProfileAvatarJob";
private static final String TAG = RetrieveProfileAvatarJob.class.getSimpleName();
@@ -43,32 +44,34 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
private String profileAvatar;
private Recipient recipient;
public RetrieveProfileAvatarJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RetrieveProfileAvatarJob(Recipient recipient, String profileAvatar) {
this(new Job.Parameters.Builder()
.setQueue("RetrieveProfileAvatarJob" + recipient.getAddress().serialize())
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.HOURS.toMillis(1))
.setMaxInstances(1)
.build(),
recipient,
profileAvatar);
}
public RetrieveProfileAvatarJob(Context context, Recipient recipient, String profileAvatar) {
super(context, JobParameters.newBuilder()
.withGroupId(RetrieveProfileAvatarJob.class.getSimpleName() + recipient.getAddress().serialize())
.withDuplicatesIgnored(true)
.withNetworkRequirement()
.create());
private RetrieveProfileAvatarJob(@NonNull Job.Parameters parameters, @NonNull Recipient recipient, String profileAvatar) {
super(parameters);
this.recipient = recipient;
this.profileAvatar = profileAvatar;
}
@Override
protected void initialize(@NonNull SafeData data) {
profileAvatar = data.getString(KEY_PROFILE_AVATAR);
recipient = Recipient.from(context, Address.fromSerialized(data.getString(KEY_ADDRESS)), true);
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_PROFILE_AVATAR, profileAvatar)
.putString(KEY_ADDRESS, recipient.getAddress().serialize())
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_PROFILE_AVATAR, profileAvatar)
.putString(KEY_ADDRESS, recipient.getAddress().serialize())
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -110,13 +113,27 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
@Override
public boolean onShouldRetry(Exception e) {
Log.w(TAG, e);
if (e instanceof PushNetworkException) return true;
return false;
}
@Override
public void onCanceled() {
}
public static final class Factory implements Job.Factory<RetrieveProfileAvatarJob> {
private final Application application;
public Factory(Application application) {
this.application = application;
}
@Override
public @NonNull RetrieveProfileAvatarJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RetrieveProfileAvatarJob(parameters,
Recipient.from(application, Address.fromSerialized(data.getString(KEY_ADDRESS)), true),
data.getString(KEY_PROFILE_AVATAR));
}
}
}

View File

@@ -1,7 +1,7 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.app.Application;
import android.support.annotation.NonNull;
import android.text.TextUtils;
@@ -12,8 +12,9 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
@@ -38,40 +39,39 @@ import java.util.List;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RetrieveProfileJob extends BaseJob implements InjectableType {
public class RetrieveProfileJob extends ContextJob implements InjectableType {
public static final String KEY = "RetrieveProfileJob";
private static final String TAG = RetrieveProfileJob.class.getSimpleName();
private static final String KEY_ADDRESS = "address";
@Inject transient SignalServiceMessageReceiver receiver;
@Inject SignalServiceMessageReceiver receiver;
private Recipient recipient;
public RetrieveProfileJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RetrieveProfileJob(@NonNull Recipient recipient) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(3)
.build(),
recipient);
}
public RetrieveProfileJob(Context context, Recipient recipient) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withRetryCount(3)
.create());
private RetrieveProfileJob(@NonNull Job.Parameters parameters, @NonNull Recipient recipient) {
super(parameters);
this.recipient = recipient;
}
@Override
protected void initialize(@NonNull SafeData data) {
recipient = Recipient.from(context, Address.fromSerialized(data.getString(KEY_ADDRESS)), true);
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_ADDRESS, recipient.getAddress().serialize()).build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_ADDRESS, recipient.getAddress().serialize()).build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -221,7 +221,7 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
if (!Util.equals(profileAvatar, recipient.getProfileAvatar())) {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RetrieveProfileAvatarJob(context, recipient, profileAvatar));
.add(new RetrieveProfileAvatarJob(recipient, profileAvatar));
}
}
@@ -234,4 +234,18 @@ public class RetrieveProfileJob extends ContextJob implements InjectableType {
return Optional.absent();
}
public static final class Factory implements Job.Factory<RetrieveProfileJob> {
private final Application application;
public Factory(Application application) {
this.application = application;
}
@Override
public @NonNull RetrieveProfileJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RetrieveProfileJob(parameters, Recipient.from(application, Address.fromSerialized(data.getString(KEY_ADDRESS)), true));
}
}
}

View File

@@ -5,55 +5,55 @@ 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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
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;
import androidx.work.WorkerParameters;
@SuppressWarnings("WeakerAccess")
public class RotateCertificateJob extends ContextJob implements InjectableType {
public class RotateCertificateJob extends BaseJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "RotateCertificateJob";
private static final String TAG = RotateCertificateJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager accountManager;
public RotateCertificateJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
@Inject SignalServiceAccountManager accountManager;
public RotateCertificateJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId("__ROTATE_SENDER_CERTIFICATE__")
.withNetworkRequirement()
.create());
this(new Job.Parameters.Builder()
.setQueue("__ROTATE_SENDER_CERTIFICATE__")
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build());
setContext(context);
}
@NonNull
@Override
protected Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
private RotateCertificateJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
public String getFactoryKey() {
return KEY;
}
@Override
public void onAdded() {}
@Override
public void onRun() throws IOException {
synchronized (RotateCertificateJob.class) {
@@ -71,4 +71,11 @@ public class RotateCertificateJob extends ContextJob implements InjectableType {
public void onCanceled() {
Log.w(TAG, "Failed to rotate sender certificate!");
}
public static final class Factory implements Job.Factory<RotateCertificateJob> {
@Override
public @NonNull RotateCertificateJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RotateCertificateJob(parameters);
}
}
}

View File

@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -8,8 +7,9 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
@@ -22,33 +22,33 @@ import java.io.IOException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RotateProfileKeyJob extends BaseJob implements InjectableType {
public class RotateProfileKeyJob extends ContextJob implements InjectableType {
public static String KEY = "RotateProfileKeyJob";
@Inject SignalServiceAccountManager accountManager;
public RotateProfileKeyJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RotateProfileKeyJob() {
this(new Job.Parameters.Builder()
.setQueue("__ROTATE_PROFILE_KEY__")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(25)
.setMaxInstances(1)
.build());
}
public RotateProfileKeyJob(Context context) {
super(context, new JobParameters.Builder()
.withGroupId("__ROTATE_PROFILE_KEY__")
.withDuplicatesIgnored(true)
.withNetworkRequirement()
.create());
}
@NonNull
@Override
protected Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
private RotateProfileKeyJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -60,11 +60,11 @@ public class RotateProfileKeyJob extends ContextJob implements InjectableType {
ApplicationContext.getInstance(context)
.getJobManager()
.add(new RefreshAttributesJob(context));
.add(new RefreshAttributesJob());
}
@Override
protected void onCanceled() {
public void onCanceled() {
}
@@ -86,4 +86,11 @@ public class RotateProfileKeyJob extends ContextJob implements InjectableType {
}
return null;
}
public static final class Factory implements Job.Factory<RotateProfileKeyJob> {
@Override
public @NonNull RotateProfileKeyJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RotateProfileKeyJob(parameters);
}
}
}

View File

@@ -1,16 +1,15 @@
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;
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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
@@ -20,33 +19,33 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class RotateSignedPreKeyJob extends BaseJob implements InjectableType {
public class RotateSignedPreKeyJob extends ContextJob implements InjectableType {
public static final String KEY = "RotateSignedPreKeyJob";
private static final String TAG = RotateSignedPreKeyJob.class.getSimpleName();
@Inject transient SignalServiceAccountManager accountManager;
@Inject SignalServiceAccountManager accountManager;
public RotateSignedPreKeyJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public RotateSignedPreKeyJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(5)
.build());
}
public RotateSignedPreKeyJob(Context context) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.withRetryCount(5)
.create());
private RotateSignedPreKeyJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -64,7 +63,7 @@ public class RotateSignedPreKeyJob extends ContextJob implements InjectableType
ApplicationContext.getInstance(context)
.getJobManager()
.add(new CleanPreKeysJob(context));
.add(new CleanPreKeysJob());
}
@Override
@@ -76,4 +75,11 @@ public class RotateSignedPreKeyJob extends ContextJob implements InjectableType
public void onCanceled() {
TextSecurePreferences.setSignedPreKeyFailureCount(context, TextSecurePreferences.getSignedPreKeyFailureCount(context) + 1);
}
public static final class Factory implements Job.Factory<RotateSignedPreKeyJob> {
@Override
public @NonNull RotateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RotateSignedPreKeyJob(parameters);
}
}
}

View File

@@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@@ -19,15 +19,13 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class SendDeliveryReceiptJob extends BaseJob implements InjectableType {
public class SendDeliveryReceiptJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "SendDeliveryReceiptJob";
private static final String KEY_ADDRESS = "address";
private static final String KEY_MESSAGE_ID = "message_id";
@@ -42,37 +40,40 @@ public class SendDeliveryReceiptJob extends ContextJob implements InjectableType
private long messageId;
private long timestamp;
public SendDeliveryReceiptJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public SendDeliveryReceiptJob(@NonNull Address address, long messageId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
address,
messageId,
System.currentTimeMillis());
}
public SendDeliveryReceiptJob(Context context, Address address, long messageId) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.create());
private SendDeliveryReceiptJob(@NonNull Job.Parameters parameters,
@NonNull Address address,
long messageId,
long timestamp)
{
super(parameters);
this.address = address.serialize();
this.messageId = messageId;
this.timestamp = System.currentTimeMillis();
this.timestamp = timestamp;
}
@Override
public void onAdded() {}
@NonNull
@Override
protected Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putString(KEY_ADDRESS, address)
.putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_TIMESTAMP, timestamp)
.build();
public @NonNull Data serialize() {
return new Data.Builder().putString(KEY_ADDRESS, address)
.putLong(KEY_MESSAGE_ID, messageId)
.putLong(KEY_TIMESTAMP, timestamp)
.build();
}
@Override
protected void initialize(@NonNull SafeData data) {
this.address = data.getString(KEY_ADDRESS);
this.messageId = data.getLong(KEY_MESSAGE_ID);
this.timestamp = data.getLong(KEY_TIMESTAMP);
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -98,4 +99,13 @@ public class SendDeliveryReceiptJob extends ContextJob implements InjectableType
Log.w(TAG, "Failed to send delivery receipt to: " + address);
}
public static final class Factory implements Job.Factory<SendDeliveryReceiptJob> {
@Override
public @NonNull SendDeliveryReceiptJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new SendDeliveryReceiptJob(parameters,
Address.fromSerialized(data.getString(KEY_ADDRESS)),
data.getLong(KEY_MESSAGE_ID),
data.getLong(KEY_TIMESTAMP));
}
}
}

View File

@@ -1,17 +1,15 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.TextSecureExpiredException;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobLogger;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MediaStream;
@@ -24,19 +22,13 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import androidx.work.WorkerParameters;
public abstract class SendJob extends ContextJob {
public abstract class SendJob extends BaseJob {
@SuppressWarnings("unused")
private final static String TAG = SendJob.class.getSimpleName();
public SendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public SendJob(Context context, JobParameters parameters) {
super(context, parameters);
public SendJob(Job.Parameters parameters) {
super(parameters);
}
@Override
@@ -93,7 +85,7 @@ public abstract class SendJob extends ContextJob {
}
protected void log(@NonNull String tag, @NonNull String message) {
Log.i(tag, "[" + getId().toString() + "] " + message + logSuffix());
Log.i(tag, JobLogger.format(this, message));
}
protected void warn(@NonNull String tag, @NonNull String message) {
@@ -105,6 +97,6 @@ public abstract class SendJob extends ContextJob {
}
protected void warn(@NonNull String tag, @NonNull String message, @Nullable Throwable t) {
Log.w(tag, "[" + getId().toString() + "] " + message + logSuffix(), t);
Log.w(tag, JobLogger.format(this, message), t);
}
}

View File

@@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -21,15 +21,13 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class SendReadReceiptJob extends BaseJob implements InjectableType {
public class SendReadReceiptJob extends ContextJob implements InjectableType {
private static final long serialVersionUID = 1L;
public static final String KEY = "SendReadReceiptJob";
private static final String TAG = SendReadReceiptJob.class.getSimpleName();
@@ -37,49 +35,51 @@ public class SendReadReceiptJob extends ContextJob implements InjectableType {
private static final String KEY_MESSAGE_IDS = "message_ids";
private static final String KEY_TIMESTAMP = "timestamp";
@Inject transient SignalServiceMessageSender messageSender;
@Inject SignalServiceMessageSender messageSender;
private String address;
private List<Long> messageIds;
private long timestamp;
public SendReadReceiptJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public SendReadReceiptJob(Address address, List<Long> messageIds) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
address,
messageIds,
System.currentTimeMillis());
}
public SendReadReceiptJob(Context context, Address address, List<Long> messageIds) {
super(context, JobParameters.newBuilder()
.withNetworkRequirement()
.create());
private SendReadReceiptJob(@NonNull Job.Parameters parameters,
@NonNull Address address,
@NonNull List<Long> messageIds,
long timestamp)
{
super(parameters);
this.address = address.serialize();
this.messageIds = messageIds;
this.timestamp = System.currentTimeMillis();
this.timestamp = timestamp;
}
@Override
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) {
public @NonNull Data serialize() {
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();
return new Data.Builder().putString(KEY_ADDRESS, address)
.putLongArray(KEY_MESSAGE_IDS, ids)
.putLong(KEY_TIMESTAMP, timestamp)
.build();
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -104,4 +104,20 @@ public class SendReadReceiptJob extends ContextJob implements InjectableType {
public void onCanceled() {
Log.w(TAG, "Failed to send read receipts to: " + address);
}
public static final class Factory implements Job.Factory<SendReadReceiptJob> {
@Override
public @NonNull SendReadReceiptJob create(@NonNull Parameters parameters, @NonNull Data data) {
Address address = Address.fromSerialized(data.getString(KEY_ADDRESS));
long timestamp = data.getLong(KEY_TIMESTAMP);
long[] ids = data.getLongArray(KEY_MESSAGE_IDS);
List<Long> messageIds = new ArrayList<>(ids.length);
for (long id : ids) {
messageIds.add(id);
}
return new SendReadReceiptJob(parameters, address, messageIds, timestamp);
}
}
}

View File

@@ -1,13 +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.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -15,10 +15,9 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.net.InetAddress;
import java.net.UnknownHostException;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class ServiceOutageDetectionJob extends BaseJob {
public class ServiceOutageDetectionJob extends ContextJob {
public static final String KEY = "ServiceOutageDetectionJob";
private static final String TAG = ServiceOutageDetectionJob.class.getSimpleName();
@@ -26,26 +25,27 @@ 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(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public ServiceOutageDetectionJob() {
this(new Job.Parameters.Builder()
.setQueue("ServiceOutageDetectionJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(5)
.setMaxInstances(1)
.build());
}
public ServiceOutageDetectionJob(Context context) {
super(context, new JobParameters.Builder()
.withGroupId(ServiceOutageDetectionJob.class.getSimpleName())
.withDuplicatesIgnored(true)
.withNetworkRequirement()
.withRetryCount(5)
.create());
private ServiceOutageDetectionJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -92,4 +92,11 @@ public class ServiceOutageDetectionJob extends ContextJob {
TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis());
EventBus.getDefault().post(new ReminderUpdateEvent());
}
public static final class Factory implements Job.Factory<ServiceOutageDetectionJob> {
@Override
public @NonNull ServiceOutageDetectionJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new ServiceOutageDetectionJob(parameters);
}
}
}

View File

@@ -1,17 +1,17 @@
package org.thoughtcrime.securesms.jobs;
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
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.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
@@ -23,12 +23,9 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class SmsReceiveJob extends BaseJob {
public class SmsReceiveJob extends ContextJob {
private static final long serialVersionUID = 1L;
public static final String KEY = "SmsReceiveJob";
private static final String TAG = SmsReceiveJob.class.getSimpleName();
@@ -39,44 +36,37 @@ public class SmsReceiveJob extends ContextJob {
private int subscriptionId;
public SmsReceiveJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public SmsReceiveJob(@Nullable Object[] pdus, int subscriptionId) {
this(new Job.Parameters.Builder()
.addConstraint(SqlCipherMigrationConstraint.KEY)
.setMaxAttempts(25)
.build(),
pdus,
subscriptionId);
}
public SmsReceiveJob(@NonNull Context context, @Nullable Object[] pdus, int subscriptionId) {
super(context, JobParameters.newBuilder()
.withSqlCipherRequirement()
.create());
private SmsReceiveJob(@NonNull Job.Parameters parameters, @Nullable Object[] pdus, int subscriptionId) {
super(parameters);
this.pdus = pdus;
this.subscriptionId = subscriptionId;
}
@Override
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) {
public @NonNull Data serialize() {
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();
return new Data.Builder().putStringArray(KEY_PDUS, encoded)
.putInt(KEY_SUBSCRIPTION_ID, subscriptionId)
.build();
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -155,6 +145,24 @@ public class SmsReceiveJob extends ContextJob {
}
private class MigrationPendingException extends Exception {
}
public static final class Factory implements Job.Factory<SmsReceiveJob> {
@Override
public @NonNull SmsReceiveJob create(@NonNull Parameters parameters, @NonNull Data data) {
try {
int subscriptionId = data.getInt(KEY_SUBSCRIPTION_ID);
String[] encoded = data.getStringArray(KEY_PDUS);
Object[] pdus = new Object[encoded.length];
for (int i = 0; i < encoded.length; i++) {
pdus[i] = Base64.decode(encoded[i]);
}
return new SmsReceiveJob(parameters, pdus, subscriptionId);
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
}

View File

@@ -9,12 +9,11 @@ import android.support.annotation.NonNull;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobs.requirements.NetworkOrServiceRequirement;
import org.thoughtcrime.securesms.jobs.requirements.ServiceRequirement;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SmsDatabase;
@@ -22,20 +21,16 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.NumberUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import java.util.ArrayList;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class SmsSendJob extends SendJob {
private static final long serialVersionUID = -5118520036244759718L;
public static final String KEY = "SmsSendJob";
private static final String TAG = SmsSendJob.class.getSimpleName();
private static final int MAX_ATTEMPTS = 15;
private static final String KEY_MESSAGE_ID = "message_id";
@@ -44,44 +39,35 @@ public class SmsSendJob extends SendJob {
private long messageId;
private int runAttempt;
public SmsSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
}
public SmsSendJob(Context context, long messageId, String name) {
this(context, messageId, name, 0);
}
public SmsSendJob(Context context, long messageId, String name, int runAttempt) {
super(context, constructParameters(name));
this(constructParameters(context, name), messageId, runAttempt);
}
private SmsSendJob(@NonNull Job.Parameters parameters, long messageId, int runAttempt) {
super(parameters);
this.messageId = messageId;
this.runAttempt = runAttempt;
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
runAttempt = data.getInt(KEY_RUN_ATTEMPT);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putInt(KEY_RUN_ATTEMPT, runAttempt)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
.putInt(KEY_RUN_ATTEMPT, runAttempt)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void onAdded() {
}
@Override
public void onSend() throws NoSuchMessageException, RequirementNotMetException, TooManyRetriesException {
if (!requirementsMet()) {
warn(TAG, "No service. Retrying.");
throw new RequirementNotMetException();
}
public void onSend() throws NoSuchMessageException, TooManyRetriesException {
if (runAttempt >= MAX_ATTEMPTS) {
warn(TAG, "Hit the retry limit. Failing.");
throw new TooManyRetriesException();
@@ -124,14 +110,6 @@ public class SmsSendJob extends SendJob {
}
}
private boolean requirementsMet() {
if (TextSecurePreferences.isWifiSmsEnabled(context)) {
return new NetworkOrServiceRequirement(context).isPresent();
} else {
return new ServiceRequirement(context).isPresent();
}
}
private void deliver(SmsMessageRecord message)
throws UndeliverableMessageException
{
@@ -223,7 +201,7 @@ public class SmsSendJob extends SendJob {
pending.putExtra("type", type);
pending.putExtra("message_id", messageId);
pending.putExtra("run_attempt", Math.max(runAttempt, getRunAttemptCount()));
pending.putExtra("run_attempt", Math.max(runAttempt, getRunAttempt()));
pending.putExtra("upgraded", upgraded);
pending.putExtra("push", push);
@@ -248,15 +226,22 @@ public class SmsSendJob extends SendJob {
}
}
private static JobParameters constructParameters(String name) {
JobParameters.Builder builder = JobParameters.newBuilder()
.withRetryCount(MAX_ATTEMPTS)
.withGroupId(name);
return builder.create();
private static Job.Parameters constructParameters(@NonNull Context context, String name) {
String constraint = TextSecurePreferences.isWifiSmsEnabled(context) ? NetworkOrCellServiceConstraint.KEY
: CellServiceConstraint.KEY;
return new Job.Parameters.Builder()
.setMaxAttempts(MAX_ATTEMPTS)
.setQueue(name)
.addConstraint(constraint)
.build();
}
private static class TooManyRetriesException extends Exception { }
private static class RequirementNotMetException extends Exception { }
public static class Factory implements Job.Factory<SmsSendJob> {
@Override
public @NonNull SmsSendJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
return new SmsSendJob(parameters, data.getLong(KEY_MESSAGE_ID), data.getInt(KEY_RUN_ATTEMPT));
}
}
}

View File

@@ -1,30 +1,26 @@
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.crypto.MasterSecret;
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.jobmanager.JobParameters;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.service.SmsDeliveryListener;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class SmsSentJob extends BaseJob {
public class SmsSentJob extends ContextJob {
public static final String KEY = "SmsSentJob";
private static final long serialVersionUID = -2624694558755317560L;
private static final String TAG = SmsSentJob.class.getSimpleName();
private static final String TAG = SmsSentJob.class.getSimpleName();
private static final String KEY_MESSAGE_ID = "message_id";
private static final String KEY_ACTION = "action";
@@ -36,13 +32,16 @@ public class SmsSentJob extends ContextJob {
private int result;
private int runAttempt;
public SmsSentJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public SmsSentJob(long messageId, String action, int result, int runAttempt) {
this(new Job.Parameters.Builder().build(),
messageId,
action,
result,
runAttempt);
}
public SmsSentJob(Context context, long messageId, String action, int result, int runAttempt) {
super(context, JobParameters.newBuilder()
.create());
private SmsSentJob(@NonNull Job.Parameters parameters, long messageId, String action, int result, int runAttempt) {
super(parameters);
this.messageId = messageId;
this.action = action;
@@ -51,20 +50,17 @@ public class SmsSentJob extends ContextJob {
}
@Override
protected void initialize(@NonNull SafeData data) {
messageId = data.getLong(KEY_MESSAGE_ID);
action = data.getString(KEY_ACTION);
result = data.getInt(KEY_RESULT);
runAttempt = data.getInt(KEY_RUN_ATTEMPT);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_ACTION, action)
.putInt(KEY_RESULT, result)
.putInt(KEY_RUN_ATTEMPT, runAttempt)
.build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_MESSAGE_ID, messageId)
.putString(KEY_ACTION, action)
.putInt(KEY_RESULT, result)
.putInt(KEY_RUN_ATTEMPT, runAttempt)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -88,7 +84,6 @@ public class SmsSentJob extends ContextJob {
@Override
public void onCanceled() {
}
private void handleDeliveredResult(long messageId, int result) {
@@ -108,8 +103,8 @@ public class SmsSentJob extends ContextJob {
case SmsManager.RESULT_ERROR_RADIO_OFF:
Log.w(TAG, "Service connectivity problem, requeuing...");
ApplicationContext.getInstance(context)
.getJobManager()
.add(new SmsSendJob(context, messageId, record.getIndividualRecipient().getAddress().serialize(), runAttempt + 1));
.getJobManager()
.add(new SmsSendJob(context, messageId, record.getIndividualRecipient().getAddress().serialize(), runAttempt + 1));
break;
default:
database.markAsSentFailed(messageId);
@@ -119,4 +114,15 @@ public class SmsSentJob extends ContextJob {
Log.w(TAG, e);
}
}
public static final class Factory implements Job.Factory<SmsSentJob> {
@Override
public @NonNull SmsSentJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new SmsSentJob(parameters,
data.getLong(KEY_MESSAGE_ID),
data.getString(KEY_ACTION),
data.getInt(KEY_RESULT),
data.getInt(KEY_RUN_ATTEMPT));
}
}
}

View File

@@ -16,19 +16,17 @@
*/
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.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class TrimThreadJob extends BaseJob {
public class TrimThreadJob extends ContextJob {
public static final String KEY = "TrimThreadJob";
private static final String TAG = TrimThreadJob.class.getSimpleName();
@@ -36,24 +34,23 @@ public class TrimThreadJob extends ContextJob {
private long threadId;
public TrimThreadJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public TrimThreadJob(long threadId) {
this(new Job.Parameters.Builder().setQueue("TrimThreadJob").build(), threadId);
}
public TrimThreadJob(Context context, long threadId) {
super(context, JobParameters.newBuilder().withGroupId(TrimThreadJob.class.getSimpleName()).create());
this.context = context;
private TrimThreadJob(@NonNull Job.Parameters parameters, long threadId) {
super(parameters);
this.threadId = threadId;
}
@Override
protected void initialize(@NonNull SafeData data) {
threadId = data.getLong(KEY_THREAD_ID);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_THREAD_ID, threadId).build();
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_THREAD_ID, threadId).build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -76,4 +73,11 @@ public class TrimThreadJob extends ContextJob {
public void onCanceled() {
Log.w(TAG, "Canceling trim attempt: " + threadId);
}
public static final class Factory implements Job.Factory<TrimThreadJob> {
@Override
public @NonNull TrimThreadJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new TrimThreadJob(parameters, data.getLong(KEY_THREAD_ID));
}
}
}

View File

@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.support.annotation.NonNull;
import com.annimon.stream.Stream;
@@ -8,8 +7,8 @@ import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobmanager.JobParameters;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.GroupUtil;
@@ -23,13 +22,13 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.WorkerParameters;
public class TypingSendJob extends BaseJob implements InjectableType {
public class TypingSendJob extends ContextJob implements InjectableType {
public static final String KEY = "TypingSendJob";
private static final String TAG = TypingSendJob.class.getSimpleName();
@@ -41,32 +40,34 @@ public class TypingSendJob extends ContextJob implements InjectableType {
@Inject SignalServiceMessageSender messageSender;
public TypingSendJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public TypingSendJob(long threadId, boolean typing) {
this(new Job.Parameters.Builder()
.setQueue("TYPING_" + threadId)
.setMaxAttempts(1)
.setLifespan(TimeUnit.SECONDS.toMillis(5))
.build(),
threadId,
typing);
}
public TypingSendJob(Context context, long threadId, boolean typing) {
super(context, JobParameters.newBuilder()
.withGroupId("TYPING_" + threadId)
.withRetryCount(1)
.create());
private TypingSendJob(@NonNull Job.Parameters parameters, long threadId, boolean typing) {
super(parameters);
this.threadId = threadId;
this.typing = typing;
}
@Override
protected void initialize(@NonNull SafeData data) {
this.threadId = data.getLong(KEY_THREAD_ID);
this.typing = data.getBoolean(KEY_TYPING);
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_THREAD_ID, threadId)
.putBoolean(KEY_TYPING, typing)
.build();
}
@NonNull
@Override
protected Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.putLong(KEY_THREAD_ID, threadId)
.putBoolean(KEY_TYPING, typing)
.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -99,11 +100,18 @@ public class TypingSendJob extends ContextJob implements InjectableType {
}
@Override
protected void onCanceled() {
public void onCanceled() {
}
@Override
protected boolean onShouldRetry(Exception exception) {
return false;
}
public static final class Factory implements Job.Factory<TypingSendJob> {
@Override
public @NonNull TypingSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new TypingSendJob(parameters, data.getLong(KEY_THREAD_ID), data.getBoolean(KEY_TYPING));
}
}
}

View File

@@ -8,17 +8,17 @@ import android.content.pm.PackageInfo;
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.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
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.service.UpdateApkReadyListener;
import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.Hex;
@@ -29,35 +29,36 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import androidx.work.Data;
import androidx.work.WorkerParameters;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class UpdateApkJob extends ContextJob {
public class UpdateApkJob extends BaseJob {
public static final String KEY = "UpdateApkJob";
private static final String TAG = UpdateApkJob.class.getSimpleName();
public UpdateApkJob(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
super(context, workerParameters);
public UpdateApkJob() {
this(new Job.Parameters.Builder()
.setQueue("UpdateApkJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(2)
.build());
}
public UpdateApkJob(Context context) {
super(context, JobParameters.newBuilder()
.withGroupId(UpdateApkJob.class.getSimpleName())
.withNetworkRequirement()
.withRetryCount(2)
.create());
private UpdateApkJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
protected void initialize(@NonNull SafeData data) {
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
protected @NonNull Data serialize(@NonNull Data.Builder dataBuilder) {
return dataBuilder.build();
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
@@ -260,4 +261,11 @@ public class UpdateApkJob extends ContextJob {
return downloadId;
}
}
public static final class Factory implements Job.Factory<UpdateApkJob> {
@Override
public @NonNull UpdateApkJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new UpdateApkJob(parameters);
}
}
}

View File

@@ -1,27 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
import org.thoughtcrime.securesms.jobmanager.requirements.SimpleRequirement;
import org.thoughtcrime.securesms.service.KeyCachingService;
public class MasterSecretRequirement extends SimpleRequirement implements ContextDependent {
private transient Context context;
public MasterSecretRequirement(Context context) {
this.context = context;
}
@Override
public boolean isPresent() {
return KeyCachingService.getMasterSecret(context) != null;
}
@Override
public void setContext(Context context) {
this.context = context;
}
}

View File

@@ -1,36 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementListener;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementProvider;
import org.thoughtcrime.securesms.service.KeyCachingService;
public class MasterSecretRequirementProvider implements RequirementProvider {
private final BroadcastReceiver newKeyReceiver;
private RequirementListener listener;
public MasterSecretRequirementProvider(Context context) {
this.newKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (listener != null) {
listener.onRequirementStatusChanged();
}
}
};
IntentFilter filter = new IntentFilter(KeyCachingService.NEW_KEY_EVENT);
context.registerReceiver(newKeyReceiver, filter, KeyCachingService.KEY_PERMISSION, null);
}
@Override
public void setListener(RequirementListener listener) {
this.listener = listener;
}
}

View File

@@ -1,30 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
import org.thoughtcrime.securesms.jobmanager.requirements.SimpleRequirement;
public class NetworkOrServiceRequirement extends SimpleRequirement implements ContextDependent {
private transient Context context;
public NetworkOrServiceRequirement(Context context) {
this.context = context;
}
@Override
public void setContext(Context context) {
this.context = context;
}
@Override
public boolean isPresent() {
NetworkRequirement networkRequirement = new NetworkRequirement(context);
ServiceRequirement serviceRequirement = new ServiceRequirement(context);
return networkRequirement.isPresent() || serviceRequirement.isPresent();
}
}

View File

@@ -1,30 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
import org.thoughtcrime.securesms.jobmanager.requirements.SimpleRequirement;
import org.thoughtcrime.securesms.sms.TelephonyServiceState;
public class ServiceRequirement extends SimpleRequirement implements ContextDependent {
private static final String TAG = ServiceRequirement.class.getSimpleName();
private transient Context context;
public ServiceRequirement(Context context) {
this.context = context;
}
@Override
public void setContext(Context context) {
this.context = context;
}
@Override
public boolean isPresent() {
TelephonyServiceState telephonyServiceState = new TelephonyServiceState();
return telephonyServiceState.isConnected(context);
}
}

View File

@@ -1,56 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementListener;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementProvider;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServiceRequirementProvider implements RequirementProvider {
private final TelephonyManager telephonyManager;
private final ServiceStateListener serviceStateListener;
private final AtomicBoolean listeningForServiceState;
private RequirementListener requirementListener;
public ServiceRequirementProvider(Context context) {
this.telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
this.serviceStateListener = new ServiceStateListener();
this.listeningForServiceState = new AtomicBoolean(false);
}
@Override
public void setListener(RequirementListener requirementListener) {
this.requirementListener = requirementListener;
}
public void start() {
if (listeningForServiceState.compareAndSet(false, true)) {
this.telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
}
}
private void handleInService() {
if (listeningForServiceState.compareAndSet(true, false)) {
this.telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_NONE);
}
if (requirementListener != null) {
requirementListener.onRequirementStatusChanged();
}
}
private class ServiceStateListener extends PhoneStateListener {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
handleInService();
}
}
}
}

View File

@@ -1,32 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
import org.thoughtcrime.securesms.jobmanager.requirements.Requirement;
import org.thoughtcrime.securesms.jobmanager.requirements.SimpleRequirement;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class SqlCipherMigrationRequirement extends SimpleRequirement implements ContextDependent {
@SuppressWarnings("unused")
private static final String TAG = SqlCipherMigrationRequirement.class.getSimpleName();
private transient Context context;
public SqlCipherMigrationRequirement(@NonNull Context context) {
this.context = context;
}
@Override
public void setContext(Context context) {
this.context = context;
}
@Override
public boolean isPresent() {
return !TextSecurePreferences.getNeedsSqlCipherMigration(context);
}
}

View File

@@ -1,31 +0,0 @@
package org.thoughtcrime.securesms.jobs.requirements;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementListener;
import org.thoughtcrime.securesms.jobmanager.requirements.RequirementProvider;
public class SqlCipherMigrationRequirementProvider implements RequirementProvider {
private RequirementListener listener;
public SqlCipherMigrationRequirementProvider() {
EventBus.getDefault().register(this);
}
@Override
public void setListener(RequirementListener listener) {
this.listener = listener;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(SqlCipherNeedsMigrationEvent event) {
if (listener != null) listener.onRequirementStatusChanged();
}
public static class SqlCipherNeedsMigrationEvent {
}
}