From 6af6ff80ba4b3120fcf221c3d9ccdada0154212e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:51:35 +0000 Subject: [PATCH 1/4] Initial plan From fe26af88b4c4881b28c1eaad934c4cef081ad875 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:55:15 +0000 Subject: [PATCH 2/4] Fix quick-camera button crash on devices with external SD cards Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../providers/PersistentBlobProvider.java | 21 +++++++++++++++++-- src/main/res/xml/file_provider_paths.xml | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java index 0a85bc73e..87a05c229 100644 --- a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java +++ b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java @@ -122,8 +122,25 @@ private void persistToDisk(@NonNull Context context, } public Uri createForExternal(@NonNull Context context, @NonNull String mimeType) throws IOException, IllegalStateException, NullPointerException { - File target = new File(getExternalDir(context), System.currentTimeMillis() + "." + getExtensionFromMimeType(mimeType)); - return FileProviderUtil.getUriFor(context, target); + long timestamp = System.currentTimeMillis(); + String filename = timestamp + "." + getExtensionFromMimeType(mimeType); + + // Try external cache first + try { + File externalDir = getExternalDir(context); + File target = new File(externalDir, filename); + return FileProviderUtil.getUriFor(context, target); + } catch (IllegalArgumentException e) { + // FileProvider doesn't support the external cache path (e.g., on removable SD card) + // Fall back to internal cache + Log.w(TAG, "FileProvider doesn't support external cache path, falling back to internal cache", e); + File internalDir = context.getCacheDir(); + if (internalDir == null) { + throw new IOException("no cache directory available"); + } + File target = new File(internalDir, filename); + return FileProviderUtil.getUriFor(context, target); + } } public boolean delete(@NonNull Context context, @NonNull Uri uri) { diff --git a/src/main/res/xml/file_provider_paths.xml b/src/main/res/xml/file_provider_paths.xml index 77df3dcae..00c8530e3 100644 --- a/src/main/res/xml/file_provider_paths.xml +++ b/src/main/res/xml/file_provider_paths.xml @@ -1,5 +1,6 @@ + From 99c848b1b7ae5ff7e0a9c24653687b7ac93fd780 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:58:38 +0000 Subject: [PATCH 3/4] Add clarifying comment about fallback logic Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../securesms/providers/PersistentBlobProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java index 87a05c229..ae797d77a 100644 --- a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java +++ b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java @@ -131,8 +131,10 @@ public Uri createForExternal(@NonNull Context context, @NonNull String mimeType) File target = new File(externalDir, filename); return FileProviderUtil.getUriFor(context, target); } catch (IllegalArgumentException e) { - // FileProvider doesn't support the external cache path (e.g., on removable SD card) - // Fall back to internal cache + // FileProvider doesn't support the external cache path (e.g., on removable SD card). + // Note: getExternalDir() already falls back to internal cache when external cache is null, + // but when external cache exists on a removable SD card, FileProvider may reject it. + // In that case, we explicitly use internal cache which FileProvider always supports. Log.w(TAG, "FileProvider doesn't support external cache path, falling back to internal cache", e); File internalDir = context.getCacheDir(); if (internalDir == null) { From 98d711e0cae9472de8032fae4ff0e42e1f339316 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Mon, 22 Dec 2025 18:23:08 +0100 Subject: [PATCH 4/4] tweak createForExternal --- .../securesms/providers/PersistentBlobProvider.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java index ae797d77a..460da70d3 100644 --- a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java +++ b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java @@ -122,8 +122,7 @@ private void persistToDisk(@NonNull Context context, } public Uri createForExternal(@NonNull Context context, @NonNull String mimeType) throws IOException, IllegalStateException, NullPointerException { - long timestamp = System.currentTimeMillis(); - String filename = timestamp + "." + getExtensionFromMimeType(mimeType); + String filename = System.currentTimeMillis() + "." + getExtensionFromMimeType(mimeType); // Try external cache first try {