Merge pull request #3869 from deltachat/adb/update-deps-6/8/25

remove some dependecies and upgrade others
This commit is contained in:
adb 2025-08-07 23:50:43 +02:00 committed by GitHub
commit e55249182a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 91 additions and 119 deletions

View file

@ -1,5 +1,5 @@
plugins {
id 'com.android.application' version '8.5.2'
id 'com.android.application' version '8.11.1'
id 'com.google.gms.google-services' version '4.4.1'
}
@ -149,9 +149,9 @@ android {
dependencies {
implementation 'androidx.sharetarget:sharetarget:1.2.0'
implementation 'androidx.webkit:webkit:1.12.1'
implementation 'androidx.webkit:webkit:1.14.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation ('androidx.preference:preference:1.2.1') {
@ -159,7 +159,7 @@ dependencies {
exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel-ktx'
}
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.3.7'
implementation 'androidx.exifinterface:exifinterface:1.4.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
@ -174,51 +174,47 @@ dependencies {
implementation ('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false } // QR Code scanner
implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.1' // used as JSON library
implementation 'com.google.code.gson:gson:2.12.1' // used as JSON library.
implementation "me.leolin:ShortcutBadger:1.1.16" // display messagecount on the home screen icon.
implementation 'com.jpardogo.materialtabstrip:library:1.0.9' // used in the emoji selector for the tab selection.
implementation 'com.github.Baseflow:PhotoView:2.3.0' // does the zooming on photos / media
implementation 'com.github.penfeizhou.android.animation:awebp:3.0.2' // animated webp support.
implementation 'com.github.penfeizhou.android.animation:awebp:3.0.5' // animated webp support.
implementation 'com.caverock:androidsvg-aar:1.4' // SVG support.
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
annotationProcessor 'androidx.annotation:annotation:1.9.1'
implementation 'com.makeramen:roundedimageview:2.1.0' // crops the avatars to circles
implementation 'com.pnikosis:materialish-progress:1.5' // used only in the "Progress Wheel" in Share Activity.
implementation 'com.makeramen:roundedimageview:2.3.0' // crops the avatars to circles
implementation 'com.github.amulyakhare:TextDrawable:558677ea31' // number of unread messages,
// the one-letter circle for the contacts (when there is not avatar) and a white background.
implementation 'com.googlecode.mp4parser:isoparser:1.0.6' // MP4 recoding; upgrading eg. to 1.1.22 breaks recoding, however, i have not investigated further, just reset to 1.0.6
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') { // for the zooming on photos / media
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.10.0') { // for the zooming on photos / media
exclude group: 'com.android.support', module: 'support-annotations'
}
implementation 'com.annimon:stream:1.1.8' // brings future java streams api to SDK Version < 24
// Replacement for ContentResolver
// that protects against the Surreptitious Sharing attack.
// <https://github.com/cketti/SafeContentResolver>
implementation 'de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0'
gplayImplementation('com.google.firebase:firebase-messaging:24.1.0') { // for PUSH notifications
gplayImplementation('com.google.firebase:firebase-messaging:24.1.2') { // for PUSH notifications, don't upgrade: v25.0.0 requires minSdk>=23
exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
}
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.assertj:assertj-core:1.7.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
testImplementation 'org.assertj:assertj-core:3.27.3'
testImplementation 'org.mockito:mockito-core:5.18.0'
testImplementation 'org.powermock:powermock-api-mockito:1.7.4'
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.9'
testImplementation 'org.powermock:powermock-classloading-xstream:2.0.9'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test:runner:1.7.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.7.0'
androidTestImplementation 'androidx.test:rules:1.7.0'
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
androidTestImplementation ('org.assertj:assertj-core:1.7.1') {
androidTestImplementation ('org.assertj:assertj-core:3.27.3') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
}

View file

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -35,7 +35,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amulyakhare.textdrawable.TextDrawable;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
@ -55,7 +54,6 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class ConversationListItem extends RelativeLayout
@ -318,15 +316,12 @@ public class ConversationListItem extends RelativeLayout
String normalizedValue = value.toLowerCase(Util.getLocale());
String normalizedTest = highlight.toLowerCase(Util.getLocale());
List<String> testTokens;
try (Stream<String> stream = Stream.of(normalizedTest.split(" "))) {
testTokens = stream.filter(s -> !s.trim().isEmpty()).toList();
}
Spannable spanned = new SpannableString(value);
int searchStartIndex = 0;
for (String token : testTokens) {
for (String token : normalizedTest.split(" ")) {
if (token.trim().isEmpty()) continue;
if (searchStartIndex >= spanned.length()) {
break;
}

View file

@ -16,7 +16,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.RpcException;
@ -194,18 +193,17 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
}
private void setQuoteAttachment(@NonNull GlideRequests glideRequests, @NonNull SlideDeck slideDeck) {
List<Slide> thumbnailSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker() || s.isWebxdcDocument() || s.isVcard()).limit(1).toList();
List<Slide> audioSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasAudio()).limit(1).toList();
List<Slide> documentSlides = Stream.of(attachments.getSlides()).filter(Slide::hasDocument).limit(1).toList();
List<Slide> slides = slideDeck.getSlides();
Slide slide = slides.isEmpty()? null : slides.get(0);
attachmentVideoOverlayView.setVisibility(GONE);
if (!thumbnailSlides.isEmpty() && thumbnailSlides.get(0).getUri() != null) {
if (slide != null && slide.hasQuoteThumbnail()) {
thumbnailView.setVisibility(VISIBLE);
attachmentContainerView.setVisibility(GONE);
dismissView.setBackgroundResource(R.drawable.dismiss_background);
if (thumbnailSlides.get(0).isWebxdcDocument()) {
if (slide.isWebxdcDocument()) {
try {
JSONObject info = quotedMsg.getWebxdcInfo();
byte[] blob = quotedMsg.getWebxdcBlob(info.getString("icon"));
@ -218,7 +216,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
Log.e(TAG, "failed to get webxdc icon", e);
thumbnailView.setVisibility(GONE);
}
} else if (thumbnailSlides.get(0).isVcard()) {
} else if (slide.isVcard()) {
try {
VcardContact vcardContact = DcHelper.getRpc(getContext()).parseVcard(quotedMsg.getFile()).get(0);
Recipient recipient = new Recipient(getContext(), vcardContact);
@ -233,11 +231,11 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
thumbnailView.setVisibility(GONE);
}
} else {
Uri thumbnailUri = thumbnailSlides.get(0).getUri();
if (thumbnailSlides.get(0).hasVideo()) {
Uri thumbnailUri = slide.getUri();
if (slide.hasVideo()) {
attachmentVideoOverlayView.setVisibility(VISIBLE);
MediaUtil.createVideoThumbnailIfNeeded(getContext(), thumbnailSlides.get(0).getUri(), thumbnailSlides.get(0).getThumbnailUri(), null);
thumbnailUri = thumbnailSlides.get(0).getThumbnailUri();
MediaUtil.createVideoThumbnailIfNeeded(getContext(), slide.getUri(), slide.getThumbnailUri(), null);
thumbnailUri = slide.getThumbnailUri();
}
glideRequests.load(new DecryptableUri(thumbnailUri))
.centerCrop()
@ -245,10 +243,10 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(thumbnailView);
}
} else if(!audioSlides.isEmpty()) {
} else if(slide != null && slide.hasAudio()) {
thumbnailView.setVisibility(GONE);
attachmentContainerView.setVisibility(GONE);
} else if (!documentSlides.isEmpty()) {
} else if (slide != null && slide.hasDocument()) {
thumbnailView.setVisibility(GONE);
attachmentContainerView.setVisibility(VISIBLE);
} else {

View file

@ -6,7 +6,6 @@ import android.content.Context;
import androidx.annotation.NonNull;
import androidx.loader.content.AsyncTaskLoader;
import com.annimon.stream.Stream;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
@ -128,28 +127,38 @@ public class BucketedThreadMediaLoader extends AsyncTaskLoader<BucketedThreadMed
}
public int getSectionCount() {
return (int)Stream.of(TIME_SECTIONS)
.filter(timeBucket -> !timeBucket.isEmpty())
.count() +
OLDER.getSectionCount();
int count = 0;
for (TimeBucket section : TIME_SECTIONS) {
if (!section.isEmpty()) count++;
}
return count + OLDER.getSectionCount();
}
public int getSectionItemCount(int section) {
List<TimeBucket> activeTimeBuckets = Stream.of(TIME_SECTIONS).filter(timeBucket -> !timeBucket.isEmpty()).toList();
List<TimeBucket> activeTimeBuckets = new ArrayList<>();
for (TimeBucket bucket : TIME_SECTIONS) {
if (!bucket.isEmpty()) activeTimeBuckets.add(bucket);
}
if (section < activeTimeBuckets.size()) return activeTimeBuckets.get(section).getItemCount();
else return OLDER.getSectionItemCount(section - activeTimeBuckets.size());
}
public DcMsg get(int section, int item) {
List<TimeBucket> activeTimeBuckets = Stream.of(TIME_SECTIONS).filter(timeBucket -> !timeBucket.isEmpty()).toList();
List<TimeBucket> activeTimeBuckets = new ArrayList<>();
for (TimeBucket bucket : TIME_SECTIONS) {
if (!bucket.isEmpty()) activeTimeBuckets.add(bucket);
}
if (section < activeTimeBuckets.size()) return activeTimeBuckets.get(section).getItem(item);
else return OLDER.getItem(section - activeTimeBuckets.size(), item);
}
public String getName(int section) {
List<TimeBucket> activeTimeBuckets = Stream.of(TIME_SECTIONS).filter(timeBucket -> !timeBucket.isEmpty()).toList();
List<TimeBucket> activeTimeBuckets = new ArrayList<>();
for (TimeBucket bucket : TIME_SECTIONS) {
if (!bucket.isEmpty()) activeTimeBuckets.add(bucket);
}
if (section < activeTimeBuckets.size()) return activeTimeBuckets.get(section).getName();
else return OLDER.getName(section - activeTimeBuckets.size());

View file

@ -76,6 +76,11 @@ public abstract class Slide {
return attachment.getSize();
}
/* Return true if this slide has a thumbnail when being quoted, false otherwise */
public boolean hasQuoteThumbnail() {
return (hasImage() || hasVideo() || hasSticker() || isWebxdcDocument() || isVcard()) && getUri() != null;
}
public boolean hasImage() {
return false;
}

View file

@ -21,15 +21,13 @@ import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.annimon.stream.Stream;
import com.annimon.stream.function.Consumer;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.LRUCache;
import org.thoughtcrime.securesms.util.ServiceUtil;
import java.lang.ref.WeakReference;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -70,10 +68,6 @@ public class Permissions {
private Runnable anyPermanentlyDeniedListener;
private Runnable anyResultListener;
private Consumer<List<String>> someGrantedListener;
private Consumer<List<String>> someDeniedListener;
private Consumer<List<String>> somePermanentlyDeniedListener;
private @DrawableRes int[] rationalDialogHeader;
private String rationaleDialogMessage;
@ -148,29 +142,13 @@ public class Permissions {
return this;
}
public PermissionsBuilder onSomeGranted(Consumer<List<String>> someGrantedListener) {
this.someGrantedListener = someGrantedListener;
return this;
}
public PermissionsBuilder onSomeDenied(Consumer<List<String>> someDeniedListener) {
this.someDeniedListener = someDeniedListener;
return this;
}
public PermissionsBuilder onSomePermanentlyDenied(Consumer<List<String>> somePermanentlyDeniedListener) {
this.somePermanentlyDeniedListener = somePermanentlyDeniedListener;
return this;
}
public void execute() {
if (alwaysGranted) {
allGrantedListener.run();
return;
}
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener,
someGrantedListener, someDeniedListener, somePermanentlyDeniedListener);
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener);
if (ifNecesary && (permissionObject.hasAll(requestedPermissions) || !condition)) {
executePreGrantedPermissionsRequest(request);
@ -183,7 +161,7 @@ public class Permissions {
private void executePreGrantedPermissionsRequest(PermissionsRequest request) {
int[] grantResults = new int[requestedPermissions.length];
for (int i=0;i<grantResults.length;i++) grantResults[i] = PackageManager.PERMISSION_GRANTED;
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
request.onResult(requestedPermissions, grantResults, new boolean[requestedPermissions.length]);
}
@ -218,7 +196,8 @@ public class Permissions {
}
String[] permissions = filterNotGranted(permissionObject.getContext(), requestedPermissions);
int[] grantResults = Stream.of(permissions).mapToInt(permission -> PackageManager.PERMISSION_DENIED).toArray();
int[] grantResults = new int[permissions.length];
Arrays.fill(grantResults, PackageManager.PERMISSION_DENIED);
boolean[] showDialog = new boolean[permissions.length];
Arrays.fill(showDialog, true);
@ -236,22 +215,29 @@ public class Permissions {
}
private static String[] filterNotGranted(@NonNull Context context, String... permissions) {
return Stream.of(permissions)
.filter(permission -> ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
.toList()
.toArray(new String[0]);
List<String> notGranted = new ArrayList<>();
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
notGranted.add(permission);
}
}
return notGranted.toArray(new String[0]);
}
public static boolean hasAny(@NonNull Context context, String... permissions) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
Stream.of(permissions).anyMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) return true;
}
return false;
}
public static boolean hasAll(@NonNull Context context, String... permissions) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
Stream.of(permissions).allMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) return false;
}
return true;
}
public static void onRequestPermissionsResult(Fragment fragment, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

View file

@ -5,8 +5,6 @@ import android.content.pm.PackageManager;
import androidx.annotation.Nullable;
import com.annimon.stream.function.Consumer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -22,27 +20,16 @@ class PermissionsRequest {
private final @Nullable Runnable anyPermanentlyDeniedListener;
private final @Nullable Runnable anyResultListener;
private final @Nullable Consumer<List<String>> someGrantedListener;
private final @Nullable Consumer<List<String>> someDeniedListener;
private final @Nullable Consumer<List<String>> somePermanentlyDeniedListener;
PermissionsRequest(@Nullable Runnable allGrantedListener,
@Nullable Runnable anyDeniedListener,
@Nullable Runnable anyPermanentlyDeniedListener,
@Nullable Runnable anyResultListener,
@Nullable Consumer<List<String>> someGrantedListener,
@Nullable Consumer<List<String>> someDeniedListener,
@Nullable Consumer<List<String>> somePermanentlyDeniedListener)
@Nullable Runnable anyResultListener)
{
this.allGrantedListener = allGrantedListener;
this.anyDeniedListener = anyDeniedListener;
this.anyPermanentlyDeniedListener = anyPermanentlyDeniedListener;
this.anyResultListener = anyResultListener;
this.someGrantedListener = someGrantedListener;
this.someDeniedListener = someDeniedListener;
this.somePermanentlyDeniedListener = somePermanentlyDeniedListener;
}
void onResult(String[] permissions, int[] grantResults, boolean[] shouldShowRationaleDialog) {
@ -56,9 +43,9 @@ class PermissionsRequest {
} else {
boolean preRequestShouldShowRationaleDialog = PRE_REQUEST_MAPPING.get(permissions[i]);
if ((somePermanentlyDeniedListener != null || anyPermanentlyDeniedListener != null) &&
!preRequestShouldShowRationaleDialog && !shouldShowRationaleDialog[i])
{
if (anyPermanentlyDeniedListener != null
&& !preRequestShouldShowRationaleDialog
&& !shouldShowRationaleDialog[i]) {
permanentlyDenied.add(permissions[i]);
} else {
denied.add(permissions[i]);
@ -68,18 +55,14 @@ class PermissionsRequest {
if (allGrantedListener != null && !granted.isEmpty() && (denied.isEmpty() && permanentlyDenied.isEmpty())) {
allGrantedListener.run();
} else if (someGrantedListener != null && !granted.isEmpty()) {
someGrantedListener.accept(granted);
}
if (!denied.isEmpty()) {
if (anyDeniedListener != null) anyDeniedListener.run();
if (someDeniedListener != null) someDeniedListener.accept(denied);
}
if (!permanentlyDenied.isEmpty()) {
if (anyPermanentlyDeniedListener != null) anyPermanentlyDeniedListener.run();
if (somePermanentlyDeniedListener != null) somePermanentlyDeniedListener.accept(permanentlyDenied);
}
if (anyResultListener != null) {

View file

@ -33,10 +33,10 @@
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<com.pnikosis.materialishprogress.ProgressWheel android:id="@+id/progress_wheel"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
wheel:matProg_progressIndeterminate="true"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="20sp"
android:text="@string/one_moment" />
</RelativeLayout>