From c904a7aa9707be49ae495be6b48778f0dc35e37a Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 1 Apr 2024 11:19:14 -0400 Subject: [PATCH] Delete LegacyAttachmentUploadJob. It's been over 4 months since it was replaced. That's beyond the 90 day build expiration + 1 day job lifespan. Should be safe to remove. --- .../securesms/jobs/JobManagerFactories.java | 2 +- .../jobs/LegacyAttachmentUploadJob.java | 280 ------------------ 2 files changed, 1 insertion(+), 281 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 4bd168873a..98df8e82bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -137,7 +137,6 @@ public final class JobManagerFactories { put(IndividualSendJob.KEY, new IndividualSendJob.Factory()); put(LeaveGroupV2Job.KEY, new LeaveGroupV2Job.Factory()); put(LeaveGroupV2WorkerJob.KEY, new LeaveGroupV2WorkerJob.Factory()); - put(LegacyAttachmentUploadJob.KEY, new LegacyAttachmentUploadJob.Factory()); put(LinkedDeviceInactiveCheckJob.KEY, new LinkedDeviceInactiveCheckJob.Factory()); put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); put(LocalBackupJobApi29.KEY, new LocalBackupJobApi29.Factory()); @@ -316,6 +315,7 @@ public final class JobManagerFactories { put("SmsSendJob", new FailingJob.Factory()); put("SmsSentJob", new FailingJob.Factory()); put("MmsSendJobV2", new FailingJob.Factory()); + put("AttachmentUploadJobV2", new FailingJob.Factory()); }}; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java deleted file mode 100644 index 4e0a1ec2ad..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2023 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.thoughtcrime.securesms.jobs; - -import android.graphics.Bitmap; -import android.os.Build; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.greenrobot.eventbus.EventBus; -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.attachments.DatabaseAttachment; -import org.thoughtcrime.securesms.attachments.PointerAttachment; -import org.thoughtcrime.securesms.blurhash.BlurHashEncoder; -import org.thoughtcrime.securesms.database.AttachmentTable; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.events.PartProgressEvent; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.JsonJobData; -import org.thoughtcrime.securesms.mms.PartAuthority; -import org.thoughtcrime.securesms.net.NotPushRegisteredException; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.service.NotificationController; -import org.thoughtcrime.securesms.util.MediaUtil; -import org.whispersystems.signalservice.api.SignalServiceMessageSender; -import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; -import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; -import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; -import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException; -import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException; -import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * Uploads an attachment without alteration. - *

