Merge remote-tracking branch 'upstream/main'

This commit is contained in:
adbenitez
2024-10-22 02:13:13 +02:00
59 changed files with 338 additions and 302 deletions
@@ -27,7 +27,7 @@ import static org.thoughtcrime.securesms.util.RelayUtil.isSharing;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ClipData;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
@@ -36,7 +36,6 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.provider.Browser;
@@ -346,14 +345,27 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
switch (reqCode) {
case PICK_GALLERY:
MediaType mediaType;
String mimeType = MediaUtil.getMimeType(this, data.getData());
if (MediaUtil.isGif(mimeType)) mediaType = MediaType.GIF;
else if (MediaUtil.isVideo(mimeType)) mediaType = MediaType.VIDEO;
else mediaType = MediaType.IMAGE;
setMedia(data.getData(), mediaType);
final Uri singleUri = data.getData();
if (singleUri != null) {
MediaType mediaType;
String mimeType = MediaUtil.getMimeType(this, singleUri);
if (MediaUtil.isGif(mimeType)) mediaType = MediaType.GIF;
else if (MediaUtil.isVideo(mimeType)) mediaType = MediaType.VIDEO;
else mediaType = MediaType.IMAGE;
setMedia(singleUri, mediaType);
} else {
final ClipData multipleUris = data.getClipData();
if (multipleUris != null) {
final int uriCount = multipleUris.getItemCount();
if (uriCount > 0) {
ArrayList<Uri> uriList = new ArrayList<>(uriCount);
for (int i = 0; i < uriCount; i++) {
uriList.add(multipleUris.getItemAt(i).getUri());
}
askSendingFiles(uriList, () -> SendRelayedMessageUtil.sendMultipleMsgs(this, chatId, uriList, null));
}
}
}
break;
case PICK_DOCUMENT:
@@ -656,20 +668,24 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
}
private void askSendingFiles(ArrayList<Uri> uriList, Runnable onConfirm) {
String message = String.format(getString(R.string.ask_send_files_to_chat), uriList.size(), dcChat.getName());
if (SendRelayedMessageUtil.containsVideoType(context, uriList)) {
message += "\n\n" + getString(R.string.videos_sent_without_recoding);
}
new AlertDialog.Builder(this)
.setMessage(message)
.setCancelable(false)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.menu_send, (dialog, which) -> onConfirm.run())
.show();
}
private void handleSharing() {
ArrayList<Uri> uriList = RelayUtil.getSharedUris(this);
int sharedContactId = RelayUtil.getSharedContactId(this);
if (uriList.size() > 1) {
String message = String.format(getString(R.string.ask_send_files_to_selected_chat), uriList.size());
if (SendRelayedMessageUtil.containsVideoType(context, uriList)) {
message += "\n\n" + getString(R.string.videos_sent_without_recoding);
}
new AlertDialog.Builder(this)
.setMessage(message)
.setCancelable(false)
.setNegativeButton(android.R.string.cancel, ((dialog, which) -> finish()))
.setPositiveButton(R.string.menu_send, (dialog, which) -> SendRelayedMessageUtil.immediatelyRelay(this, chatId))
.show();
askSendingFiles(uriList, () -> SendRelayedMessageUtil.immediatelyRelay(this, chatId));
} else {
if (sharedContactId != 0) {
addAttachmentContactInfo(sharedContactId);
@@ -19,6 +19,7 @@ package org.thoughtcrime.securesms;
import static org.thoughtcrime.securesms.ConversationActivity.CHAT_ID_EXTRA;
import static org.thoughtcrime.securesms.ConversationActivity.STARTING_POSITION_EXTRA;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_ADDRESS;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_PROXY_ENABLED;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_SERVER_FLAGS;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_PROXY_URL;
import static org.thoughtcrime.securesms.util.RelayUtil.acquireRelayMessageContent;
@@ -365,6 +366,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
public void onResume() {
super.onResume();
refreshTitle();
invalidateOptionsMenu();
DirectShareUtil.triggerRefreshDirectShare(this);
}
@@ -376,7 +378,14 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
if (!isRelayingMessageContent(this)) {
inflater.inflate(R.menu.text_secure_normal, menu);
menu.findItem(R.id.menu_global_map).setVisible(Prefs.isLocationStreamingEnabled(this));
menu.findItem(R.id.menu_proxy_settings).setVisible(!TextUtils.isEmpty(DcHelper.get(this, CONFIG_PROXY_URL)));
MenuItem proxyItem = menu.findItem(R.id.menu_proxy_settings);
if (TextUtils.isEmpty(DcHelper.get(this, CONFIG_PROXY_URL))) {
proxyItem.setVisible(false);
} else {
boolean proxyEnabled = DcHelper.getInt(this, CONFIG_PROXY_ENABLED) == 1;
proxyItem.setIcon(proxyEnabled? R.drawable.ic_proxy_enabled_24 : R.drawable.ic_proxy_disabled_24);
proxyItem.setVisible(true);
}
MenuCompat.setGroupDividerEnabled(menu, true);
}
@@ -1,5 +1,8 @@
package org.thoughtcrime.securesms;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_PROXY_ENABLED;
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_PROXY_URL;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
@@ -140,6 +143,14 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
getMenuInflater().inflate(R.menu.instant_onboarding_menu, menu);
MenuItem proxyItem = menu.findItem(R.id.menu_proxy_settings);
if (TextUtils.isEmpty(DcHelper.get(this, CONFIG_PROXY_URL))) {
proxyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
} else {
boolean proxyEnabled = DcHelper.getInt(this, CONFIG_PROXY_ENABLED) == 1;
proxyItem.setIcon(proxyEnabled? R.drawable.ic_proxy_enabled_24 : R.drawable.ic_proxy_disabled_24);
proxyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
return super.onPrepareOptionsMenu(menu);
}
@@ -243,6 +254,12 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
}
}
@Override
public void onResume() {
super.onResume();
invalidateOptionsMenu();
}
@Override
public void onDestroy() {
super.onDestroy();
@@ -87,15 +87,15 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
private void refreshData() {
if (adapter == null) return;
DcAccounts accounts = DcHelper.getAccounts(requireActivity());
DcAccounts accounts = DcHelper.getAccounts(getActivity());
int[] accountIds = accounts.getAll();
int[] ids = new int[accountIds.length + 1];
ids[0] = DC_CONTACT_ID_ADD_ACCOUNT;
int j = 0;
for (int accountId : accountIds) {
ids[++j] = accountId;
ids[j++] = accountId;
}
ids[j] = DC_CONTACT_ID_ADD_ACCOUNT;
adapter.changeData(ids, accounts.getSelectedAccount().getAccountId());
}
@@ -460,7 +460,7 @@ public class AttachmentManager {
.request(Permissions.galleryPermissions())
.ifNecessary()
.withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> selectMediaType(activity, "image/*", new String[] {"image/*", "video/*"}, requestCode))
.onAllGranted(() -> selectMediaType(activity, "image/*", new String[] {"image/*", "video/*"}, requestCode, null, true))
.execute();
}
@@ -573,10 +573,14 @@ public class AttachmentManager {
}
public static void selectMediaType(Activity activity, @NonNull String type, @Nullable String[] extraMimeType, int requestCode) {
selectMediaType(activity, type, extraMimeType, requestCode, null);
selectMediaType(activity, type, extraMimeType, requestCode, null, false);
}
public static void selectMediaType(Activity activity, @NonNull String type, @Nullable String[] extraMimeType, int requestCode, @Nullable Uri initialUri) {
selectMediaType(activity, type, extraMimeType, requestCode, initialUri, false);
}
public static void selectMediaType(Activity activity, @NonNull String type, @Nullable String[] extraMimeType, int requestCode, @Nullable Uri initialUri, boolean allowMultiple) {
final Intent intent = new Intent();
intent.setType(type);
@@ -588,6 +592,10 @@ public class AttachmentManager {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialUri);
}
if (allowMultiple) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
try {
@@ -35,7 +35,7 @@ public class PersistentBlobProvider {
public static final String EXPECTED_PATH_NEW = "capture-new/*/*/*/*/#";
private static final int MIMETYPE_PATH_SEGMENT = 1;
private static final int FILENAME_PATH_SEGMENT = 2;
public static final int FILENAME_PATH_SEGMENT = 2;
private static final int FILESIZE_PATH_SEGMENT = 3;
private static final String BLOB_EXTENSION = "blob";
@@ -75,8 +75,7 @@ public class QrActivity extends BaseActionBarActivity {
getSupportActionBar().setTitle(R.string.menu_new_contact);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
int lastSelectedTab = PreferenceManager.getDefaultSharedPreferences(this).getInt("qrTab", TAB_SHOW);
viewPager.setCurrentItem(lastSelectedTab);
viewPager.setCurrentItem(TAB_SHOW);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
@@ -95,8 +94,6 @@ public class QrActivity extends BaseActionBarActivity {
});
tabLayout.setupWithViewPager(viewPager);
checkPermissions(lastSelectedTab, adapter, viewPager);
}
private void checkPermissions(int position, ProfilePagerAdapter adapter, ViewPager viewPager) {
@@ -123,13 +120,6 @@ public class QrActivity extends BaseActionBarActivity {
return super.onPrepareOptionsMenu(menu);
}
@Override
protected void onPause() {
super.onPause();
int currentSelectedTab = tabLayout.getSelectedTabPosition();
PreferenceManager.getDefaultSharedPreferences(this).edit().putInt("qrTab", currentSelectedTab).apply();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
@@ -1,9 +1,12 @@
package org.thoughtcrime.securesms.util;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.provider.OpenableColumns;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
@@ -11,6 +14,7 @@ import com.b44t.messenger.DcMsg;
import org.thoughtcrime.securesms.ConversationListRelayingActivity;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import java.io.BufferedReader;
import java.io.FileOutputStream;
@@ -56,7 +60,7 @@ public class SendRelayedMessageUtil {
resetRelayingMessageContent(activity);
Util.runOnAnyBackgroundThread(() -> {
for (long chatId : chatIds) {
handleSharing(activity, (int) chatId, sharedUris, msgType, sharedHtml, subject, sharedText);
sendMultipleMsgs(activity, (int) chatId, sharedUris, msgType, sharedHtml, subject, sharedText);
}
});
}
@@ -67,7 +71,11 @@ public class SendRelayedMessageUtil {
dcContext.forwardMsgs(forwardedMessageIDs, chatId);
}
private static void handleSharing(Context context, int chatId, ArrayList<Uri> sharedUris, String msgType, String sharedHtml, String subject, String sharedText) {
public static void sendMultipleMsgs(Context context, int chatId, ArrayList<Uri> sharedUris, String sharedText) {
sendMultipleMsgs(context, chatId, sharedUris, null, null, null, sharedText);
}
private static void sendMultipleMsgs(Context context, int chatId, ArrayList<Uri> sharedUris, String msgType, String sharedHtml, String subject, String sharedText) {
DcContext dcContext = DcHelper.getContext(context);
ArrayList<Uri> uris = sharedUris;
String text = sharedText;
@@ -130,13 +138,32 @@ public class SendRelayedMessageUtil {
private static String getRealPathFromUri(Context context, Uri uri) throws NullPointerException {
DcContext dcContext = DcHelper.getContext(context);
try {
String filename = uri.getPathSegments().get(2); // Get real file name from Uri
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")) {
final ContentResolver contentResolver = context.getContentResolver();
final Cursor cursor = contentResolver.query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
final int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (nameIndex >= 0) {
filename = cursor.getString(nameIndex);
}
}
} finally {
cursor.close();
}
}
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);
// copy content to this file