Remove WorkManager migration that is no longer necessary.

We migrated away from WorkManager over 2 years ago. We needed it at the
time because we wanted to migrate jobs that were scheduled on
WorkManager into the new system. However, at this point, the user's
client would have been expired for 2 years at the point of upgrade, and
there wouldn't be any jobs that need migrating.
fork-5.53.8
Greyson Parrelli 2021-11-04 09:58:13 -04:00
rodzic f52364f75c
commit 049ba6a706
5 zmienionych plików z 0 dodań i 430 usunięć

Wyświetl plik

@ -14,7 +14,6 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage;
import org.thoughtcrime.securesms.jobmanager.workmanager.WorkManagerMigrator;
import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
@ -73,11 +72,6 @@ public class JobManager implements ConstraintObserver.Notifier {
executor.execute(() -> {
synchronized (this) {
if (WorkManagerMigrator.needsMigration(application)) {
Log.i(TAG, "Detected an old WorkManager database. Migrating.");
WorkManagerMigrator.migrate(application, configuration.getJobStorage(), configuration.getDataSerializer());
}
JobStorage jobStorage = configuration.getJobStorage();
jobStorage.init();

Wyświetl plik

@ -1,169 +0,0 @@
package org.thoughtcrime.securesms.jobmanager.workmanager;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.jobmanager.Data;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;
/**
* Takes a persisted data blob stored by WorkManager and converts it to our {@link Data} class.
*/
final class DataMigrator {
private static final String TAG = Log.tag(DataMigrator.class);
static final Data convert(@NonNull byte[] workManagerData) {
Map<String, Object> values = parseWorkManagerDataMap(workManagerData);
Data.Builder builder = new Data.Builder();
for (Map.Entry<String, Object> entry : values.entrySet()) {
Object value = entry.getValue();
if (value == null) {
builder.putString(entry.getKey(), null);
} else {
Class type = value.getClass();
if (type == String.class) {
builder.putString(entry.getKey(), (String) value);
} else if (type == String[].class) {
builder.putStringArray(entry.getKey(), (String[]) value);
} else if (type == Integer.class || type == int.class) {
builder.putInt(entry.getKey(), (int) value);
} else if (type == Integer[].class || type == int[].class) {
builder.putIntArray(entry.getKey(), convertToIntArray(value, type));
} else if (type == Long.class || type == long.class) {
builder.putLong(entry.getKey(), (long) value);
} else if (type == Long[].class || type == long[].class) {
builder.putLongArray(entry.getKey(), convertToLongArray(value, type));
} else if (type == Float.class || type == float.class) {
builder.putFloat(entry.getKey(), (float) value);
} else if (type == Float[].class || type == float[].class) {
builder.putFloatArray(entry.getKey(), convertToFloatArray(value, type));
} else if (type == Double.class || type == double.class) {
builder.putDouble(entry.getKey(), (double) value);
} else if (type == Double[].class || type == double[].class) {
builder.putDoubleArray(entry.getKey(), convertToDoubleArray(value, type));
} else if (type == Boolean.class || type == boolean.class) {
builder.putBoolean(entry.getKey(), (boolean) value);
} else if (type == Boolean[].class || type == boolean[].class) {
builder.putBooleanArray(entry.getKey(), convertToBooleanArray(value, type));
} else {
Log.w(TAG, "Encountered unexpected type '" + type + "'. Skipping.");
}
}
}
return builder.build();
}
private static @NonNull Map<String, Object> parseWorkManagerDataMap(@NonNull byte[] bytes) throws IllegalStateException {
Map<String, Object> map = new HashMap<>();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(inputStream);
for (int i = objectInputStream.readInt(); i > 0; i--) {
map.put(objectInputStream.readUTF(), objectInputStream.readObject());
}
} catch (IOException | ClassNotFoundException e) {
Log.w(TAG, "Failed to read WorkManager data.", e);
} finally {
try {
inputStream.close();
if (objectInputStream != null) {
objectInputStream.close();
}
} catch (IOException e) {
Log.e(TAG, "Failed to close streams after reading WorkManager data.", e);
}
}
return map;
}
private static int[] convertToIntArray(Object value, Class type) {
if (type == int[].class) {
return (int[]) value;
}
Integer[] casted = (Integer[]) value;
int[] output = new int[casted.length];
for (int i = 0; i < casted.length; i++) {
output[i] = casted[i];
}
return output;
}
private static long[] convertToLongArray(Object value, Class type) {
if (type == long[].class) {
return (long[]) value;
}
Long[] casted = (Long[]) value;
long[] output = new long[casted.length];
for (int i = 0; i < casted.length; i++) {
output[i] = casted[i];
}
return output;
}
private static float[] convertToFloatArray(Object value, Class type) {
if (type == float[].class) {
return (float[]) value;
}
Float[] casted = (Float[]) value;
float[] output = new float[casted.length];
for (int i = 0; i < casted.length; i++) {
output[i] = casted[i];
}
return output;
}
private static double[] convertToDoubleArray(Object value, Class type) {
if (type == double[].class) {
return (double[]) value;
}
Double[] casted = (Double[]) value;
double[] output = new double[casted.length];
for (int i = 0; i < casted.length; i++) {
output[i] = casted[i];
}
return output;
}
private static boolean[] convertToBooleanArray(Object value, Class type) {
if (type == boolean[].class) {
return (boolean[]) value;
}
Boolean[] casted = (Boolean[]) value;
boolean[] output = new boolean[casted.length];
for (int i = 0; i < casted.length; i++) {
output[i] = casted[i];
}
return output;
}
}

Wyświetl plik

@ -1,102 +0,0 @@
package org.thoughtcrime.securesms.jobmanager.workmanager;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
final class WorkManagerDatabase extends SQLiteOpenHelper {
private static final String TAG = Log.tag(WorkManagerDatabase.class);
static final String DB_NAME = "androidx.work.workdb";
WorkManagerDatabase(@NonNull Context context) {
super(context, DB_NAME, null, 5);
}
@Override
public void onCreate(SQLiteDatabase db) {
throw new UnsupportedOperationException("We should never be creating this database, only migrating an existing one!");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// There's a chance that a user who hasn't upgraded in > 6 months could hit this onUpgrade path,
// but we don't use any of the columns that were added in any migrations they could hit, so we
// can ignore this.
Log.w(TAG, "Hit onUpgrade path from " + oldVersion + " to " + newVersion);
}
@NonNull List<FullSpec> getAllJobs(@NonNull Data.Serializer dataSerializer) {
SQLiteDatabase db = getReadableDatabase();
String[] columns = new String[] { "id", "worker_class_name", "input", "required_network_type"};
List<FullSpec> fullSpecs = new LinkedList<>();
try (Cursor cursor = db.query("WorkSpec", columns, null, null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
String factoryName = WorkManagerFactoryMappings.getFactoryKey(cursor.getString(cursor.getColumnIndexOrThrow("worker_class_name")));
if (factoryName != null) {
String id = cursor.getString(cursor.getColumnIndexOrThrow("id"));
byte[] data = cursor.getBlob(cursor.getColumnIndexOrThrow("input"));
List<ConstraintSpec> constraints = new LinkedList<>();
JobSpec jobSpec = new JobSpec(id,
factoryName,
getQueueKey(id),
System.currentTimeMillis(),
0,
0,
Job.Parameters.UNLIMITED,
TimeUnit.DAYS.toMillis(1),
dataSerializer.serialize(DataMigrator.convert(data)),
null,
false,
false);
if (cursor.getInt(cursor.getColumnIndexOrThrow("required_network_type")) != 0) {
constraints.add(new ConstraintSpec(id, NetworkConstraint.KEY, false));
}
fullSpecs.add(new FullSpec(jobSpec, constraints, Collections.emptyList()));
} else {
Log.w(TAG, "Failed to find a matching factory for worker class: " + factoryName);
}
}
}
return fullSpecs;
}
private @Nullable String getQueueKey(@NonNull String jobId) {
String query = "work_spec_id = ?";
String[] args = new String[] { jobId };
try (Cursor cursor = getReadableDatabase().query("WorkName", null, query, args, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
return cursor.getString(cursor.getColumnIndexOrThrow("name"));
}
}
return null;
}
}

Wyświetl plik

@ -1,107 +0,0 @@
package org.thoughtcrime.securesms.jobmanager.workmanager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob;
import org.thoughtcrime.securesms.jobs.AvatarGroupsV1DownloadJob;
import org.thoughtcrime.securesms.jobs.CleanPreKeysJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.FailingJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.LocalBackupJob;
import org.thoughtcrime.securesms.jobs.LocalBackupJobApi29;
import org.thoughtcrime.securesms.jobs.MmsDownloadJob;
import org.thoughtcrime.securesms.jobs.MmsReceiveJob;
import org.thoughtcrime.securesms.jobs.MmsSendJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceVerifiedUpdateJob;
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob;
import org.thoughtcrime.securesms.jobs.PushMediaSendJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.PushTextSendJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob;
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob;
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
import org.thoughtcrime.securesms.jobs.RotateCertificateJob;
import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob;
import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob;
import org.thoughtcrime.securesms.jobs.SendReadReceiptJob;
import org.thoughtcrime.securesms.jobs.SendViewedReceiptJob;
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
import org.thoughtcrime.securesms.jobs.SmsReceiveJob;
import org.thoughtcrime.securesms.jobs.SmsSendJob;
import org.thoughtcrime.securesms.jobs.SmsSentJob;
import org.thoughtcrime.securesms.jobs.TrimThreadJob;
import org.thoughtcrime.securesms.jobs.TypingSendJob;
import org.thoughtcrime.securesms.jobs.UpdateApkJob;
import java.util.HashMap;
import java.util.Map;
public class WorkManagerFactoryMappings {
private static final Map<String, String> FACTORY_MAP = new HashMap<String, String>() {{
put("AttachmentDownloadJob", AttachmentDownloadJob.KEY);
put("AttachmentUploadJob", AttachmentUploadJob.KEY);
put("AvatarDownloadJob", AvatarGroupsV1DownloadJob.KEY);
put("CleanPreKeysJob", CleanPreKeysJob.KEY);
put("CreateSignedPreKeyJob", CreateSignedPreKeyJob.KEY);
put("DirectoryRefreshJob", DirectoryRefreshJob.KEY);
put("FcmRefreshJob", FcmRefreshJob.KEY);
put("LocalBackupJob", LocalBackupJob.KEY);
put("LocalBackupJobApi29", LocalBackupJobApi29.KEY);
put("MmsDownloadJob", MmsDownloadJob.KEY);
put("MmsReceiveJob", MmsReceiveJob.KEY);
put("MmsSendJob", MmsSendJob.KEY);
put("MultiDeviceBlockedUpdateJob", MultiDeviceBlockedUpdateJob.KEY);
put("MultiDeviceConfigurationUpdateJob", MultiDeviceConfigurationUpdateJob.KEY);
put("MultiDeviceContactUpdateJob", MultiDeviceContactUpdateJob.KEY);
put("MultiDeviceGroupUpdateJob", MultiDeviceGroupUpdateJob.KEY);
put("MultiDeviceProfileKeyUpdateJob", MultiDeviceProfileKeyUpdateJob.KEY);
put("MultiDeviceReadUpdateJob", MultiDeviceReadUpdateJob.KEY);
put("MultiDeviceVerifiedUpdateJob", MultiDeviceVerifiedUpdateJob.KEY);
put("PushContentReceiveJob", FailingJob.KEY);
put("PushDecryptJob", PushDecryptMessageJob.KEY);
put("PushGroupSendJob", PushGroupSendJob.KEY);
put("PushGroupUpdateJob", PushGroupUpdateJob.KEY);
put("PushMediaSendJob", PushMediaSendJob.KEY);
put("PushNotificationReceiveJob", PushNotificationReceiveJob.KEY);
put("PushTextSendJob", PushTextSendJob.KEY);
put("RefreshAttributesJob", RefreshAttributesJob.KEY);
put("RefreshPreKeysJob", RefreshPreKeysJob.KEY);
put("RefreshUnidentifiedDeliveryAbilityJob", FailingJob.KEY);
put("RequestGroupInfoJob", RequestGroupInfoJob.KEY);
put("RetrieveProfileAvatarJob", RetrieveProfileAvatarJob.KEY);
put("RetrieveProfileJob", RetrieveProfileJob.KEY);
put("RotateCertificateJob", RotateCertificateJob.KEY);
put("RotateProfileKeyJob", RotateProfileKeyJob.KEY);
put("RotateSignedPreKeyJob", RotateSignedPreKeyJob.KEY);
put("SendDeliveryReceiptJob", SendDeliveryReceiptJob.KEY);
put("SendReadReceiptJob", SendReadReceiptJob.KEY);
put("SendViewedReceiptJob", SendViewedReceiptJob.KEY);
put("ServiceOutageDetectionJob", ServiceOutageDetectionJob.KEY);
put("SmsReceiveJob", SmsReceiveJob.KEY);
put("SmsSendJob", SmsSendJob.KEY);
put("SmsSentJob", SmsSentJob.KEY);
put("TrimThreadJob", TrimThreadJob.KEY);
put("TypingSendJob", TypingSendJob.KEY);
put("UpdateApkJob", UpdateApkJob.KEY);
}};
public static @Nullable String getFactoryKey(@NonNull String workManagerClass) {
return FACTORY_MAP.get(workManagerClass);
}
}

Wyświetl plik

@ -1,46 +0,0 @@
package org.thoughtcrime.securesms.jobmanager.workmanager;
import android.annotation.SuppressLint;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec;
import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage;
import java.util.List;
public class WorkManagerMigrator {
private static final String TAG = Log.tag(WorkManagerMigrator.class);
@SuppressLint("DefaultLocale")
@WorkerThread
public static synchronized void migrate(@NonNull Context context,
@NonNull JobStorage jobStorage,
@NonNull Data.Serializer dataSerializer)
{
long startTime = System.currentTimeMillis();
Log.i(TAG, "Beginning WorkManager migration.");
WorkManagerDatabase database = new WorkManagerDatabase(context);
List<FullSpec> fullSpecs = database.getAllJobs(dataSerializer);
for (FullSpec fullSpec : fullSpecs) {
Log.i(TAG, String.format("Migrating job with key '%s' and %d constraint(s).", fullSpec.getJobSpec().getFactoryKey(), fullSpec.getConstraintSpecs().size()));
}
jobStorage.insertJobs(fullSpecs);
context.deleteDatabase(WorkManagerDatabase.DB_NAME);
Log.i(TAG, String.format("WorkManager migration finished. Migrated %d job(s) in %d ms.", fullSpecs.size(), System.currentTimeMillis() - startTime));
}
@WorkerThread
public static synchronized boolean needsMigration(@NonNull Context context) {
return context.getDatabasePath(WorkManagerDatabase.DB_NAME).exists();
}
}