Merge remote-tracking branch 'upstream/main' into lite

This commit is contained in:
adbenitez
2023-10-12 23:11:40 +02:00
16 changed files with 57 additions and 26 deletions
+1
View File
@@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.CAMERA" />
+2
View File
@@ -6,4 +6,6 @@
<color name="reaction_pill_background_selected">#ff282828</color>
<color name="reaction_pill_border_selected">@color/reaction_pill_border</color>
<color name="reaction_pill_text_color_selected">@color/reaction_pill_text_color</color>
<color name="action_mode_status_bar">@color/gray95</color>
</resources>
+1 -1
View File
@@ -198,7 +198,7 @@
<item name="actionBarStyle">@style/TextSecure.DarkActionBar</item>
<item name="actionBarTabBarStyle">@style/TextSecure.DarkActionBar.TabBar</item>
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="actionModeBackground">@color/gray50</item>
<item name="actionModeBackground">@color/gray78</item>
<item name="android:textColor">@color/text_color_dark_theme</item>
<item name="android:textColorSecondary">@color/text_color_secondary_dark_theme</item>
@@ -52,7 +52,7 @@ class ConversationListAdapter extends RecyclerView.Adapter {
private static final int MESSAGE_TYPE_INBOX_ZERO = 3;
private final WeakReference<Context> context;
private final @NonNull DcContext dcContext;
private @NonNull DcContext dcContext;
private @NonNull DcChatlist dcChatlist;
private final @NonNull GlideRequests glideRequests;
private final @NonNull Locale locale;
@@ -195,7 +195,16 @@ class ConversationListAdapter extends RecyclerView.Adapter {
}
void changeData(@Nullable DcChatlist chatlist) {
dcChatlist = chatlist == null ? new DcChatlist(0, 0) : chatlist;
Context context = this.context.get();
if (context == null) {
return;
}
if (chatlist == null) {
dcChatlist = new DcChatlist(0, 0);
} else {
dcChatlist = chatlist;
dcContext = DcHelper.getContext(context);
}
notifyDataSetChanged();
}
}
@@ -254,6 +254,8 @@ public class ConversationListFragment extends Fragment
@SuppressLint({"StaticFieldLeak", "NewApi"})
private void updateReminders() {
// by the time onPostExecute() is asynchronously run, getActivity() might return null, so get the activity here:
Activity activity = getActivity();
new AsyncTask<Context, Void, Void>() {
@Override
protected Void doInBackground(Context... params) {
@@ -270,7 +272,6 @@ public class ConversationListFragment extends Fragment
@Override
protected void onPostExecute(Void result) {
Activity activity = ConversationListFragment.this.getActivity();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (!Prefs.getBooleanPreference(activity, Prefs.ASKED_FOR_NOTIFICATION_PERMISSION, false)) {
Prefs.setBooleanPreference(activity, Prefs.ASKED_FOR_NOTIFICATION_PERMISSION, true);
@@ -278,7 +279,7 @@ public class ConversationListFragment extends Fragment
.request(Manifest.permission.POST_NOTIFICATIONS)
.ifNecessary()
.onAllGranted(() -> {
DozeReminder.maybeAskDirectly(getActivity());
DozeReminder.maybeAskDirectly(activity);
})
.onAnyDenied(() -> {
final DcContext dcContext = DcHelper.getContext(activity);
@@ -290,10 +291,10 @@ public class ConversationListFragment extends Fragment
.execute();
}
} else {
DozeReminder.maybeAskDirectly(getActivity());
DozeReminder.maybeAskDirectly(activity);
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, activity);
}
private void handlePinAllSelected() {
@@ -56,6 +56,7 @@ public class LogViewActivity extends BaseActionBarActivity {
case R.id.save_log:
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.onAllGranted(() -> {
boolean success = logViewFragment.saveLogFile();
@@ -305,6 +305,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> {
@@ -86,6 +86,7 @@ public abstract class MessageSelectorFragment
Permissions.with(getActivity())
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> performSave(messageRecords))
@@ -151,6 +151,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
private void requestPermissionForFiles(List<Uri> streamExtras) {
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.alwaysGrantOnSdk33()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> resolveUris(streamExtras))
@@ -170,6 +170,7 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
private void startImportBackup() {
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> {
@@ -446,6 +446,10 @@ public class AttachmentManager {
}
public static void selectGallery(Activity activity, int requestCode) {
// to enable camera roll,
// we're asking for "gallery permissions" also on newer systems that do not strictly require that.
// (asking directly after tapping "attachment" would be not-so-good as the user may want to attach sth. else
// and asking for permissions is better done on-point)
Permissions.with(activity)
.request(Permissions.galleryPermissions())
.ifNecessary()
@@ -466,6 +470,7 @@ public class AttachmentManager {
public static void selectAudio(Activity activity, int requestCode) {
Permissions.with(activity)
.request(Manifest.permission.READ_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> selectMediaType(activity, "audio/*", null, requestCode))
@@ -80,6 +80,8 @@ public class Permissions {
private boolean condition = true;
private boolean alwaysGranted = false;
PermissionsBuilder(PermissionObject permissionObject) {
this.permissionObject = permissionObject;
}
@@ -100,6 +102,20 @@ public class Permissions {
return this;
}
public PermissionsBuilder alwaysGrantOnSdk30() {
if (Build.VERSION.SDK_INT >= 30) {
alwaysGranted = true;
}
return this;
}
public PermissionsBuilder alwaysGrantOnSdk33() {
if (Build.VERSION.SDK_INT >= 33) {
alwaysGranted = true;
}
return this;
}
public PermissionsBuilder withRationaleDialog(@NonNull String message, @NonNull @DrawableRes int... headers) {
this.rationalDialogHeader = headers;
this.rationaleDialogMessage = message;
@@ -147,16 +163,9 @@ public class Permissions {
}
public void execute() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE does not exist on modern androids
// as file access is done by pickers
String[] r = requestedPermissions;
Arrays.sort(r);
if ( (r.length == 1 && (r[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE) || r[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)))
|| (r.length == 2 && r[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE) && r[1].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) ) {
allGrantedListener.run();
return;
}
if (alwaysGranted) {
allGrantedListener.run();
return;
}
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener,
@@ -177,7 +177,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) return;
if (requestCode == REQUEST_CODE_CONFIRM_CREDENTIALS_KEYS) {
exportKeys();
manageKeys();
} else if (requestCode == PICK_SELF_KEYS) {
Uri uri = (data != null ? data.getData() : null);
if (uri == null) {
@@ -330,15 +330,16 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
public boolean onPreferenceClick(Preference preference) {
boolean result = ScreenLockUtil.applyScreenLock(getActivity(), getString(R.string.pref_manage_keys), getString(R.string.enter_system_secret_to_continue), REQUEST_CODE_CONFIRM_CREDENTIALS_KEYS);
if (!result) {
exportKeys();
manageKeys();
}
return true;
}
}
private void exportKeys() {
private void manageKeys() {
Permissions.with(getActivity())
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> {
@@ -359,7 +360,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
}
else {
if (Build.VERSION.SDK_INT >= 30) {
AttachmentManager.selectMediaType(getActivity(), "application/pgp-keys", new String[]{"text/plain"}, PICK_SELF_KEYS, StorageUtil.getDownloadUri());
AttachmentManager.selectMediaType(getActivity(), "*/*", null, PICK_SELF_KEYS, StorageUtil.getDownloadUri());
} else {
String path = DcHelper.getImexDir().getAbsolutePath();
showImportKeysDialog(path, path);
@@ -38,7 +38,6 @@ public class ChatBackgroundActivity extends PassphraseRequiredActionBarActivity
Button galleryButton;
Button defaultButton;
MenuItem acceptMenuItem;
ImageView preview;
String tempDestinationPath;
@@ -80,7 +79,6 @@ public class ChatBackgroundActivity extends PassphraseRequiredActionBarActivity
MenuInflater inflater = this.getMenuInflater();
menu.clear();
inflater.inflate(R.menu.chat_background, menu);
acceptMenuItem = menu.findItem(R.id.apply_background);
super.onPrepareOptionsMenu(menu);
return true;
}
@@ -173,7 +171,6 @@ public class ChatBackgroundActivity extends PassphraseRequiredActionBarActivity
if (data != null && context != null && resultCode == RESULT_OK && requestCode == ApplicationPreferencesActivity.REQUEST_CODE_SET_BACKGROUND) {
imageUri = data.getData();
if (imageUri != null) {
acceptMenuItem.setEnabled(true);
Thread thread = new Thread(){
@Override
public void run() {
@@ -266,7 +266,8 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment {
private void performBackup() {
Permissions.with(getActivity())
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) // READ_EXTERNAL_STORAGE required to read folder contents and to generate backup names
.alwaysGrantOnSdk30()
.ifNecessary()
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_storage_denied))
.onAllGranted(() -> {
@@ -40,7 +40,7 @@ class SearchListAdapter extends RecyclerView.Adapter<SearchListAdapter.Search
private SearchResult searchResult = SearchResult.EMPTY;
final Context context;
final DcContext dcContext;
final DcContext dcContext; // reset on account switching is not needed because SearchFragment and SearchListAdapter are recreated in every search start
SearchListAdapter(Context context,
@NonNull GlideRequests glideRequests,