That fuck shit the fascists are using
1package org.tm.archive.migrations;
2
3import android.content.Context;
4
5import androidx.annotation.NonNull;
6import androidx.annotation.Nullable;
7import androidx.preference.PreferenceManager;
8
9import com.bumptech.glide.Glide;
10
11import org.signal.core.util.logging.Log;
12import org.tm.archive.attachments.DatabaseAttachment;
13import org.tm.archive.crypto.MasterSecret;
14import org.tm.archive.database.AttachmentTable;
15import org.tm.archive.database.MessageTable;
16import org.tm.archive.database.MessageTable.MmsReader;
17import org.tm.archive.database.SignalDatabase;
18import org.tm.archive.database.model.MessageRecord;
19import org.tm.archive.dependencies.ApplicationDependencies;
20import org.tm.archive.jobmanager.Job;
21import org.tm.archive.jobs.AttachmentDownloadJob;
22import org.tm.archive.jobs.DirectoryRefreshJob;
23import org.tm.archive.jobs.PreKeysSyncJob;
24import org.tm.archive.jobs.RefreshAttributesJob;
25import org.tm.archive.keyvalue.SignalStore;
26import org.tm.archive.service.KeyCachingService;
27import org.tm.archive.transport.RetryLaterException;
28import org.tm.archive.util.FileUtils;
29import org.tm.archive.util.TextSecurePreferences;
30import org.tm.archive.util.VersionTracker;
31
32import java.io.File;
33import java.util.List;
34
35/**
36 * Represents all of the migrations that used to take place in {@link ApplicationMigrationActivity}
37 * (previously known as DatabaseUpgradeActivity). This job should *never* have new versions or
38 * migrations added to it. Instead, create a new {@link MigrationJob} and place it in
39 * {@link ApplicationMigrations}.
40 */
41public class LegacyMigrationJob extends MigrationJob {
42
43 public static final String KEY = "LegacyMigrationJob";
44
45 private static final String TAG = Log.tag(LegacyMigrationJob.class);
46
47 public static final int NO_MORE_KEY_EXCHANGE_PREFIX_VERSION = 46;
48 public static final int MMS_BODY_VERSION = 46;
49 public static final int TOFU_IDENTITIES_VERSION = 50;
50 private static final int CURVE25519_VERSION = 63;
51 public static final int ASYMMETRIC_MASTER_SECRET_FIX_VERSION = 73;
52 private static final int NO_V1_VERSION = 83;
53 private static final int SIGNED_PREKEY_VERSION = 83;
54 private static final int NO_DECRYPT_QUEUE_VERSION = 113;
55 private static final int PUSH_DECRYPT_SERIAL_ID_VERSION = 131;
56 private static final int MIGRATE_SESSION_PLAINTEXT = 136;
57 private static final int CONTACTS_ACCOUNT_VERSION = 136;
58 private static final int MEDIA_DOWNLOAD_CONTROLS_VERSION = 151;
59 private static final int REDPHONE_SUPPORT_VERSION = 157;
60 private static final int NO_MORE_CANONICAL_DB_VERSION = 276;
61 private static final int PROFILES = 289;
62 private static final int SCREENSHOTS = 300;
63 private static final int PERSISTENT_BLOBS = 317;
64 private static final int INTERNALIZE_CONTACTS = 317;
65 public static final int SQLCIPHER = 334;
66 private static final int SQLCIPHER_COMPLETE = 352;
67 private static final int REMOVE_JOURNAL = 353;
68 private static final int REMOVE_CACHE = 354;
69 private static final int FULL_TEXT_SEARCH = 358;
70 private static final int BAD_IMPORT_CLEANUP = 373;
71 private static final int IMAGE_CACHE_CLEANUP = 406;
72 private static final int WORKMANAGER_MIGRATION = 408;
73 private static final int COLOR_MIGRATION = 412;
74 private static final int UNIDENTIFIED_DELIVERY = 422;
75 private static final int SIGNALING_KEY_DEPRECATION = 447;
76 private static final int CONVERSATION_SEARCH = 455;
77
78
79 public LegacyMigrationJob() {
80 this(new Parameters.Builder().build());
81 }
82
83 private LegacyMigrationJob(@NonNull Parameters parameters) {
84 super(parameters);
85 }
86
87 @Override
88 public boolean isUiBlocking() {
89 return true;
90 }
91
92 @Override
93 public @NonNull String getFactoryKey() {
94 return KEY;
95 }
96
97 @Override
98 void performMigration() throws RetryLaterException {
99 Log.i(TAG, "Running background upgrade..");
100 int lastSeenVersion = VersionTracker.getLastSeenVersion(context);
101 MasterSecret masterSecret = KeyCachingService.getMasterSecret(context);
102
103 if (lastSeenVersion < SQLCIPHER && masterSecret != null) {
104 SignalDatabase.onApplicationLevelUpgrade(context, masterSecret, lastSeenVersion, (progress, total) -> {
105 Log.i(TAG, "onApplicationLevelUpgrade: " + progress + "/" + total);
106 });
107 } else if (lastSeenVersion < SQLCIPHER) {
108 throw new RetryLaterException();
109 }
110
111 if (lastSeenVersion < NO_V1_VERSION) {
112 File v1sessions = new File(context.getFilesDir(), "sessions");
113
114 if (v1sessions.exists() && v1sessions.isDirectory()) {
115 File[] contents = v1sessions.listFiles();
116
117 if (contents != null) {
118 for (File session : contents) {
119 session.delete();
120 }
121 }
122
123 v1sessions.delete();
124 }
125 }
126
127 if (lastSeenVersion < SIGNED_PREKEY_VERSION) {
128 PreKeysSyncJob.enqueueIfNeeded();
129 }
130
131// if (lastSeenVersion < NO_DECRYPT_QUEUE_VERSION) {
132// scheduleMessagesInPushDatabase(context);
133// }
134
135// if (lastSeenVersion < PUSH_DECRYPT_SERIAL_ID_VERSION) {
136// scheduleMessagesInPushDatabase(context);
137// }
138
139// if (lastSeenVersion < MIGRATE_SESSION_PLAINTEXT) {
140//// new TextSecureSessionStore(context, masterSecret).migrateSessions();
141//// new TextSecurePreKeyStore(context, masterSecret).migrateRecords();
142//
143// scheduleMessagesInPushDatabase(context);;
144// }
145
146 if (lastSeenVersion < CONTACTS_ACCOUNT_VERSION) {
147 ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(false));
148 }
149
150 if (lastSeenVersion < MEDIA_DOWNLOAD_CONTROLS_VERSION) {
151 schedulePendingIncomingParts(context);
152 }
153
154 if (lastSeenVersion < REDPHONE_SUPPORT_VERSION) {
155 ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());
156 ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(false));
157 }
158
159 if (lastSeenVersion < PROFILES) {
160 ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(false));
161 }
162
163 if (lastSeenVersion < SCREENSHOTS) {
164 boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, true);
165 TextSecurePreferences.setScreenSecurityEnabled(context, screenSecurity);
166 }
167
168 if (lastSeenVersion < PERSISTENT_BLOBS) {
169 File externalDir = context.getExternalFilesDir(null);
170
171 if (externalDir != null && externalDir.isDirectory() && externalDir.exists()) {
172 for (File blob : externalDir.listFiles()) {
173 if (blob.exists() && blob.isFile()) blob.delete();
174 }
175 }
176 }
177
178 if (lastSeenVersion < INTERNALIZE_CONTACTS) {
179 if (SignalStore.account().isRegistered()) {
180 TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
181 }
182 }
183
184// if (lastSeenVersion < SQLCIPHER) {
185// scheduleMessagesInPushDatabase(context);
186// }
187
188 if (lastSeenVersion < SQLCIPHER_COMPLETE) {
189 File file = context.getDatabasePath("messages.db");
190 if (file != null && file.exists()) file.delete();
191 }
192
193 if (lastSeenVersion < REMOVE_JOURNAL) {
194 File file = context.getDatabasePath("messages.db-journal");
195 if (file != null && file.exists()) file.delete();
196 }
197
198 if (lastSeenVersion < REMOVE_CACHE) {
199 FileUtils.deleteDirectoryContents(context.getCacheDir());
200 }
201
202 if (lastSeenVersion < IMAGE_CACHE_CLEANUP) {
203 FileUtils.deleteDirectoryContents(context.getExternalCacheDir());
204 Glide.get(context).clearDiskCache();
205 }
206
207 // This migration became unnecessary after switching away from WorkManager
208// if (lastSeenVersion < WORKMANAGER_MIGRATION) {
209// Log.i(TAG, "Beginning migration of existing jobs to WorkManager");
210//
211// JobManager jobManager = ApplicationContext.getInstance(getApplicationContext()).getJobManager();
212// PersistentStorage storage = new PersistentStorage(getApplicationContext(), "TextSecureJobs", new JavaJobSerializer());
213//
214// for (Job job : storage.getAllUnencrypted()) {
215// jobManager.add(job);
216// Log.i(TAG, "Migrated job with class '" + job.getClass().getSimpleName() + "' to run on new JobManager.");
217// }
218// }
219
220 if (lastSeenVersion < COLOR_MIGRATION) {
221 long startTime = System.currentTimeMillis();
222 //noinspection deprecation
223 SignalDatabase.recipients().updateSystemContactColors();
224 Log.i(TAG, "Color migration took " + (System.currentTimeMillis() - startTime) + " ms");
225 }
226
227 if (lastSeenVersion < UNIDENTIFIED_DELIVERY) {
228 Log.i(TAG, "Scheduling UD attributes refresh.");
229 ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());
230 }
231
232 if (lastSeenVersion < SIGNALING_KEY_DEPRECATION) {
233 Log.i(TAG, "Scheduling a RefreshAttributesJob to remove the signaling key remotely.");
234 ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());
235 }
236 }
237
238 @Override
239 boolean shouldRetry(@NonNull Exception e) {
240 return e instanceof RetryLaterException;
241 }
242
243 private void schedulePendingIncomingParts(Context context) {
244 final AttachmentTable attachmentDb = SignalDatabase.attachments();
245 final MessageTable mmsDb = SignalDatabase.messages();
246 final List<DatabaseAttachment> pendingAttachments = SignalDatabase.attachments().getPendingAttachments();
247
248 Log.i(TAG, pendingAttachments.size() + " pending parts.");
249 for (DatabaseAttachment attachment : pendingAttachments) {
250 final MmsReader reader = MessageTable.mmsReaderFor(mmsDb.getMessageCursor(attachment.mmsId));
251 final MessageRecord record = reader.getNext();
252
253 if (attachment.hasData) {
254 Log.i(TAG, "corrected a pending media part " + attachment.attachmentId + "that already had data.");
255 attachmentDb.setTransferState(attachment.mmsId, attachment.attachmentId, AttachmentTable.TRANSFER_PROGRESS_DONE);
256 } else if (record != null && !record.isOutgoing() && record.isPush()) {
257 Log.i(TAG, "queuing new attachment download job for incoming push part " + attachment.attachmentId + ".");
258 ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(attachment.mmsId, attachment.attachmentId, false));
259 }
260 reader.close();
261 }
262 }
263
264// private static void scheduleMessagesInPushDatabase(@NonNull Context context) {
265// PushTable pushDatabase = SignalDatabase.push();
266// JobManager jobManager = ApplicationDependencies.getJobManager();
267//
268// try (PushTable.Reader pushReader = pushDatabase.readerFor(pushDatabase.getPending())) {
269// SignalServiceEnvelope envelope;
270// while ((envelope = pushReader.getNext()) != null) {
271// jobManager.add(new PushDecryptMessageJob(envelope));
272// }
273// }
274// }
275
276 public interface DatabaseUpgradeListener {
277 void setProgress(int progress, int total);
278 }
279
280 public static final class Factory implements Job.Factory<LegacyMigrationJob> {
281 @Override
282 public @NonNull LegacyMigrationJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) {
283 return new LegacyMigrationJob(parameters);
284 }
285 }
286}