- * Queue {@link AttachmentCompressionJob} before to compress. - */ -@Deprecated -public final class LegacyAttachmentUploadJob extends BaseJob { - - public static final String KEY = "AttachmentUploadJobV2"; - - @SuppressWarnings("unused") - private static final String TAG = Log.tag(LegacyAttachmentUploadJob.class); - - private static final long UPLOAD_REUSE_THRESHOLD = TimeUnit.DAYS.toMillis(3); - - private static final String KEY_ROW_ID = "row_id"; - private static final String KEY_FORCE_V2 = "force_v2"; - - /** - * Foreground notification shows while uploading attachments above this. - */ - private static final int FOREGROUND_LIMIT = 10 * 1024 * 1024; - - private final AttachmentId attachmentId; - - private boolean forceV2; - - private LegacyAttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId, boolean forceV2) { - super(parameters); - this.attachmentId = attachmentId; - this.forceV2 = forceV2; - } - - @Override - public @Nullable byte[] serialize() { - return new JsonJobData.Builder().putLong(KEY_ROW_ID, attachmentId.id) - .putBoolean(KEY_FORCE_V2, forceV2) - .serialize(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - protected boolean shouldTrace() { - return true; - } - - @Override - public void onRun() throws Exception { - if (!Recipient.self().isRegistered()) { - throw new NotPushRegisteredException(); - } - - JsonJobData inputData = JsonJobData.deserialize(getInputData()); - - ResumableUploadSpec resumableUploadSpec; - - if (forceV2) { - Log.d(TAG, "Forcing utilization of V2"); - resumableUploadSpec = null; - } else if (inputData.hasString(ResumableUploadSpecJob.KEY_RESUME_SPEC)) { - resumableUploadSpec = ResumableUploadSpec.deserialize(inputData.getString(ResumableUploadSpecJob.KEY_RESUME_SPEC)); - Log.d(TAG, "Using attachments V4 and CDN" + resumableUploadSpec.getCdnNumber()); - } else { - Log.d(TAG, "Using attachments V2"); - resumableUploadSpec = null; - } - - SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); - AttachmentTable database = SignalDatabase.attachments(); - DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId); - - if (databaseAttachment == null) { - throw new InvalidAttachmentException("Cannot find the specified attachment."); - } - - long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp; - if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.remoteLocation)) { - Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping."); - return; - } else if (databaseAttachment.uploadTimestamp > 0) { - Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms"); - } - - Log.i(TAG, "Uploading attachment for message " + databaseAttachment.mmsId + " with ID " + databaseAttachment.attachmentId); - - try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) { - try (SignalServiceAttachmentStream localAttachment = getAttachmentFor(databaseAttachment, notification, resumableUploadSpec)) { - SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment); - Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.fastPreflightId).get(); - - database.finalizeAttachmentAfterUpload(databaseAttachment.attachmentId, attachment, remoteAttachment.getUploadTimestamp()); - } - } catch (NonSuccessfulResumableUploadResponseCodeException e) { - if (e.getCode() == 400) { - Log.w(TAG, "Failed to upload due to a 400 when getting resumable upload information. Downgrading to attachments v2", e); - forceV2 = true; - } - } - } - - private @Nullable NotificationController getNotificationForAttachment(@NonNull Attachment attachment) { - if (attachment.size >= FOREGROUND_LIMIT) { - try { - return ForegroundServiceUtil.startGenericTaskWhenCapable(context, context.getString(R.string.AttachmentUploadJob_uploading_media)); - } catch (UnableToStartException e) { - Log.w(TAG, "Unable to start foreground service", e); - return null; - } - } else { - return null; - } - } - - @Override - public void onFailure() { - if (isCanceled()) { - SignalDatabase.attachments().deleteAttachment(attachmentId); - } - } - - @Override - protected boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof ResumeLocationInvalidException) return false; - - return exception instanceof IOException && !(exception instanceof NotPushRegisteredException); - } - - private @NonNull SignalServiceAttachmentStream getAttachmentFor(Attachment attachment, @Nullable NotificationController notification, @Nullable ResumableUploadSpec resumableUploadSpec) throws InvalidAttachmentException { - if (attachment.getUri() == null || attachment.size == 0) { - throw new InvalidAttachmentException(new IOException("Assertion failed, outgoing attachment has no data!")); - } - - try { - InputStream is = PartAuthority.getAttachmentStream(context, attachment.getUri()); - SignalServiceAttachment.Builder builder = SignalServiceAttachment.newStreamBuilder() - .withStream(is) - .withContentType(attachment.contentType) - .withLength(attachment.size) - .withFileName(attachment.fileName) - .withVoiceNote(attachment.voiceNote) - .withBorderless(attachment.borderless) - .withGif(attachment.videoGif) - .withFaststart(attachment.transformProperties.mp4FastStart) - .withWidth(attachment.width) - .withHeight(attachment.height) - .withUploadTimestamp(System.currentTimeMillis()) - .withCaption(attachment.caption) - .withCancelationSignal(this::isCanceled) - .withResumableUploadSpec(resumableUploadSpec) - .withListener(new SignalServiceAttachment.ProgressListener() { - @Override - public void onAttachmentProgress(long total, long progress) { - EventBus.getDefault().postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress)); - if (notification != null) { - notification.setProgress(total, progress); - } - } - - @Override - public boolean shouldCancel() { - return isCanceled(); - } - }); - if (MediaUtil.isImageType(attachment.contentType)) { - return builder.withBlurHash(getImageBlurHash(attachment)).build(); - } else if (MediaUtil.isVideoType(attachment.contentType)) { - return builder.withBlurHash(getVideoBlurHash(attachment)).build(); - } else { - return builder.build(); - } - } catch (IOException ioe) { - throw new InvalidAttachmentException(ioe); - } - } - - private @Nullable String getImageBlurHash(@NonNull Attachment attachment) throws IOException { - if (attachment.blurHash != null) return attachment.blurHash.getHash(); - if (attachment.getUri() == null) return null; - - try (InputStream inputStream = PartAuthority.getAttachmentStream(context, attachment.getUri())) { - return BlurHashEncoder.encode(inputStream); - } - } - - private @Nullable String getVideoBlurHash(@NonNull Attachment attachment) throws IOException { - if (attachment.blurHash != null) { - return attachment.blurHash.getHash(); - } - - if (Build.VERSION.SDK_INT < 23) { - Log.w(TAG, "Video thumbnails not supported..."); - return null; - } - - Bitmap bitmap = MediaUtil.getVideoThumbnail(context, Objects.requireNonNull(attachment.getUri()), 1000); - - if (bitmap != null) { - Bitmap thumb = Bitmap.createScaledBitmap(bitmap, 100, 100, false); - bitmap.recycle(); - - Log.i(TAG, "Generated video thumbnail..."); - String hash = BlurHashEncoder.encode(thumb); - thumb.recycle(); - - return hash; - } else { - return null; - } - } - - private class InvalidAttachmentException extends Exception { - InvalidAttachmentException(String message) { - super(message); - } - - InvalidAttachmentException(Exception e) { - super(e); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull LegacyAttachmentUploadJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { - JsonJobData data = JsonJobData.deserialize(serializedData); - - return new LegacyAttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false)); - } - } -}