From c6b89055d82fc810e75c29349726937d1fc72cab Mon Sep 17 00:00:00 2001 From: Hocuri Date: Mon, 27 Jan 2025 18:40:44 +0100 Subject: [PATCH] File deduplication, Android part (#3513) --- jni/dc_wrapper.c | 12 ++++++++++ src/main/java/com/b44t/messenger/DcMsg.java | 1 + .../securesms/ConversationActivity.java | 4 ++-- .../securesms/components/MediaView.java | 2 -- .../securesms/connect/DcHelper.java | 7 ++++++ .../securesms/mms/AttachmentManager.java | 4 +--- .../util/SendRelayedMessageUtil.java | 22 +++++++------------ .../securesms/video/recode/VideoRecoder.java | 5 +---- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index 31f57802f..2d83f9f4f 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -1632,6 +1632,18 @@ JNIEXPORT void Java_com_b44t_messenger_DcMsg_setFile(JNIEnv *env, jobject obj, j } +JNIEXPORT void Java_com_b44t_messenger_DcMsg_setFileAndDeduplicate(JNIEnv *env, jobject obj, jstring file, jstring name, jstring filemime) +{ + CHAR_REF(file); + CHAR_REF(name); + CHAR_REF(filemime); + dc_msg_set_file_and_deduplicate(get_dc_msg(env, obj), filePtr, namePtr, filemimePtr); + CHAR_UNREF(filemime); + CHAR_UNREF(name); + CHAR_UNREF(file); +} + + JNIEXPORT void Java_com_b44t_messenger_DcMsg_setDimension(JNIEnv *env, jobject obj, int width, int height) { dc_msg_set_dimension(get_dc_msg(env, obj), width, height); diff --git a/src/main/java/com/b44t/messenger/DcMsg.java b/src/main/java/com/b44t/messenger/DcMsg.java index e41b237a6..12c3e06b3 100644 --- a/src/main/java/com/b44t/messenger/DcMsg.java +++ b/src/main/java/com/b44t/messenger/DcMsg.java @@ -157,6 +157,7 @@ public JSONObject getWebxdcInfo () { public native int getVideochatType (); public native void setText (String text); public native void setFile (String file, String filemime); + public native void setFileAndDeduplicate(String file, String name, String filemime); public native void setDimension (int width, int height); public native void setDuration (int duration); public native void setLocation (float latitude, float longitude); diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index 75bf927ff..32059c47e 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java @@ -1039,7 +1039,7 @@ protected ListenableFuture processComposeControls(final int action, Str msg = new DcMsg(dcContext, DcMsg.DC_MSG_FILE); } String path = attachment.getRealPath(this); - msg.setFile(path, null); + msg.setFileAndDeduplicate(path, attachment.getFileName(), null); } } msg.setText(body); @@ -1329,7 +1329,7 @@ private void sendSticker(@NonNull Uri uri, String contentType) { if (quote.isPresent()) { msg.setQuote(quote.get().getQuotedMsg()); } - msg.setFile(path, null); + msg.setFileAndDeduplicate(path, null, null); dcContext.sendMsg(chatId, msg); } diff --git a/src/main/java/org/thoughtcrime/securesms/components/MediaView.java b/src/main/java/org/thoughtcrime/securesms/components/MediaView.java index 890f1e8a9..bd335218f 100644 --- a/src/main/java/org/thoughtcrime/securesms/components/MediaView.java +++ b/src/main/java/org/thoughtcrime/securesms/components/MediaView.java @@ -3,10 +3,8 @@ import android.content.Context; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import android.util.AttributeSet; import android.view.View; import android.view.Window; diff --git a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java index cf18d2341..5f1b37686 100644 --- a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java +++ b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java @@ -367,6 +367,13 @@ private static String checkMime(String path, String mimeType) { return mimeType; } + /** + * Return the path of a not-yet-existing file in the blobdir with roughly the given filename + * and the given extension. + * In many cases, since we're using setFileAndDeduplicate now, this wouldn't be necessary anymore + * and we could just create a file with a random filename, + * but there are a few usages that still need the current behavior (like `openMaps()`). + */ public static String getBlobdirFile(DcContext dcContext, String filename, String ext) { filename = FileUtils.sanitizeFilename(filename); ext = FileUtils.sanitizeFilename(ext); diff --git a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java index 4101e5e6d..77bd46add 100644 --- a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java +++ b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.database.Cursor; -import android.graphics.PorterDuff; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; @@ -68,7 +67,6 @@ import org.thoughtcrime.securesms.providers.PersistentBlobProvider; import org.thoughtcrime.securesms.scribbles.ScribbleActivity; import org.thoughtcrime.securesms.util.MediaUtil; -import org.thoughtcrime.securesms.util.ThemeUtil; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.guava.Optional; import org.thoughtcrime.securesms.util.views.Stub; @@ -693,7 +691,7 @@ public enum MediaType { DcMsg msg = new DcMsg(dcContext, DcMsg.DC_MSG_WEBXDC); Attachment attachment = new UriAttachment(uri, null, MediaUtil.WEBXDC, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, 0, 0, 0, fileName, null, false); String path = attachment.getRealPath(context); - msg.setFile(path, MediaUtil.WEBXDC); + msg.setFileAndDeduplicate(path, fileName, MediaUtil.WEBXDC); dcContext.setDraft(chatId, msg); return new DocumentSlide(context, msg); } diff --git a/src/main/java/org/thoughtcrime/securesms/util/SendRelayedMessageUtil.java b/src/main/java/org/thoughtcrime/securesms/util/SendRelayedMessageUtil.java index 5877f50db..656f9b001 100644 --- a/src/main/java/org/thoughtcrime/securesms/util/SendRelayedMessageUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/util/SendRelayedMessageUtil.java @@ -105,7 +105,7 @@ public static DcMsg createMessage(Context context, Uri uri, String text) throws } if (uri != null) { - message.setFile(getRealPathFromUri(context, uri), mimeType); + setFileFromUri(context, uri, message, mimeType); } if (text != null) { message.setText(text); @@ -113,11 +113,12 @@ public static DcMsg createMessage(Context context, Uri uri, String text) throws return message; } - private static String getRealPathFromUri(Context context, Uri uri) throws NullPointerException { + private static void setFileFromUri(Context context, Uri uri, DcMsg message, String mimeType) { + String path; DcContext dcContext = DcHelper.getContext(context); + String filename = "cannot-resolve.jpg"; // best guess, this still leads to most images being workable if OS does weird things try { - String filename = "cannot-resolve.jpg"; // best guess, this still leads to most images being workable if OS does weird things if (PartAuthority.isLocalUri(uri)) { filename = uri.getPathSegments().get(PersistentBlobProvider.FILENAME_PATH_SEGMENT); } else if (uri.getScheme().equals("content")) { @@ -135,14 +136,7 @@ private static String getRealPathFromUri(Context context, Uri uri) throws NullPo } } - String ext = ""; - int i = filename.lastIndexOf("."); - if (i >= 0) { - ext = filename.substring(i); - filename = filename.substring(0, i); - } - - String path = DcHelper.getBlobdirFile(dcContext, filename, ext); + path = DcHelper.getBlobdirFile(dcContext, filename, "temp"); // copy content to this file if (path != null) { @@ -150,11 +144,11 @@ private static String getRealPathFromUri(Context context, Uri uri) throws NullPo OutputStream outputStream = new FileOutputStream(path); Util.copy(inputStream, outputStream); } - - return path; } catch (Exception e) { e.printStackTrace(); - return null; + path = null; } + message.setFileAndDeduplicate(path, filename, mimeType); } + } diff --git a/src/main/java/org/thoughtcrime/securesms/video/recode/VideoRecoder.java b/src/main/java/org/thoughtcrime/securesms/video/recode/VideoRecoder.java index b47f0e864..df17d04c9 100644 --- a/src/main/java/org/thoughtcrime/securesms/video/recode/VideoRecoder.java +++ b/src/main/java/org/thoughtcrime/securesms/video/recode/VideoRecoder.java @@ -640,10 +640,7 @@ public static boolean prepareVideo(Context context, int chatId, DcMsg msg) { return false; } - if (!Util.moveFile(tempPath, inPath)) { - alert(context, String.format("Recoding failed for %s: cannot move temporary file %s", inPath, tempPath)); - return false; - } + msg.setFileAndDeduplicate(tempPath, msg.getFilename(), msg.getFilemime()); Log.i(TAG, String.format("recoding for %s done", inPath)); }