From ea522be8f4e75e6c06f5c3a78a93bed2cc939047 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Mon, 16 Mar 2026 16:57:36 +0100 Subject: [PATCH] format some more files --- .../securesms/connect/DcHelper.java | 446 ++++++++++-------- .../providers/PersistentBlobProvider.java | 37 +- 2 files changed, 273 insertions(+), 210 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java index 7e124ab14..4e9e80d02 100644 --- a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java +++ b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java @@ -12,17 +12,19 @@ import android.provider.Settings; import android.util.Log; import android.webkit.MimeTypeMap; import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.FileProvider; - +import chat.delta.rpc.Rpc; +import chat.delta.rpc.RpcException; import com.b44t.messenger.DcAccounts; import com.b44t.messenger.DcChat; import com.b44t.messenger.DcContext; import com.b44t.messenger.DcLot; import com.b44t.messenger.DcMsg; - +import java.io.File; +import java.util.Date; +import java.util.HashMap; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.LocalHelpActivity; @@ -38,83 +40,79 @@ import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.ShareUtil; import org.thoughtcrime.securesms.util.Util; -import java.io.File; -import java.util.Date; -import java.util.HashMap; - -import chat.delta.rpc.Rpc; -import chat.delta.rpc.RpcException; - public class DcHelper { - private static final String TAG = DcHelper.class.getSimpleName(); + private static final String TAG = DcHelper.class.getSimpleName(); - public static final String CONFIG_CONFIGURED_ADDRESS = "configured_addr"; - public static final String CONFIG_DISPLAY_NAME = "displayname"; - public static final String CONFIG_SELF_STATUS = "selfstatus"; - public static final String CONFIG_SELF_AVATAR = "selfavatar"; - public static final String CONFIG_MVBOX_MOVE = "mvbox_move"; - public static final String CONFIG_ONLY_FETCH_MVBOX = "only_fetch_mvbox"; - public static final String CONFIG_BCC_SELF = "bcc_self"; - public static final String CONFIG_SHOW_EMAILS = "show_emails"; - public static final String CONFIG_MEDIA_QUALITY = "media_quality"; - public static final String CONFIG_PROXY_ENABLED = "proxy_enabled"; - public static final String CONFIG_PROXY_URL = "proxy_url"; - public static final String CONFIG_PRIVATE_TAG = "private_tag"; - public static final String CONFIG_STATS_SENDING = "stats_sending"; - public static final String CONFIG_STATS_ID = "stats_id"; + public static final String CONFIG_CONFIGURED_ADDRESS = "configured_addr"; + public static final String CONFIG_DISPLAY_NAME = "displayname"; + public static final String CONFIG_SELF_STATUS = "selfstatus"; + public static final String CONFIG_SELF_AVATAR = "selfavatar"; + public static final String CONFIG_MVBOX_MOVE = "mvbox_move"; + public static final String CONFIG_ONLY_FETCH_MVBOX = "only_fetch_mvbox"; + public static final String CONFIG_BCC_SELF = "bcc_self"; + public static final String CONFIG_SHOW_EMAILS = "show_emails"; + public static final String CONFIG_MEDIA_QUALITY = "media_quality"; + public static final String CONFIG_PROXY_ENABLED = "proxy_enabled"; + public static final String CONFIG_PROXY_URL = "proxy_url"; + public static final String CONFIG_PRIVATE_TAG = "private_tag"; + public static final String CONFIG_STATS_SENDING = "stats_sending"; + public static final String CONFIG_STATS_ID = "stats_id"; - public static DcContext getContext(@NonNull Context context) { - return ApplicationContext.getInstance(context).getDcContext(); - } + public static DcContext getContext(@NonNull Context context) { + return ApplicationContext.getInstance(context).getDcContext(); + } - public static Rpc getRpc(@NonNull Context context) { - return ApplicationContext.getInstance(context).getRpc(); - } + public static Rpc getRpc(@NonNull Context context) { + return ApplicationContext.getInstance(context).getRpc(); + } - public static DcAccounts getAccounts(@NonNull Context context) { - return ApplicationContext.getInstance(context).getDcAccounts(); - } + public static DcAccounts getAccounts(@NonNull Context context) { + return ApplicationContext.getInstance(context).getDcAccounts(); + } - public static DcEventCenter getEventCenter(@NonNull Context context) { - return ApplicationContext.getInstance(context).getEventCenter(); - } + public static DcEventCenter getEventCenter(@NonNull Context context) { + return ApplicationContext.getInstance(context).getEventCenter(); + } - public static NotificationCenter getNotificationCenter(@NonNull Context context) { - return ApplicationContext.getInstance(context).getNotificationCenter(); - } + public static NotificationCenter getNotificationCenter(@NonNull Context context) { + return ApplicationContext.getInstance(context).getNotificationCenter(); + } - public static boolean isConfigured(Context context) { - DcContext dcContext = getContext(context); - return dcContext.isConfigured() == 1; - } + public static boolean isConfigured(Context context) { + DcContext dcContext = getContext(context); + return dcContext.isConfigured() == 1; + } - public static int getInt(Context context, String key) { - DcContext dcContext = getContext(context); - return dcContext.getConfigInt(key); - } + public static int getInt(Context context, String key) { + DcContext dcContext = getContext(context); + return dcContext.getConfigInt(key); + } - public static String get(Context context, String key) { - DcContext dcContext = getContext(context); - return dcContext.getConfig(key); - } + public static String get(Context context, String key) { + DcContext dcContext = getContext(context); + return dcContext.getConfig(key); + } - @Deprecated public static int getInt(Context context, String key, int defaultValue) { - return getInt(context, key); - } + @Deprecated + public static int getInt(Context context, String key, int defaultValue) { + return getInt(context, key); + } - @Deprecated public static String get(Context context, String key, String defaultValue) { - return get(context, key); - } + @Deprecated + public static String get(Context context, String key, String defaultValue) { + return get(context, key); + } - public static void set(Context context, String key, String value) { - DcContext dcContext = getContext(context); - dcContext.setConfig(key, value); - } + public static void set(Context context, String key, String value) { + DcContext dcContext = getContext(context); + dcContext.setConfig(key, value); + } public static void setStockTranslations(Context context) { DcContext dcContext = getContext(context); - // the integers are defined in the core and used only here, an enum or sth. like that won't have a big benefit + // the integers are defined in the core and used only here, an enum or sth. like that won't have + // a big benefit dcContext.setStockTranslation(1, context.getString(R.string.chat_no_messages)); dcContext.setStockTranslation(2, context.getString(R.string.self)); dcContext.setStockTranslation(3, context.getString(R.string.draft)); @@ -133,7 +131,8 @@ public class DcHelper { dcContext.setStockTranslation(69, context.getString(R.string.saved_messages)); dcContext.setStockTranslation(70, context.getString(R.string.device_talk_explain)); dcContext.setStockTranslation(71, context.getString(R.string.device_talk_welcome_message2)); - dcContext.setStockTranslation(73, context.getString(R.string.systemmsg_subject_for_new_contact)); + dcContext.setStockTranslation( + 73, context.getString(R.string.systemmsg_subject_for_new_contact)); dcContext.setStockTranslation(74, context.getString(R.string.systemmsg_failed_sending_to)); dcContext.setStockTranslation(84, context.getString(R.string.configuration_failed_with_error)); dcContext.setStockTranslation(85, context.getString(R.string.devicemsg_bad_time)); @@ -160,9 +159,11 @@ public class DcHelper { dcContext.setStockTranslation(119, context.getString(R.string.qrshow_join_contact_hint)); // HACK: svg does not handle entities correctly and shows `"` as the text `quot;`. - // until that is fixed, we fix the most obvious errors (core uses encode_minimal, so this does not affect so many characters) + // until that is fixed, we fix the most obvious errors (core uses encode_minimal, so this does + // not affect so many characters) // cmp. https://github.com/deltachat/deltachat-android/issues/2187 - dcContext.setStockTranslation(120, context.getString(R.string.qrshow_join_group_hint).replace("\"", "")); + dcContext.setStockTranslation( + 120, context.getString(R.string.qrshow_join_group_hint).replace("\"", "")); dcContext.setStockTranslation(121, context.getString(R.string.connectivity_not_connected)); dcContext.setStockTranslation(124, context.getString(R.string.group_name_changed_by_you)); dcContext.setStockTranslation(125, context.getString(R.string.group_name_changed_by_other)); @@ -179,9 +180,11 @@ public class DcHelper { dcContext.setStockTranslation(136, context.getString(R.string.location_enabled_by_you)); dcContext.setStockTranslation(137, context.getString(R.string.location_enabled_by_other)); dcContext.setStockTranslation(138, context.getString(R.string.ephemeral_timer_disabled_by_you)); - dcContext.setStockTranslation(139, context.getString(R.string.ephemeral_timer_disabled_by_other)); + dcContext.setStockTranslation( + 139, context.getString(R.string.ephemeral_timer_disabled_by_other)); dcContext.setStockTranslation(140, context.getString(R.string.ephemeral_timer_seconds_by_you)); - dcContext.setStockTranslation(141, context.getString(R.string.ephemeral_timer_seconds_by_other)); + dcContext.setStockTranslation( + 141, context.getString(R.string.ephemeral_timer_seconds_by_other)); dcContext.setStockTranslation(144, context.getString(R.string.ephemeral_timer_1_hour_by_you)); dcContext.setStockTranslation(145, context.getString(R.string.ephemeral_timer_1_hour_by_other)); dcContext.setStockTranslation(146, context.getString(R.string.ephemeral_timer_1_day_by_you)); @@ -189,7 +192,8 @@ public class DcHelper { dcContext.setStockTranslation(148, context.getString(R.string.ephemeral_timer_1_week_by_you)); dcContext.setStockTranslation(149, context.getString(R.string.ephemeral_timer_1_week_by_other)); dcContext.setStockTranslation(150, context.getString(R.string.ephemeral_timer_minutes_by_you)); - dcContext.setStockTranslation(151, context.getString(R.string.ephemeral_timer_minutes_by_other)); + dcContext.setStockTranslation( + 151, context.getString(R.string.ephemeral_timer_minutes_by_other)); dcContext.setStockTranslation(152, context.getString(R.string.ephemeral_timer_hours_by_you)); dcContext.setStockTranslation(153, context.getString(R.string.ephemeral_timer_hours_by_other)); dcContext.setStockTranslation(154, context.getString(R.string.ephemeral_timer_days_by_you)); @@ -199,11 +203,14 @@ public class DcHelper { dcContext.setStockTranslation(158, context.getString(R.string.ephemeral_timer_1_year_by_you)); dcContext.setStockTranslation(159, context.getString(R.string.ephemeral_timer_1_year_by_other)); dcContext.setStockTranslation(162, context.getString(R.string.multidevice_qr_subtitle)); - dcContext.setStockTranslation(163, context.getString(R.string.multidevice_transfer_done_devicemsg)); - dcContext.setStockTranslation(170, context.getString(R.string.chat_protection_enabled_tap_to_learn_more)); + dcContext.setStockTranslation( + 163, context.getString(R.string.multidevice_transfer_done_devicemsg)); + dcContext.setStockTranslation( + 170, context.getString(R.string.chat_protection_enabled_tap_to_learn_more)); dcContext.setStockTranslation(172, context.getString(R.string.chat_new_group_hint)); dcContext.setStockTranslation(173, context.getString(R.string.member_x_added)); - dcContext.setStockTranslation(174, context.getString(R.string.invalid_unencrypted_tap_to_learn_more)); + dcContext.setStockTranslation( + 174, context.getString(R.string.invalid_unencrypted_tap_to_learn_more)); dcContext.setStockTranslation(176, context.getString(R.string.reaction_by_you)); dcContext.setStockTranslation(177, context.getString(R.string.reaction_by_other)); dcContext.setStockTranslation(178, context.getString(R.string.member_x_removed)); @@ -225,28 +232,34 @@ public class DcHelper { dcContext.setStockTranslation(234, context.getString(R.string.audio_call)); dcContext.setStockTranslation(235, context.getString(R.string.video_call)); dcContext.setStockTranslation(240, context.getString(R.string.chat_description_changed_by_you)); - dcContext.setStockTranslation(241, context.getString(R.string.chat_description_changed_by_other)); + dcContext.setStockTranslation( + 241, context.getString(R.string.chat_description_changed_by_other)); } public static File getImexDir() { - // DIRECTORY_DOCUMENTS could be used but DIRECTORY_DOWNLOADS seems to be easier accessible by the user, + // DIRECTORY_DOCUMENTS could be used but DIRECTORY_DOWNLOADS seems to be easier accessible by + // the user, // eg. "Download Managers" are nearly always installed. // CAVE: do not use DownloadManager to add the file as it is deleted on uninstall then ... return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); } // When the user shares a file to another app or opens a file in another app, it is added here. - // `HashMap` where `file` is the name of the file in the blobdir (not the user-visible filename). + // `HashMap` where `file` is the name of the file in the blobdir (not the + // user-visible filename). public static final HashMap sharedFiles = new HashMap<>(); public static void openForViewOrShare(Context activity, int msg_id, String cmd) { DcContext dcContext = getContext(activity); - if(!(activity instanceof Activity)) { + if (!(activity instanceof Activity)) { // would be nicer to accepting only Activity objects, - // however, typically in Android just Context objects are passed around (as this normally does not make a difference). - // Accepting only Activity here would force callers to cast, which would easily result in even more ugliness. - Toast.makeText(activity, "openForViewOrShare() expects an Activity object", Toast.LENGTH_LONG).show(); + // however, typically in Android just Context objects are passed around (as this normally does + // not make a difference). + // Accepting only Activity here would force callers to cast, which would easily result in even + // more ugliness. + Toast.makeText(activity, "openForViewOrShare() expects an Activity object", Toast.LENGTH_LONG) + .show(); return; } @@ -257,7 +270,9 @@ public class DcHelper { try { File file = new File(path); if (!file.exists()) { - Toast.makeText(activity, activity.getString(R.string.file_not_found, path), Toast.LENGTH_LONG).show(); + Toast.makeText( + activity, activity.getString(R.string.file_not_found, path), Toast.LENGTH_LONG) + .show(); return; } @@ -267,7 +282,14 @@ public class DcHelper { // Build a Uri that will later be passed to AttachmentsContentProvider.openFile(). // The last part needs to be `filename`, i.e. the original, user-visible name of the file, // so that the external apps show the name of the file correctly. - uri = Uri.parse("content://" + BuildConfig.APPLICATION_ID + ".attachments/" + Uri.encode(file.getName()) + "/" + Uri.encode(filename)); + uri = + Uri.parse( + "content://" + + BuildConfig.APPLICATION_ID + + ".attachments/" + + Uri.encode(file.getName()) + + "/" + + Uri.encode(filename)); // As different Android version handle uris in putExtra differently, // we also check on our own that the file was actually shared. @@ -275,7 +297,9 @@ public class DcHelper { sharedFiles.put(file.getName(), mimeType); } else { if (Build.VERSION.SDK_INT >= 24) { - uri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".fileprovider", file); + uri = + FileProvider.getUriForFile( + activity, BuildConfig.APPLICATION_ID + ".fileprovider", file); } else { uri = Uri.fromFile(file); } @@ -292,76 +316,89 @@ public class DcHelper { intent.putExtra(Intent.EXTRA_STREAM, uri); intent.putExtra(Intent.EXTRA_TEXT, msg.getText()); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.chat_share_with_title))); + activity.startActivity( + Intent.createChooser(intent, activity.getString(R.string.chat_share_with_title))); } } catch (RuntimeException e) { - Toast.makeText(activity, String.format("%s (%s)", activity.getString(R.string.no_app_to_handle_data), mimeType), Toast.LENGTH_LONG).show(); + Toast.makeText( + activity, + String.format( + "%s (%s)", activity.getString(R.string.no_app_to_handle_data), mimeType), + Toast.LENGTH_LONG) + .show(); Log.i(TAG, "opening of external activity failed.", e); } } - public static void sendToChat(Context activity, byte[] data, String mimeType, String fileName, String text) { - Intent intent = new Intent(activity, ShareActivity.class); - intent.setAction(Intent.ACTION_SEND); - ShareUtil.setIsFromWebxdc(intent, true); + public static void sendToChat( + Context activity, byte[] data, String mimeType, String fileName, String text) { + Intent intent = new Intent(activity, ShareActivity.class); + intent.setAction(Intent.ACTION_SEND); + ShareUtil.setIsFromWebxdc(intent, true); - if (data != null) { - Uri uri = PersistentBlobProvider.getInstance().create(activity, data, mimeType, fileName); - intent.setType(mimeType); - intent.putExtra(Intent.EXTRA_STREAM, uri); - ShareUtil.setSharedTitle(intent, activity.getString(R.string.send_file_to, fileName)); + if (data != null) { + Uri uri = PersistentBlobProvider.getInstance().create(activity, data, mimeType, fileName); + intent.setType(mimeType); + intent.putExtra(Intent.EXTRA_STREAM, uri); + ShareUtil.setSharedTitle(intent, activity.getString(R.string.send_file_to, fileName)); + } + + if (text != null) { + intent.putExtra(Intent.EXTRA_TEXT, text); + if (data == null) { + ShareUtil.setSharedTitle(intent, activity.getString(R.string.send_message_to)); } + } - if (text != null) { - intent.putExtra(Intent.EXTRA_TEXT, text); - if (data == null) { - ShareUtil.setSharedTitle(intent, activity.getString(R.string.send_message_to)); - } - } - - activity.startActivity(intent); + activity.startActivity(intent); } private static void startActivity(Activity activity, Intent intent) { // request for permission to install apks on API 26+ if intent mimetype is an apk - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - "application/vnd.android.package-archive".equals(intent.getType()) && - !activity.getPackageManager().canRequestPackageInstalls()) { - activity.startActivity(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", activity.getPackageName())))); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && "application/vnd.android.package-archive".equals(intent.getType()) + && !activity.getPackageManager().canRequestPackageInstalls()) { + activity.startActivity( + new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + .setData(Uri.parse(String.format("package:%s", activity.getPackageName())))); return; } activity.startActivity(intent); } public static String checkMime(String path, String mimeType) { - if(mimeType == null || mimeType.equals("application/octet-stream")) { + if (mimeType == null || mimeType.equals("application/octet-stream")) { path = path.replaceAll(" ", ""); String extension = MediaUtil.getFileExtensionFromUrl(path); String newType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - if(newType != null) return newType; + if (newType != null) return newType; } 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()`). + * 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); String outPath = null; for (int i = 0; i < 1000; i++) { - String test = dcContext.getBlobdir() + "/" + filename + (i == 0 ? "" : i < 100 ? "-" + i : "-" + (new Date().getTime() + i)) + ext; + String test = + dcContext.getBlobdir() + + "/" + + filename + + (i == 0 ? "" : i < 100 ? "-" + i : "-" + (new Date().getTime() + i)) + + ext; if (!new File(test).exists()) { outPath = test; break; } } - if(outPath==null) { + if (outPath == null) { // should not happen outPath = dcContext.getBlobdir() + "/" + Math.random(); } @@ -369,19 +406,22 @@ public class DcHelper { } public static String getBlobdirFile(DcContext dcContext, String path) { - String filename = path.substring(path.lastIndexOf('/')+1); // is the whole path if '/' is not found (lastIndexOf() returns -1 then) + String filename = + path.substring( + path.lastIndexOf('/') + + 1); // is the whole path if '/' is not found (lastIndexOf() returns -1 then) String ext = ""; int point = filename.indexOf('.'); - if(point!=-1) { + if (point != -1) { ext = filename.substring(point); filename = filename.substring(0, point); } return getBlobdirFile(dcContext, filename, ext); - } @NonNull - public static ThreadRecord getThreadRecord(Context context, DcLot summary, DcChat chat) { // adapted from ThreadDatabase.getCurrent() + public static ThreadRecord getThreadRecord( + Context context, DcLot summary, DcChat chat) { // adapted from ThreadDatabase.getCurrent() int chatId = chat.getId(); String body = summary.getText1(); @@ -394,14 +434,23 @@ public class DcHelper { long date = summary.getTimestamp(); int unreadCount = getContext(context).getFreshMsgCount(chatId); - return new ThreadRecord(body, recipient, date, - unreadCount, chatId, - chat.getVisibility(), chat.isSendingLocations(), chat.isMuted(), chat.isContactRequest(), summary); + return new ThreadRecord( + body, + recipient, + date, + unreadCount, + chatId, + chat.getVisibility(), + chat.isSendingLocations(), + chat.isMuted(), + chat.isContactRequest(), + summary); } public static boolean isNetworkConnected(Context context) { try { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnected()) { return true; @@ -414,105 +463,110 @@ public class DcHelper { /** * Gets a string you can show to the user with basic information about connectivity. + * * @param context * @param connectedString Usually "Connected", but when using this as the title in - * ConversationListActivity, we want to write "Delta Chat" - * or the user's display name there instead. + * ConversationListActivity, we want to write "Delta Chat" or the user's display name there + * instead. * @return */ public static String getConnectivitySummary(Context context, String connectedString) { - int connectivity = getContext(context).getConnectivity(); - if (connectivity >= DcContext.DC_CONNECTIVITY_CONNECTED) { - return connectedString; - } else if (connectivity >= DcContext.DC_CONNECTIVITY_WORKING) { - return context.getString(R.string.connectivity_updating); - } else if (connectivity >= DcContext.DC_CONNECTIVITY_CONNECTING) { - return context.getString(R.string.connectivity_connecting); - } else { - return context.getString(R.string.connectivity_not_connected); - } + int connectivity = getContext(context).getConnectivity(); + if (connectivity >= DcContext.DC_CONNECTIVITY_CONNECTED) { + return connectedString; + } else if (connectivity >= DcContext.DC_CONNECTIVITY_WORKING) { + return context.getString(R.string.connectivity_updating); + } else if (connectivity >= DcContext.DC_CONNECTIVITY_CONNECTING) { + return context.getString(R.string.connectivity_connecting); + } else { + return context.getString(R.string.connectivity_not_connected); + } } public static void showProtectionEnabledDialog(Context context) { new AlertDialog.Builder(context) - .setMessage(context.getString(R.string.chat_protection_enabled_explanation)) - .setNeutralButton(R.string.learn_more, (d, w) -> openHelp(context, "#e2ee")) - .setPositiveButton(R.string.ok, null) - .setCancelable(true) - .show(); + .setMessage(context.getString(R.string.chat_protection_enabled_explanation)) + .setNeutralButton(R.string.learn_more, (d, w) -> openHelp(context, "#e2ee")) + .setPositiveButton(R.string.ok, null) + .setCancelable(true) + .show(); } public static void showInvalidUnencryptedDialog(Context context) { new AlertDialog.Builder(context) - .setMessage(context.getString(R.string.invalid_unencrypted_explanation)) - .setNeutralButton(R.string.learn_more, (d, w) -> openHelp(context, "#howtoe2ee")) - .setNegativeButton(R.string.qrscan_title, (d, w) -> context.startActivity(new Intent(context, QrActivity.class))) - .setPositiveButton(R.string.ok, null) - .setCancelable(true) - .show(); + .setMessage(context.getString(R.string.invalid_unencrypted_explanation)) + .setNeutralButton(R.string.learn_more, (d, w) -> openHelp(context, "#howtoe2ee")) + .setNegativeButton( + R.string.qrscan_title, + (d, w) -> context.startActivity(new Intent(context, QrActivity.class))) + .setPositiveButton(R.string.ok, null) + .setCancelable(true) + .show(); } public static void openHelp(Context context, String section) { Intent intent = new Intent(context, LocalHelpActivity.class); - if (section != null) { intent.putExtra(LocalHelpActivity.SECTION_EXTRA, section); } + if (section != null) { + intent.putExtra(LocalHelpActivity.SECTION_EXTRA, section); + } context.startActivity(intent); } - /** - * For the PGP-Contacts migration, things can go wrong. - * The migration happens when the account is setup, at which point no events can be sent yet. - * So, instead, if something goes wrong, it's returned by getLastError(). - * This function shows the error message to the user. - *

- * A few releases after the PGP-contacts migration (which happened in 2025-05), - * we can remove this function again. - */ - public static void maybeShowMigrationError(Context context) { - try { - String lastError = DcHelper.getRpc(context).getMigrationError(DcHelper.getContext(context).getAccountId()); + /** + * For the PGP-Contacts migration, things can go wrong. The migration happens when the account is + * setup, at which point no events can be sent yet. So, instead, if something goes wrong, it's + * returned by getLastError(). This function shows the error message to the user. + * + *

A few releases after the PGP-contacts migration (which happened in 2025-05), we can remove + * this function again. + */ + public static void maybeShowMigrationError(Context context) { + try { + String lastError = + DcHelper.getRpc(context).getMigrationError(DcHelper.getContext(context).getAccountId()); - if (lastError != null && !lastError.isEmpty()) { - Log.w(TAG, "Opening account failed, trying to share error: " + lastError); + if (lastError != null && !lastError.isEmpty()) { + Log.w(TAG, "Opening account failed, trying to share error: " + lastError); - String subject = "Delta Chat failed to update"; - String email = "delta@merlinux.eu"; + String subject = "Delta Chat failed to update"; + String email = "delta@merlinux.eu"; - new AlertDialog.Builder(context) - .setMessage(context.getString(R.string.error_x, lastError)) - .setNeutralButton(R.string.global_menu_edit_copy_desktop, (d, which) -> { - Util.writeTextToClipboard(context, lastError); - }) - .setPositiveButton(R.string.menu_send, (d, which) -> { - Intent sharingIntent = new Intent( - Intent.ACTION_SENDTO, Uri.fromParts( - "mailto", email, null - ) - ); - sharingIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{email}); - sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); - sharingIntent.putExtra(Intent.EXTRA_TEXT, lastError); + new AlertDialog.Builder(context) + .setMessage(context.getString(R.string.error_x, lastError)) + .setNeutralButton( + R.string.global_menu_edit_copy_desktop, + (d, which) -> { + Util.writeTextToClipboard(context, lastError); + }) + .setPositiveButton( + R.string.menu_send, + (d, which) -> { + Intent sharingIntent = + new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null)); + sharingIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {email}); + sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + sharingIntent.putExtra(Intent.EXTRA_TEXT, lastError); - if (sharingIntent.resolveActivity(context.getPackageManager()) == null) { - Log.w(TAG, "No email client found to send crash report"); - sharingIntent = new Intent(Intent.ACTION_SEND); - sharingIntent.setType("text/plain"); - sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); - sharingIntent.putExtra(Intent.EXTRA_TEXT, lastError); - sharingIntent.putExtra(Intent.EXTRA_EMAIL, email); - } + if (sharingIntent.resolveActivity(context.getPackageManager()) == null) { + Log.w(TAG, "No email client found to send crash report"); + sharingIntent = new Intent(Intent.ACTION_SEND); + sharingIntent.setType("text/plain"); + sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + sharingIntent.putExtra(Intent.EXTRA_TEXT, lastError); + sharingIntent.putExtra(Intent.EXTRA_EMAIL, email); + } - Intent chooser = - Intent.createChooser(sharingIntent, "Send using..."); - chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - chooser.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + Intent chooser = Intent.createChooser(sharingIntent, "Send using..."); + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + chooser.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - context.startActivity(chooser); - }) - .setCancelable(false) - .show(); - } - } catch (RpcException e) { - e.printStackTrace(); - } + context.startActivity(chooser); + }) + .setCancelable(false) + .show(); + } + } catch (RpcException e) { + e.printStackTrace(); } + } } diff --git a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java index a38d9d9a4..7da633627 100644 --- a/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java +++ b/src/main/java/org/thoughtcrime/securesms/providers/PersistentBlobProvider.java @@ -67,11 +67,12 @@ public class PersistentBlobProvider { private PersistentBlobProvider() {} public Uri create( - @NonNull Context context, - @NonNull File inputFile, - @NonNull String mimeType, - @Nullable String fileName, - @Nullable Long fileSize) throws IOException { + @NonNull Context context, + @NonNull File inputFile, + @NonNull String mimeType, + @Nullable String fileName, + @Nullable Long fileSize) + throws IOException { if (!inputFile.exists()) { throw new IOException("Input file does not exist: " + inputFile.getAbsolutePath()); @@ -102,22 +103,30 @@ public class PersistentBlobProvider { Util.copy(input, output); } finally { if (output != null) { - try { output.close(); } catch (IOException e) { Log.w(TAG, e); } + try { + output.close(); + } catch (IOException e) { + Log.w(TAG, e); + } } if (input != null) { - try { input.close(); } catch (IOException e) { Log.w(TAG, e); } + try { + input.close(); + } catch (IOException e) { + Log.w(TAG, e); + } } } } final Uri uniqueUri = - CONTENT_URI - .buildUpon() - .appendPath(mimeType) - .appendPath(fileName) - .appendEncodedPath(String.valueOf(fileSize)) - .appendEncodedPath(String.valueOf(System.currentTimeMillis())) - .build(); + CONTENT_URI + .buildUpon() + .appendPath(mimeType) + .appendPath(fileName) + .appendEncodedPath(String.valueOf(fileSize)) + .appendEncodedPath(String.valueOf(System.currentTimeMillis())) + .build(); return ContentUris.withAppendedId(uniqueUri, id); }