Merge remote-tracking branch 'origin/dev' into release/1.19.1

# Conflicts:
#	app/build.gradle
#	app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt
#	app/src/main/java/org/thoughtcrime/securesms/components/AvatarImageView.java
#	gradle.properties
This commit is contained in:
fanchao 2024-08-14 10:47:16 +10:00
commit 50929b8970
108 changed files with 875 additions and 1321 deletions

View File

@ -10,22 +10,19 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
classpath "com.google.gms:google-services:$googleServicesVersion" classpath "com.google.gms:google-services:$googleServicesVersion"
classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion"
} }
} }
plugins { plugins {
id 'kotlin-kapt' id 'com.google.devtools.ksp'
id 'com.google.dagger.hilt.android' id 'com.google.dagger.hilt.android'
} }
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'witness' apply plugin: 'witness'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlinx-serialization' apply plugin: 'kotlinx-serialization'
apply plugin: 'dagger.hilt.android.plugin'
configurations.all { configurations.all {
exclude module: "commons-logging" exclude module: "commons-logging"
@ -89,7 +86,7 @@ android {
compose true compose true
} }
composeOptions { composeOptions {
kotlinCompilerExtensionVersion '1.4.7' kotlinCompilerExtensionVersion '1.5.14'
} }
defaultConfig { defaultConfig {
@ -239,8 +236,9 @@ android {
dependencies { dependencies {
implementation("com.google.dagger:hilt-android:2.46.1") implementation("com.google.dagger:hilt-android:$daggerHiltVersion")
kapt("com.google.dagger:hilt-android-compiler:2.44") ksp("com.google.dagger:hilt-compiler:$daggerHiltVersion")
ksp("androidx.hilt:hilt-compiler:$jetpackHiltVersion")
implementation "androidx.appcompat:appcompat:$appcompatVersion" implementation "androidx.appcompat:appcompat:$appcompatVersion"
implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.2.1'
@ -281,8 +279,7 @@ dependencies {
implementation 'commons-net:commons-net:3.7.2' implementation 'commons-net:commons-net:3.7.2'
implementation 'com.github.chrisbanes:PhotoView:2.1.3' implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation "com.github.bumptech.glide:glide:$glideVersion" implementation "com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" ksp "com.github.bumptech.glide:ksp:$glideVersion"
kapt "com.github.bumptech.glide:compiler:$glideVersion"
implementation 'com.makeramen:roundedimageview:2.1.0' implementation 'com.makeramen:roundedimageview:2.1.0'
implementation 'com.pnikosis:materialish-progress:1.5' implementation 'com.pnikosis:materialish-progress:1.5'
implementation 'org.greenrobot:eventbus:3.0.0' implementation 'org.greenrobot:eventbus:3.0.0'
@ -290,8 +287,6 @@ dependencies {
implementation 'com.vanniktech:android-image-cropper:4.5.0' implementation 'com.vanniktech:android-image-cropper:4.5.0'
implementation 'com.melnykov:floatingactionbutton:1.3.0' implementation 'com.melnykov:floatingactionbutton:1.3.0'
implementation 'com.google.zxing:android-integration:3.1.0' implementation 'com.google.zxing:android-integration:3.1.0'
implementation "com.google.dagger:hilt-android:$daggerVersion"
kapt "com.google.dagger:hilt-compiler:$daggerVersion"
implementation 'com.google.zxing:core:3.2.1' implementation 'com.google.zxing:core:3.2.1'
implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') { implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.6.0') {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
@ -410,8 +405,3 @@ def autoResConfig() {
.collect { matcher -> matcher.group(1) } .collect { matcher -> matcher.group(1) }
.sort() .sort()
} }
// Allow references to generated code
kapt {
correctErrorTypes = true
}

View File

@ -40,7 +40,7 @@ import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBar import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBar
import org.thoughtcrime.securesms.home.HomeActivity import org.thoughtcrime.securesms.home.HomeActivity
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@LargeTest @LargeTest
@ -71,7 +71,7 @@ class HomeActivityTests {
onView(allOf(isDescendantOfA(withId(R.id.inputBar)),withId(R.id.inputBarEditText))).perform(ViewActions.replaceText(messageToSend)) onView(allOf(isDescendantOfA(withId(R.id.inputBar)),withId(R.id.inputBarEditText))).perform(ViewActions.replaceText(messageToSend))
if (linkPreview != null) { if (linkPreview != null) {
val activity = activityMonitor.waitForActivity() as ConversationActivityV2 val activity = activityMonitor.waitForActivity() as ConversationActivityV2
val glide = GlideApp.with(activity) val glide = Glide.with(activity)
activity.findViewById<InputBar>(R.id.inputBar).updateLinkPreviewDraft(glide, linkPreview) activity.findViewById<InputBar>(R.id.inputBar).updateLinkPreviewDraft(glide, linkPreview)
} }
onView(allOf(isDescendantOfA(withId(R.id.inputBar)),inputButtonWithDrawable(R.drawable.ic_arrow_up))).perform(ViewActions.click()) onView(allOf(isDescendantOfA(withId(R.id.inputBar)),inputButtonWithDrawable(R.drawable.ic_arrow_up))).perform(ViewActions.click())

View File

@ -328,7 +328,6 @@
<action android:name="android.service.chooser.ChooserTargetService" /> <action android:name="android.service.chooser.ChooserTargetService" />
</intent-filter> </intent-filter>
</service> </service>
<service android:name="org.thoughtcrime.securesms.service.GenericForegroundService" />
<receiver <receiver
android:name="org.thoughtcrime.securesms.notifications.MarkReadReceiver" android:name="org.thoughtcrime.securesms.notifications.MarkReadReceiver"
android:enabled="true" android:enabled="true"
@ -440,9 +439,7 @@
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service
android:name="org.thoughtcrime.securesms.jobmanager.KeepAliveService"
android:enabled="@bool/enable_alarm_manager" />
<uses-library <uses-library
android:name="com.sec.android.app.multiwindow" android:name="com.sec.android.app.multiwindow"
android:required="false" /> android:required="false" />

View File

@ -29,7 +29,7 @@ import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord; import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia; import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.MediaUtil;
@ -46,7 +46,7 @@ class MediaGalleryAdapter extends StickyHeaderGridAdapter {
private static final String TAG = MediaGalleryAdapter.class.getSimpleName(); private static final String TAG = MediaGalleryAdapter.class.getSimpleName();
private final Context context; private final Context context;
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final Locale locale; private final Locale locale;
private final ItemClickListener itemClickListener; private final ItemClickListener itemClickListener;
private final Set<MediaRecord> selected; private final Set<MediaRecord> selected;
@ -74,7 +74,7 @@ class MediaGalleryAdapter extends StickyHeaderGridAdapter {
} }
MediaGalleryAdapter(@NonNull Context context, MediaGalleryAdapter(@NonNull Context context,
@NonNull GlideRequests glideRequests, @NonNull RequestManager glideRequests,
BucketedThreadMedia media, BucketedThreadMedia media,
Locale locale, Locale locale,
ItemClickListener clickListener) ItemClickListener clickListener)

View File

@ -61,7 +61,7 @@ import org.thoughtcrime.securesms.database.MediaDatabase;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader; import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader;
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia; import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader; import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.permissions.Permissions;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.util.AttachmentUtil; import org.thoughtcrime.securesms.util.AttachmentUtil;
@ -227,7 +227,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
this.gridManager = new StickyHeaderGridLayoutManager(getResources().getInteger(R.integer.media_overview_cols)); this.gridManager = new StickyHeaderGridLayoutManager(getResources().getInteger(R.integer.media_overview_cols));
this.recyclerView.setAdapter(new MediaGalleryAdapter(getContext(), this.recyclerView.setAdapter(new MediaGalleryAdapter(getContext(),
GlideApp.with(this), Glide.with(this),
new BucketedThreadMedia(getContext()), new BucketedThreadMedia(getContext()),
locale, locale,
this)); this));

View File

@ -72,8 +72,8 @@ import org.thoughtcrime.securesms.database.loaders.PagingMediaLoader;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.mediapreview.MediaPreviewViewModel; import org.thoughtcrime.securesms.mediapreview.MediaPreviewViewModel;
import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter; import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.AttachmentUtil; import org.thoughtcrime.securesms.util.AttachmentUtil;
@ -281,7 +281,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
mediaPager.setOffscreenPageLimit(1); mediaPager.setOffscreenPageLimit(1);
albumRail = findViewById(R.id.media_preview_album_rail); albumRail = findViewById(R.id.media_preview_album_rail);
albumRailAdapter = new MediaRailAdapter(GlideApp.with(this), this, false); albumRailAdapter = new MediaRailAdapter(Glide.with(this), this, false);
albumRail.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)); albumRail.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
albumRail.setAdapter(albumRailAdapter); albumRail.setAdapter(albumRailAdapter);
@ -370,7 +370,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
if (conversationRecipient != null) { if (conversationRecipient != null) {
getSupportLoaderManager().restartLoader(0, null, this); getSupportLoaderManager().restartLoader(0, null, this);
} else { } else {
adapter = new SingleItemPagerAdapter(this, GlideApp.with(this), getWindow(), initialMediaUri, initialMediaType, initialMediaSize); adapter = new SingleItemPagerAdapter(this, Glide.with(this), getWindow(), initialMediaUri, initialMediaType, initialMediaSize);
mediaPager.setAdapter(adapter); mediaPager.setAdapter(adapter);
if (initialCaption != null) { if (initialCaption != null) {
@ -518,7 +518,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
mediaPager.removeOnPageChangeListener(viewPagerListener); mediaPager.removeOnPageChangeListener(viewPagerListener);
adapter = new CursorPagerAdapter(this, GlideApp.with(this), getWindow(), data.first, data.second, leftIsRecent); adapter = new CursorPagerAdapter(this, Glide.with(this), getWindow(), data.first, data.second, leftIsRecent);
mediaPager.setAdapter(adapter); mediaPager.setAdapter(adapter);
viewModel.setCursor(this, data.first, leftIsRecent); viewModel.setCursor(this, data.first, leftIsRecent);
@ -588,7 +588,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
private static class SingleItemPagerAdapter extends MediaItemAdapter { private static class SingleItemPagerAdapter extends MediaItemAdapter {
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final Window window; private final Window window;
private final Uri uri; private final Uri uri;
private final String mediaType; private final String mediaType;
@ -596,7 +596,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
private final LayoutInflater inflater; private final LayoutInflater inflater;
SingleItemPagerAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, SingleItemPagerAdapter(@NonNull Context context, @NonNull RequestManager glideRequests,
@NonNull Window window, @NonNull Uri uri, @NonNull String mediaType, @NonNull Window window, @NonNull Uri uri, @NonNull String mediaType,
long size) long size)
{ {
@ -663,14 +663,14 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
private final WeakHashMap<Integer, MediaView> mediaViews = new WeakHashMap<>(); private final WeakHashMap<Integer, MediaView> mediaViews = new WeakHashMap<>();
private final Context context; private final Context context;
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final Window window; private final Window window;
private final Cursor cursor; private final Cursor cursor;
private final boolean leftIsRecent; private final boolean leftIsRecent;
private int autoPlayPosition; private int autoPlayPosition;
CursorPagerAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, CursorPagerAdapter(@NonNull Context context, @NonNull RequestManager glideRequests,
@NonNull Window window, @NonNull Cursor cursor, int autoPlayPosition, @NonNull Window window, @NonNull Cursor cursor, int autoPlayPosition,
boolean leftIsRecent) boolean leftIsRecent)
{ {

View File

@ -34,7 +34,7 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
private BroadcastReceiver clearKeyReceiver; private BroadcastReceiver clearKeyReceiver;
@Override @Override
protected final void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate(" + savedInstanceState + ")"); Log.i(TAG, "onCreate(" + savedInstanceState + ")");
onPreCreate(); onPreCreate();

View File

@ -13,7 +13,7 @@ import android.view.Window;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.VideoSlide; import org.thoughtcrime.securesms.mms.VideoSlide;
import org.thoughtcrime.securesms.video.VideoPlayer; import org.thoughtcrime.securesms.video.VideoPlayer;
@ -54,7 +54,7 @@ public class MediaView extends FrameLayout {
this.videoView = new Stub<>(findViewById(R.id.video_player_stub)); this.videoView = new Stub<>(findViewById(R.id.video_player_stub));
} }
public void set(@NonNull GlideRequests glideRequests, public void set(@NonNull RequestManager glideRequests,
@NonNull Window window, @NonNull Window window,
@NonNull Uri source, @NonNull Uri source,
@NonNull String mediaType, @NonNull String mediaType,

View File

@ -20,8 +20,8 @@ import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
class ProfilePictureView @JvmOverloads constructor( class ProfilePictureView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null context: Context, attrs: AttributeSet? = null
@ -29,7 +29,7 @@ class ProfilePictureView @JvmOverloads constructor(
private val TAG = "ProfilePictureView" private val TAG = "ProfilePictureView"
private val binding = ViewProfilePictureBinding.inflate(LayoutInflater.from(context), this) private val binding = ViewProfilePictureBinding.inflate(LayoutInflater.from(context), this)
private val glide: GlideRequests = GlideApp.with(this) private val glide: RequestManager = Glide.with(this)
private val prefs = AppTextSecurePreferences(context) private val prefs = AppTextSecurePreferences(context)
private val userPublicKey = prefs.getLocalNumber() private val userPublicKey = prefs.getLocalNumber()
var publicKey: String? = null var publicKey: String? = null

View File

@ -28,7 +28,7 @@ import com.bumptech.glide.signature.MediaStoreSignature;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter; import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
import org.thoughtcrime.securesms.database.loaders.RecentPhotosLoader; import org.thoughtcrime.securesms.database.loaders.RecentPhotosLoader;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.session.libsession.utilities.ViewUtil; import org.session.libsession.utilities.ViewUtil;
@ -118,7 +118,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
Key signature = new MediaStoreSignature(mimeType, dateModified, orientation); Key signature = new MediaStoreSignature(mimeType, dateModified, orientation);
GlideApp.with(getContext().getApplicationContext()) Glide.with(getContext().getApplicationContext())
.load(uri) .load(uri)
.signature(signature) .signature(signature)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)

View File

@ -8,7 +8,7 @@ import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideClickListener; import org.thoughtcrime.securesms.mms.SlideClickListener;

View File

@ -25,7 +25,7 @@ import network.loki.messenger.R;
import org.thoughtcrime.securesms.components.subsampling.AttachmentBitmapDecoder; import org.thoughtcrime.securesms.components.subsampling.AttachmentBitmapDecoder;
import org.thoughtcrime.securesms.components.subsampling.AttachmentRegionDecoder; import org.thoughtcrime.securesms.components.subsampling.AttachmentRegionDecoder;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.util.BitmapDecodingException; import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.BitmapUtil;
@ -62,7 +62,7 @@ public class ZoomingImageView extends FrameLayout {
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
public void setImageUri(@NonNull GlideRequests glideRequests, @NonNull Uri uri, @NonNull String contentType) public void setImageUri(@NonNull RequestManager glideRequests, @NonNull Uri uri, @NonNull String contentType)
{ {
final Context context = getContext(); final Context context = getContext();
final int maxTextureSize = BitmapUtil.getMaxTextureSize(); final int maxTextureSize = BitmapUtil.getMaxTextureSize();
@ -97,7 +97,7 @@ public class ZoomingImageView extends FrameLayout {
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
private void setImageViewUri(@NonNull GlideRequests glideRequests, @NonNull Uri uri) { private void setImageViewUri(@NonNull RequestManager glideRequests, @NonNull Uri uri) {
photoView.setVisibility(View.VISIBLE); photoView.setVisibility(View.VISIBLE);
subsamplingImageView.setVisibility(View.GONE); subsamplingImageView.setVisibility(View.GONE);

View File

@ -12,7 +12,7 @@ import android.widget.ImageView;
import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.VariationSelectorListener; import org.thoughtcrime.securesms.components.emoji.EmojiPageViewGridAdapter.VariationSelectorListener;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.util.ResUtil; import org.thoughtcrime.securesms.util.ResUtil;
import org.session.libsession.utilities.ThemeUtil; import org.session.libsession.utilities.ThemeUtil;
@ -87,7 +87,7 @@ public class EmojiKeyboardProvider implements MediaKeyboardProvider,
} }
@Override @Override
public void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index) { public void loadCategoryTabIcon(@NonNull RequestManager glideRequests, @NonNull ImageView imageView, int index) {
Drawable drawable = ResUtil.getDrawable(context, models.get(index).getIconAttr()); Drawable drawable = ResUtil.getDrawable(context, models.get(index).getIconAttr());
imageView.setImageDrawable(drawable); imageView.setImageDrawable(drawable);
} }

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.components.emoji; package org.thoughtcrime.securesms.components.emoji;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
@ -8,6 +9,8 @@ import android.widget.PopupWindow;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.session.libsession.utilities.ThemeUtil;
import java.util.List; import java.util.List;
import network.loki.messenger.R; import network.loki.messenger.R;
@ -26,7 +29,9 @@ public class EmojiVariationSelectorPopup extends PopupWindow {
this.listener = listener; this.listener = listener;
this.list = (ViewGroup) getContentView(); this.list = (ViewGroup) getContentView();
setBackgroundDrawable(null); setBackgroundDrawable(
new ColorDrawable(ThemeUtil.getThemedColor(context, R.attr.colorPrimary))
);
setOutsideTouchable(true); setOutsideTouchable(true);
} }

View File

@ -17,7 +17,7 @@ import android.widget.FrameLayout;
import org.thoughtcrime.securesms.components.InputAwareLayout.InputView; import org.thoughtcrime.securesms.components.InputAwareLayout.InputView;
import org.thoughtcrime.securesms.components.RepeatableImageKey; import org.thoughtcrime.securesms.components.RepeatableImageKey;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import java.util.Arrays; import java.util.Arrays;
@ -158,7 +158,7 @@ public class MediaKeyboard extends FrameLayout implements InputView,
this.searchButton = view.findViewById(R.id.media_keyboard_search); this.searchButton = view.findViewById(R.id.media_keyboard_search);
this.addButton = view.findViewById(R.id.media_keyboard_add); this.addButton = view.findViewById(R.id.media_keyboard_add);
this.categoryTabAdapter = new MediaKeyboardBottomTabAdapter(GlideApp.with(this), this); this.categoryTabAdapter = new MediaKeyboardBottomTabAdapter(Glide.with(this), this);
categoryTabs.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false)); categoryTabs.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
categoryTabs.setAdapter(categoryTabAdapter); categoryTabs.setAdapter(categoryTabAdapter);

View File

@ -9,20 +9,20 @@ import android.widget.ImageView;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboardProvider.TabIconProvider; import org.thoughtcrime.securesms.components.emoji.MediaKeyboardProvider.TabIconProvider;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import network.loki.messenger.R; import network.loki.messenger.R;
public class MediaKeyboardBottomTabAdapter extends RecyclerView.Adapter<MediaKeyboardBottomTabAdapter.MediaKeyboardBottomTabViewHolder> { public class MediaKeyboardBottomTabAdapter extends RecyclerView.Adapter<MediaKeyboardBottomTabAdapter.MediaKeyboardBottomTabViewHolder> {
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final EventListener eventListener; private final EventListener eventListener;
private TabIconProvider tabIconProvider; private TabIconProvider tabIconProvider;
private int activePosition; private int activePosition;
private int count; private int count;
public MediaKeyboardBottomTabAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) { public MediaKeyboardBottomTabAdapter(@NonNull RequestManager glideRequests, @NonNull EventListener eventListener) {
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.eventListener = eventListener; this.eventListener = eventListener;
} }
@ -71,7 +71,7 @@ public class MediaKeyboardBottomTabAdapter extends RecyclerView.Adapter<MediaKey
this.indicator = itemView.findViewById(R.id.media_keyboard_bottom_tab_indicator); this.indicator = itemView.findViewById(R.id.media_keyboard_bottom_tab_indicator);
} }
void bind(@NonNull GlideRequests glideRequests, void bind(@NonNull RequestManager glideRequests,
@NonNull EventListener eventListener, @NonNull EventListener eventListener,
@NonNull TabIconProvider tabIconProvider, @NonNull TabIconProvider tabIconProvider,
int index, int index,

View File

@ -8,7 +8,7 @@ import android.widget.ImageView;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
public interface MediaKeyboardProvider { public interface MediaKeyboardProvider {
@LayoutRes int getProviderIconView(boolean selected); @LayoutRes int getProviderIconView(boolean selected);
@ -48,6 +48,6 @@ public interface MediaKeyboardProvider {
} }
interface TabIconProvider { interface TabIconProvider {
void loadCategoryTabIcon(@NonNull GlideRequests glideRequests, @NonNull ImageView imageView, int index); void loadCategoryTabIcon(@NonNull RequestManager glideRequests, @NonNull ImageView imageView, int index);
} }
} }

View File

@ -6,10 +6,10 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import network.loki.messenger.databinding.ContactSelectionListDividerBinding import network.loki.messenger.databinding.ContactSelectionListDividerBinding
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
class ContactSelectionListAdapter(private val context: Context, private val multiSelect: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { class ContactSelectionListAdapter(private val context: Context, private val multiSelect: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
lateinit var glide: GlideRequests lateinit var glide: RequestManager
val selectedContacts = mutableSetOf<Recipient>() val selectedContacts = mutableSetOf<Recipient>()
var items = listOf<ContactSelectionListItem>() var items = listOf<ContactSelectionListItem>()
set(value) { field = value; notifyDataSetChanged() } set(value) { field = value; notifyDataSetChanged() }

View File

@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import network.loki.messenger.databinding.ContactSelectionListFragmentBinding import network.loki.messenger.databinding.ContactSelectionListFragmentBinding
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
class ContactSelectionListFragment : Fragment(), LoaderManager.LoaderCallbacks<List<ContactSelectionListItem>>, ContactClickListener { class ContactSelectionListFragment : Fragment(), LoaderManager.LoaderCallbacks<List<ContactSelectionListItem>>, ContactClickListener {
private lateinit var binding: ContactSelectionListFragmentBinding private lateinit var binding: ContactSelectionListFragmentBinding
@ -27,7 +27,7 @@ class ContactSelectionListFragment : Fragment(), LoaderManager.LoaderCallbacks<L
private val listAdapter by lazy { private val listAdapter by lazy {
val result = ContactSelectionListAdapter(requireActivity(), multiSelect) val result = ContactSelectionListAdapter(requireActivity(), multiSelect)
result.glide = GlideApp.with(this) result.glide = Glide.with(this)
result.contactClickListener = this result.contactClickListener = this
result result
} }

View File

@ -12,7 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.ActivitySelectContactsBinding import network.loki.messenger.databinding.ActivitySelectContactsBinding
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
class SelectContactsActivity : PassphraseRequiredActionBarActivity(), LoaderManager.LoaderCallbacks<List<String>> { class SelectContactsActivity : PassphraseRequiredActionBarActivity(), LoaderManager.LoaderCallbacks<List<String>> {
private lateinit var binding: ActivitySelectContactsBinding private lateinit var binding: ActivitySelectContactsBinding
@ -21,7 +21,7 @@ class SelectContactsActivity : PassphraseRequiredActionBarActivity(), LoaderMana
private lateinit var usersToExclude: Set<String> private lateinit var usersToExclude: Set<String>
private val selectContactsAdapter by lazy { private val selectContactsAdapter by lazy {
SelectContactsAdapter(this, GlideApp.with(this)) SelectContactsAdapter(this, Glide.with(this))
} }
companion object { companion object {

View File

@ -4,10 +4,10 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup import android.view.ViewGroup
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
class SelectContactsAdapter(private val context: Context, private val glide: GlideRequests) : RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() { class SelectContactsAdapter(private val context: Context, private val glide: RequestManager) : RecyclerView.Adapter<SelectContactsAdapter.ViewHolder>() {
val selectedMembers = mutableSetOf<String>() val selectedMembers = mutableSetOf<String>()
var members = listOf<String>() var members = listOf<String>()
set(value) { field = value; notifyDataSetChanged() } set(value) { field = value; notifyDataSetChanged() }

View File

@ -10,7 +10,7 @@ import network.loki.messenger.databinding.ViewUserBinding
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
class UserView : LinearLayout { class UserView : LinearLayout {
private lateinit var binding: ViewUserBinding private lateinit var binding: ViewUserBinding
@ -45,7 +45,7 @@ class UserView : LinearLayout {
// endregion // endregion
// region Updating // region Updating
fun bind(user: Recipient, glide: GlideRequests, actionIndicator: ActionIndicator, isSelected: Boolean = false) { fun bind(user: Recipient, glide: RequestManager, actionIndicator: ActionIndicator, isSelected: Boolean = false) {
val isLocalUser = user.isLocalNumber val isLocalUser = user.isLocalNumber
fun getUserDisplayName(publicKey: String): String { fun getUserDisplayName(publicKey: String): String {
if (isLocalUser) return context.getString(R.string.MessageRecord_you) if (isLocalUser) return context.getString(R.string.MessageRecord_you)

View File

@ -155,7 +155,7 @@ import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.mediasend.MediaSendActivity import org.thoughtcrime.securesms.mediasend.MediaSendActivity
import org.thoughtcrime.securesms.mms.AudioSlide import org.thoughtcrime.securesms.mms.AudioSlide
import org.thoughtcrime.securesms.mms.GifSlide import org.thoughtcrime.securesms.mms.GifSlide
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.ImageSlide
import org.thoughtcrime.securesms.mms.MediaConstraints import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.mms.Slide
@ -347,7 +347,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
adapter adapter
} }
private val glide by lazy { GlideApp.with(this) } private val glide by lazy { Glide.with(this) }
private val lockViewHitMargin by lazy { toPx(40, resources) } private val lockViewHitMargin by lazy { toPx(40, resources) }
private val gifButton by lazy { InputBarButton(this, R.drawable.ic_gif_white_24dp, hasOpaqueBackground = true, isGIFButton = true) } private val gifButton by lazy { InputBarButton(this, R.drawable.ic_gif_white_24dp, hasOpaqueBackground = true, isGIFButton = true) }
private val documentButton by lazy { InputBarButton(this, R.drawable.ic_document_small_dark, hasOpaqueBackground = true) } private val documentButton by lazy { InputBarButton(this, R.drawable.ic_document_small_dark, hasOpaqueBackground = true) }

View File

@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageViewDel
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity import org.thoughtcrime.securesms.preferences.PrivacySettingsActivity
import org.thoughtcrime.securesms.showSessionDialog import org.thoughtcrime.securesms.showSessionDialog
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
@ -42,7 +42,7 @@ class ConversationAdapter(
private val onItemLongPress: (MessageRecord, Int, VisibleMessageView) -> Unit, private val onItemLongPress: (MessageRecord, Int, VisibleMessageView) -> Unit,
private val onDeselect: (MessageRecord, Int) -> Unit, private val onDeselect: (MessageRecord, Int) -> Unit,
private val onAttachmentNeedsDownload: (DatabaseAttachment) -> Unit, private val onAttachmentNeedsDownload: (DatabaseAttachment) -> Unit,
private val glide: GlideRequests, private val glide: RequestManager,
lifecycleCoroutineScope: LifecycleCoroutineScope lifecycleCoroutineScope: LifecycleCoroutineScope
) : CursorRecyclerViewAdapter<ViewHolder>(context, cursor) { ) : CursorRecyclerViewAdapter<ViewHolder>(context, cursor) {
private val messageDB by lazy { DatabaseComponent.get(context).mmsSmsDatabase() } private val messageDB by lazy { DatabaseComponent.get(context).mmsSmsDatabase() }

View File

@ -261,7 +261,13 @@ class ConversationViewModel(
_recipient.updateTo(repository.maybeGetRecipientForThreadId(threadId)) _recipient.updateTo(repository.maybeGetRecipientForThreadId(threadId))
} }
fun hidesInputBar(): Boolean = openGroup?.canWrite != true && /**
* The input should be hidden when:
* - We are in a community without write access
* - We are dealing with a contact from a community (blinded recipient) that does not allow
* requests form community members
*/
fun hidesInputBar(): Boolean = openGroup?.canWrite == false ||
blindedRecipient?.blocksCommunityMessageRequests == true blindedRecipient?.blocksCommunityMessageRequests == true
fun legacyBannerRecipient(context: Context): Recipient? = recipient?.run { fun legacyBannerRecipient(context: Context): Recipient? = recipient?.run {

View File

@ -33,18 +33,16 @@ import android.view.View
import com.annimon.stream.Stream import com.annimon.stream.Stream
import com.google.android.mms.pdu_alt.CharacterSets import com.google.android.mms.pdu_alt.CharacterSets
import com.google.android.mms.pdu_alt.EncodedStringValue import com.google.android.mms.pdu_alt.EncodedStringValue
import network.loki.messenger.R
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.components.ComposeText
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
import java.io.UnsupportedEncodingException import java.io.UnsupportedEncodingException
import java.security.SecureRandom
import java.util.Arrays
import java.util.Collections import java.util.Collections
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import network.loki.messenger.R
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.components.ComposeText
object Util { object Util {
private val TAG: String = Log.tag(Util::class.java) private val TAG: String = Log.tag(Util::class.java)
@ -248,32 +246,6 @@ object Util {
return result return result
} }
fun getSecretBytes(size: Int): ByteArray {
return getSecretBytes(SecureRandom(), size)
}
fun getSecretBytes(secureRandom: SecureRandom, size: Int): ByteArray {
val secret = ByteArray(size)
secureRandom.nextBytes(secret)
return secret
}
fun <T> getRandomElement(elements: Array<T>): T {
return elements[SecureRandom().nextInt(elements.size)]
}
fun <T> getRandomElement(elements: List<T>): T {
return elements[SecureRandom().nextInt(elements.size)]
}
fun equals(a: Any?, b: Any?): Boolean {
return a === b || (a != null && a == b)
}
fun hashCode(vararg objects: Any?): Int {
return objects.contentHashCode()
}
fun uri(uri: String?): Uri? { fun uri(uri: String?): Uri? {
return if (uri == null) null return if (uri == null) null
else Uri.parse(uri) else Uri.parse(uri)

View File

@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.MediaPreviewActivity
import org.thoughtcrime.securesms.components.CornerMask import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.util.ActivityDispatcher import org.thoughtcrime.securesms.util.ActivityDispatcher
@ -80,7 +80,7 @@ class AlbumThumbnailView : RelativeLayout {
slideSize = -1 slideSize = -1
} }
fun bind(glideRequests: GlideRequests, message: MmsMessageRecord, fun bind(glideRequests: RequestManager, message: MmsMessageRecord,
isStart: Boolean, isEnd: Boolean) { isStart: Boolean, isEnd: Boolean) {
slides = message.slideDeck.thumbnailSlides slides = message.slideDeck.thumbnailSlides
if (slides.isEmpty()) { if (slides.isEmpty()) {

View File

@ -7,7 +7,7 @@ import android.widget.LinearLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import network.loki.messenger.databinding.ViewLinkPreviewDraftBinding import network.loki.messenger.databinding.ViewLinkPreviewDraftBinding
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.ImageSlide
import org.thoughtcrime.securesms.util.toPx import org.thoughtcrime.securesms.util.toPx
@ -27,7 +27,7 @@ class LinkPreviewDraftView : LinearLayout {
binding.linkPreviewDraftCancelButton.setOnClickListener { cancel() } binding.linkPreviewDraftCancelButton.setOnClickListener { cancel() }
} }
fun update(glide: GlideRequests, linkPreview: LinkPreview) { fun update(glide: RequestManager, linkPreview: LinkPreview) {
// Hide the loader and show the content view // Hide the loader and show the content view
binding.linkPreviewDraftContainer.isVisible = true binding.linkPreviewDraftContainer.isVisible = true
binding.linkPreviewDraftLoader.isVisible = false binding.linkPreviewDraftLoader.isVisible = false

View File

@ -9,13 +9,13 @@ import android.widget.BaseAdapter
import android.widget.ListView import android.widget.ListView
import org.session.libsession.messaging.mentions.Mention import org.session.libsession.messaging.mentions.Mention
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.util.toPx import org.thoughtcrime.securesms.util.toPx
class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) {
private var mentionCandidates = listOf<Mention>() private var mentionCandidates = listOf<Mention>()
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.mentionCandidates = newValue } set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.mentionCandidates = newValue }
var glide: GlideRequests? = null var glide: RequestManager? = null
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.glide = newValue } set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.glide = newValue }
var openGroupServer: String? = null var openGroupServer: String? = null
set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.openGroupServer = openGroupServer } set(newValue) { field = newValue; mentionCandidateSelectionViewAdapter.openGroupServer = openGroupServer }
@ -28,7 +28,7 @@ class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defS
private class Adapter(private val context: Context) : BaseAdapter() { private class Adapter(private val context: Context) : BaseAdapter() {
var mentionCandidates = listOf<Mention>() var mentionCandidates = listOf<Mention>()
set(newValue) { field = newValue; notifyDataSetChanged() } set(newValue) { field = newValue; notifyDataSetChanged() }
var glide: GlideRequests? = null var glide: RequestManager? = null
var openGroupServer: String? = null var openGroupServer: String? = null
var openGroupRoom: String? = null var openGroupRoom: String? = null

View File

@ -8,13 +8,13 @@ import android.widget.LinearLayout
import network.loki.messenger.databinding.ViewMentionCandidateBinding import network.loki.messenger.databinding.ViewMentionCandidateBinding
import org.session.libsession.messaging.mentions.Mention import org.session.libsession.messaging.mentions.Mention
import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
class MentionCandidateView : LinearLayout { class MentionCandidateView : LinearLayout {
private lateinit var binding: ViewMentionCandidateBinding private lateinit var binding: ViewMentionCandidateBinding
var mentionCandidate = Mention("", "") var mentionCandidate = Mention("", "")
set(newValue) { field = newValue; update() } set(newValue) { field = newValue; update() }
var glide: GlideRequests? = null var glide: RequestManager? = null
var openGroupServer: String? = null var openGroupServer: String? = null
var openGroupRoom: String? = null var openGroupRoom: String? = null

View File

@ -27,7 +27,7 @@ import org.thoughtcrime.securesms.conversation.v2.messages.QuoteView
import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.util.addTextChangedListener import org.thoughtcrime.securesms.util.addTextChangedListener
import org.thoughtcrime.securesms.util.contains import org.thoughtcrime.securesms.util.contains
@ -188,7 +188,7 @@ class InputBar @JvmOverloads constructor(
private fun startRecordingVoiceMessage() { delegate?.startRecordingVoiceMessage() } private fun startRecordingVoiceMessage() { delegate?.startRecordingVoiceMessage() }
fun draftQuote(thread: Recipient, message: MessageRecord, glide: GlideRequests) { fun draftQuote(thread: Recipient, message: MessageRecord, glide: RequestManager) {
quoteView?.let(binding.inputBarAdditionalContentContainer::removeView) quoteView?.let(binding.inputBarAdditionalContentContainer::removeView)
quote = message quote = message
@ -238,7 +238,7 @@ class InputBar @JvmOverloads constructor(
requestLayout() requestLayout()
} }
fun updateLinkPreviewDraft(glide: GlideRequests, updatedLinkPreview: LinkPreview) { fun updateLinkPreviewDraft(glide: RequestManager, updatedLinkPreview: LinkPreview) {
// Update our `linkPreview` property with the new (provided as an argument to this function) // Update our `linkPreview` property with the new (provided as an argument to this function)
// then update the View from that. // then update the View from that.
linkPreview = updatedLinkPreview.also { linkPreviewDraftView?.update(glide, it) } linkPreview = updatedLinkPreview.also { linkPreviewDraftView?.update(glide, it) }

View File

@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.ModalUrlBottomSheet import org.thoughtcrime.securesms.conversation.v2.ModalUrlBottomSheet
import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.MessageBubbleUtilities
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.ImageSlide
class LinkPreviewView : LinearLayout { class LinkPreviewView : LinearLayout {
@ -32,7 +32,7 @@ class LinkPreviewView : LinearLayout {
// region Updating // region Updating
fun bind( fun bind(
message: MmsMessageRecord, message: MmsMessageRecord,
glide: GlideRequests, glide: RequestManager,
isStartOfMessageCluster: Boolean, isStartOfMessageCluster: Boolean,
isEndOfMessageCluster: Boolean isEndOfMessageCluster: Boolean
) { ) {

View File

@ -18,7 +18,7 @@ import org.session.libsession.utilities.getColorFromAttr
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
import org.thoughtcrime.securesms.database.SessionContactDatabase import org.thoughtcrime.securesms.database.SessionContactDatabase
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.mms.SlideDeck import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.getAccentColor import org.thoughtcrime.securesms.util.getAccentColor
@ -68,7 +68,7 @@ class QuoteView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
// region Updating // region Updating
fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient, fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient,
isOutgoingMessage: Boolean, isOpenGroupInvitation: Boolean, threadID: Long, isOutgoingMessage: Boolean, isOpenGroupInvitation: Boolean, threadID: Long,
isOriginalMissing: Boolean, glide: GlideRequests) { isOriginalMissing: Boolean, glide: RequestManager) {
// Author // Author
val author = contactDb.getContactWithAccountID(authorPublicKey) val author = contactDb.getContactWithAccountID(authorPublicKey)
val localNumber = TextSecurePreferences.getLocalNumber(context) val localNumber = TextSecurePreferences.getLocalNumber(context)

View File

@ -38,8 +38,8 @@ import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getInt
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.SmsMessageRecord import org.thoughtcrime.securesms.database.model.SmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.util.GlowViewUtilities import org.thoughtcrime.securesms.util.GlowViewUtilities
import org.thoughtcrime.securesms.util.SearchUtil import org.thoughtcrime.securesms.util.SearchUtil
import org.thoughtcrime.securesms.util.getAccentColor import org.thoughtcrime.securesms.util.getAccentColor
@ -63,7 +63,7 @@ class VisibleMessageContentView : ConstraintLayout {
message: MessageRecord, message: MessageRecord,
isStartOfMessageCluster: Boolean = true, isStartOfMessageCluster: Boolean = true,
isEndOfMessageCluster: Boolean = true, isEndOfMessageCluster: Boolean = true,
glide: GlideRequests = GlideApp.with(this), glide: RequestManager = Glide.with(this),
thread: Recipient, thread: Recipient,
searchQuery: String? = null, searchQuery: String? = null,
contactIsTrusted: Boolean = true, contactIsTrusted: Boolean = true,

View File

@ -52,8 +52,8 @@ import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.home.UserDetailsBottomSheet import org.thoughtcrime.securesms.home.UserDetailsBottomSheet
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.disableClipping import org.thoughtcrime.securesms.util.disableClipping
import org.thoughtcrime.securesms.util.toDp import org.thoughtcrime.securesms.util.toDp
@ -141,7 +141,7 @@ class VisibleMessageView : FrameLayout {
message: MessageRecord, message: MessageRecord,
previous: MessageRecord? = null, previous: MessageRecord? = null,
next: MessageRecord? = null, next: MessageRecord? = null,
glide: GlideRequests = GlideApp.with(this), glide: RequestManager = Glide.with(this),
searchQuery: String? = null, searchQuery: String? = null,
contact: Contact? = null, contact: Contact? = null,
senderAccountID: String, senderAccountID: String,

View File

@ -44,7 +44,7 @@ import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
import org.thoughtcrime.securesms.mms.AudioSlide; import org.thoughtcrime.securesms.mms.AudioSlide;
import org.thoughtcrime.securesms.mms.DocumentSlide; import org.thoughtcrime.securesms.mms.DocumentSlide;
import org.thoughtcrime.securesms.mms.GifSlide; import org.thoughtcrime.securesms.mms.GifSlide;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.ImageSlide;
import org.thoughtcrime.securesms.mms.MediaConstraints; import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.PartAuthority;
@ -126,7 +126,7 @@ public class AttachmentManager {
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
public ListenableFuture<Boolean> setMedia(@NonNull final GlideRequests glideRequests, public ListenableFuture<Boolean> setMedia(@NonNull final RequestManager glideRequests,
@NonNull final Uri uri, @NonNull final Uri uri,
@NonNull final MediaType mediaType, @NonNull final MediaType mediaType,
@NonNull final MediaConstraints constraints, @NonNull final MediaConstraints constraints,

View File

@ -25,8 +25,8 @@ import org.session.libsignal.utilities.SettableFuture
import org.thoughtcrime.securesms.components.GlideBitmapListeningTarget import org.thoughtcrime.securesms.components.GlideBitmapListeningTarget
import org.thoughtcrime.securesms.components.GlideDrawableListeningTarget import org.thoughtcrime.securesms.components.GlideDrawableListeningTarget
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
import org.thoughtcrime.securesms.mms.GlideRequest import com.bumptech.glide.RequestBuilder
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.mms.Slide
open class ThumbnailView @JvmOverloads constructor( open class ThumbnailView @JvmOverloads constructor(
@ -104,13 +104,13 @@ open class ThumbnailView @JvmOverloads constructor(
} }
fun setImageResource( fun setImageResource(
glide: GlideRequests, glide: RequestManager,
slide: Slide, slide: Slide,
isPreview: Boolean isPreview: Boolean
): ListenableFuture<Boolean> = setImageResource(glide, slide, isPreview, 0, 0) ): ListenableFuture<Boolean> = setImageResource(glide, slide, isPreview, 0, 0)
fun setImageResource( fun setImageResource(
glide: GlideRequests, slide: Slide, glide: RequestManager, slide: Slide,
isPreview: Boolean, naturalWidth: Int, isPreview: Boolean, naturalWidth: Int,
naturalHeight: Int naturalHeight: Int
): ListenableFuture<Boolean> { ): ListenableFuture<Boolean> {
@ -152,9 +152,9 @@ open class ThumbnailView @JvmOverloads constructor(
} }
private fun buildThumbnailGlideRequest( private fun buildThumbnailGlideRequest(
glide: GlideRequests, glide: RequestManager,
slide: Slide slide: Slide
): GlideRequest<Drawable> = glide.load(DecryptableUri(slide.thumbnailUri!!)) ): RequestBuilder<Drawable> = glide.load(DecryptableUri(slide.thumbnailUri!!))
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.overrideDimensions() .overrideDimensions()
.transition(DrawableTransitionOptions.withCrossFade()) .transition(DrawableTransitionOptions.withCrossFade())
@ -162,21 +162,21 @@ open class ThumbnailView @JvmOverloads constructor(
.missingThumbnailPicture(slide.isInProgress) .missingThumbnailPicture(slide.isInProgress)
private fun buildPlaceholderGlideRequest( private fun buildPlaceholderGlideRequest(
glide: GlideRequests, glide: RequestManager,
slide: Slide slide: Slide
): GlideRequest<Bitmap> = glide.asBitmap() ): RequestBuilder<Bitmap> = glide.asBitmap()
.load(slide.getPlaceholderRes(context.theme)) .load(slide.getPlaceholderRes(context.theme))
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.overrideDimensions() .overrideDimensions()
.fitCenter() .fitCenter()
open fun clear(glideRequests: GlideRequests) { open fun clear(glideRequests: RequestManager) {
glideRequests.clear(binding.thumbnailImage) glideRequests.clear(binding.thumbnailImage)
slide = null slide = null
} }
fun setImageResource( fun setImageResource(
glideRequests: GlideRequests, glideRequests: RequestManager,
uri: Uri uri: Uri
): ListenableFuture<Boolean> = glideRequests.load(DecryptableUri(uri)) ): ListenableFuture<Boolean> = glideRequests.load(DecryptableUri(uri))
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
@ -184,19 +184,19 @@ open class ThumbnailView @JvmOverloads constructor(
.transform(CenterCrop()) .transform(CenterCrop())
.intoDrawableTargetAsFuture() .intoDrawableTargetAsFuture()
private fun GlideRequest<Drawable>.intoDrawableTargetAsFuture() = private fun RequestBuilder<Drawable>.intoDrawableTargetAsFuture() =
SettableFuture<Boolean>().also { SettableFuture<Boolean>().also {
binding.run { binding.run {
GlideDrawableListeningTarget(thumbnailImage, thumbnailLoadIndicator, it) GlideDrawableListeningTarget(thumbnailImage, thumbnailLoadIndicator, it)
}.let { into(it) } }.let { into(it) }
} }
private fun <T> GlideRequest<T>.overrideDimensions() = private fun <T> RequestBuilder<T>.overrideDimensions() =
dimensDelegate.resourceSize().takeIf { 0 !in it } dimensDelegate.resourceSize().takeIf { 0 !in it }
?.let { override(it[WIDTH], it[HEIGHT]) } ?.let { override(it[WIDTH], it[HEIGHT]) }
?: override(getDefaultWidth(), getDefaultHeight()) ?: override(getDefaultWidth(), getDefaultHeight())
} }
private fun <T> GlideRequest<T>.missingThumbnailPicture( private fun <T> RequestBuilder<T>.missingThumbnailPicture(
inProgress: Boolean inProgress: Boolean
) = takeIf { inProgress } ?: apply(RequestOptions.errorOf(R.drawable.ic_missing_thumbnail_picture)) ) = takeIf { inProgress } ?: apply(RequestOptions.errorOf(R.drawable.ic_missing_thumbnail_picture))

View File

@ -1,14 +1,14 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.security.SecureRandom;
/** /**
* A provider that is responsible for creating or retrieving the AttachmentSecret model. * A provider that is responsible for creating or retrieving the AttachmentSecret model.
* *
@ -81,9 +81,8 @@ public class AttachmentSecretProvider {
} }
private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) { private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret); AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret);
storeAttachmentSecret(context, attachmentSecret); storeAttachmentSecret(context, attachmentSecret);

View File

@ -1,6 +1,8 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -8,7 +10,6 @@ import androidx.annotation.NonNull;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
public class DatabaseSecretProvider { public class DatabaseSecretProvider {
@ -60,9 +61,8 @@ public class DatabaseSecretProvider {
} }
private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) { private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
DatabaseSecret databaseSecret = new DatabaseSecret(secret); DatabaseSecret databaseSecret = new DatabaseSecret(secret);

View File

@ -1,6 +1,8 @@
package org.thoughtcrime.securesms.crypto; package org.thoughtcrime.securesms.crypto;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.util.Pair; import android.util.Pair;
@ -11,7 +13,6 @@ import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream; import javax.crypto.CipherOutputStream;
@ -31,7 +32,7 @@ public class ModernEncryptingPartOutputStream {
throws IOException throws IOException
{ {
byte[] random = new byte[32]; byte[] random = new byte[32];
new SecureRandom().nextBytes(random); SECURE_RANDOM.nextBytes(random);
try { try {
Mac mac = Mac.getInstance("HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256");

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
@ -26,7 +28,6 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.BitmapUtil;
import java.io.Closeable; import java.io.Closeable;
import java.security.SecureRandom;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -303,7 +304,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
public void updateProfilePicture(String groupID, byte[] newValue) { public void updateProfilePicture(String groupID, byte[] newValue) {
long avatarId; long avatarId;
if (newValue != null) avatarId = Math.abs(new SecureRandom().nextLong()); if (newValue != null) avatarId = Math.abs(SECURE_RANDOM.nextLong());
else avatarId = 0; else avatarId = 0;
@ -458,12 +459,6 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId}); database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId});
} }
public byte[] allocateGroupId() {
byte[] groupId = new byte[16];
new SecureRandom().nextBytes(groupId);
return groupId;
}
public boolean hasGroup(@NonNull String groupId) { public boolean hasGroup(@NonNull String groupId) {
try (Cursor cursor = databaseHelper.getReadableDatabase().rawQuery( try (Cursor cursor = databaseHelper.getReadableDatabase().rawQuery(
"SELECT 1 FROM " + TABLE_NAME + " WHERE " + GROUP_ID + " = ? LIMIT 1", "SELECT 1 FROM " + TABLE_NAME + " WHERE " + GROUP_ID + " = ? LIMIT 1",

View File

@ -166,8 +166,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
const val RESET_SEQ_NO = "UPDATE $lastMessageServerIDTable SET $lastMessageServerID = 0;" const val RESET_SEQ_NO = "UPDATE $lastMessageServerIDTable SET $lastMessageServerID = 0;"
const val EMPTY_VERSION = "0.0.0"
// endregion // endregion
} }
@ -175,15 +173,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
return database.get(snodePoolTable, "${Companion.dummyKey} = ?", wrap("dummy_key")) { cursor -> return database.get(snodePoolTable, "${Companion.dummyKey} = ?", wrap("dummy_key")) { cursor ->
val snodePoolAsString = cursor.getString(cursor.getColumnIndexOrThrow(snodePool)) val snodePoolAsString = cursor.getString(cursor.getColumnIndexOrThrow(snodePool))
snodePoolAsString.split(", ").mapNotNull { snodeAsString -> snodePoolAsString.split(", ").mapNotNull(::Snode)
val components = snodeAsString.split("-")
val address = components[0]
val port = components.getOrNull(1)?.toIntOrNull() ?: return@mapNotNull null
val ed25519Key = components.getOrNull(2) ?: return@mapNotNull null
val x25519Key = components.getOrNull(3) ?: return@mapNotNull null
val version = components.getOrNull(4) ?: EMPTY_VERSION
Snode(address, port, Snode.KeySet(ed25519Key, x25519Key), version)
}
}?.toSet() ?: setOf() }?.toSet() ?: setOf()
} }
@ -231,18 +221,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
fun get(indexPath: String): Snode? { fun get(indexPath: String): Snode? {
return database.get(onionRequestPathTable, "${Companion.indexPath} = ?", wrap(indexPath)) { cursor -> return database.get(onionRequestPathTable, "${Companion.indexPath} = ?", wrap(indexPath)) { cursor ->
val snodeAsString = cursor.getString(cursor.getColumnIndexOrThrow(snode)) Snode(cursor.getString(cursor.getColumnIndexOrThrow(snode)))
val components = snodeAsString.split("-")
val address = components[0]
val port = components.getOrNull(1)?.toIntOrNull()
val ed25519Key = components.getOrNull(2)
val x25519Key = components.getOrNull(3)
val version = components.getOrNull(4) ?: EMPTY_VERSION
if (port != null && ed25519Key != null && x25519Key != null) {
Snode(address, port, Snode.KeySet(ed25519Key, x25519Key), version)
} else {
null
}
} }
} }
val result = mutableListOf<List<Snode>>() val result = mutableListOf<List<Snode>>()
@ -276,15 +255,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
return database.get(swarmTable, "${Companion.swarmPublicKey} = ?", wrap(publicKey)) { cursor -> return database.get(swarmTable, "${Companion.swarmPublicKey} = ?", wrap(publicKey)) { cursor ->
val swarmAsString = cursor.getString(cursor.getColumnIndexOrThrow(swarm)) val swarmAsString = cursor.getString(cursor.getColumnIndexOrThrow(swarm))
swarmAsString.split(", ").mapNotNull { targetAsString -> swarmAsString.split(", ").mapNotNull(::Snode)
val components = targetAsString.split("-")
val address = components[0]
val port = components.getOrNull(1)?.toIntOrNull() ?: return@mapNotNull null
val ed25519Key = components.getOrNull(2) ?: return@mapNotNull null
val x25519Key = components.getOrNull(3) ?: return@mapNotNull null
val version = components.getOrNull(4) ?: EMPTY_VERSION
Snode(address, port, Snode.KeySet(ed25519Key, x25519Key), version)
}
}?.toSet() }?.toSet()
} }

View File

@ -46,11 +46,11 @@ import org.session.libsession.utilities.IdentityKeyMismatchList
import org.session.libsession.utilities.NetworkFailure import org.session.libsession.utilities.NetworkFailure
import org.session.libsession.utilities.NetworkFailureList import org.session.libsession.utilities.NetworkFailureList
import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled
import org.session.libsession.utilities.Util.toIsoBytes
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.JsonUtil
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.ThreadUtils.queue import org.session.libsignal.utilities.ThreadUtils.queue
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment
import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener
@ -66,7 +66,6 @@ import org.thoughtcrime.securesms.mms.SlideDeck
import org.thoughtcrime.securesms.util.asSequence import org.thoughtcrime.securesms.util.asSequence
import java.io.Closeable import java.io.Closeable
import java.io.IOException import java.io.IOException
import java.security.SecureRandom
import java.util.LinkedList import java.util.LinkedList
class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : MessagingDatabase(context, databaseHelper) { class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : MessagingDatabase(context, databaseHelper) {
@ -1200,7 +1199,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
inner class OutgoingMessageReader(private val message: OutgoingMediaMessage?, inner class OutgoingMessageReader(private val message: OutgoingMediaMessage?,
private val threadId: Long) { private val threadId: Long) {
private val id = SecureRandom().nextLong() private val id = SECURE_RANDOM.nextLong()
val current: MessageRecord val current: MessageRecord
get() { get() {
val slideDeck = SlideDeck(context, message!!.attachments) val slideDeck = SlideDeck(context, message!!.attachments)

View File

@ -17,6 +17,8 @@
*/ */
package org.thoughtcrime.securesms.database; package org.thoughtcrime.securesms.database;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
@ -49,7 +51,6 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@ -784,7 +785,7 @@ public class SmsDatabase extends MessagingDatabase {
public OutgoingMessageReader(OutgoingTextMessage message, long threadId) { public OutgoingMessageReader(OutgoingTextMessage message, long threadId) {
this.message = message; this.message = message;
this.threadId = threadId; this.threadId = threadId;
this.id = new SecureRandom().nextLong(); this.id = SECURE_RANDOM.nextLong();
} }
public MessageRecord getCurrent() { public MessageRecord getCurrent() {

View File

@ -29,8 +29,8 @@ import org.session.libsession.utilities.ViewUtil;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl; import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl;
import org.thoughtcrime.securesms.giph.model.GiphyImage; import org.thoughtcrime.securesms.giph.model.GiphyImage;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -43,7 +43,7 @@ class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHolder> {
private static final String TAG = GiphyAdapter.class.getSimpleName(); private static final String TAG = GiphyAdapter.class.getSimpleName();
private final Context context; private final Context context;
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private List<GiphyImage> images; private List<GiphyImage> images;
private OnItemClickListener listener; private OnItemClickListener listener;
@ -117,7 +117,7 @@ class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHolder> {
} }
} }
GiphyAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @NonNull List<GiphyImage> images) { GiphyAdapter(@NonNull Context context, @NonNull RequestManager glideRequests, @NonNull List<GiphyImage> images) {
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.images = images; this.images = images;
@ -150,7 +150,7 @@ class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHolder> {
holder.thumbnail.setAspectRatio(image.getGifAspectRatio()); holder.thumbnail.setAspectRatio(image.getGifAspectRatio());
holder.gifProgress.setVisibility(View.GONE); holder.gifProgress.setVisibility(View.GONE);
RequestBuilder<Drawable> thumbnailRequest = GlideApp.with(context) RequestBuilder<Drawable> thumbnailRequest = Glide.with(context)
.load(new ChunkedImageUrl(image.getStillUrl(), image.getStillSize())) .load(new ChunkedImageUrl(image.getStillUrl(), image.getStillSize()))
.diskCacheStrategy(DiskCacheStrategy.NONE); .diskCacheStrategy(DiskCacheStrategy.NONE);

View File

@ -19,7 +19,7 @@ import android.widget.TextView;
import org.thoughtcrime.securesms.giph.model.GiphyImage; import org.thoughtcrime.securesms.giph.model.GiphyImage;
import org.thoughtcrime.securesms.giph.net.GiphyLoader; import org.thoughtcrime.securesms.giph.net.GiphyLoader;
import org.thoughtcrime.securesms.giph.util.InfiniteScrollListener; import org.thoughtcrime.securesms.giph.util.InfiniteScrollListener;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.ViewUtil; import org.session.libsession.utilities.ViewUtil;
@ -54,7 +54,7 @@ public abstract class GiphyFragment extends Fragment implements LoaderManager.Lo
public void onActivityCreated(Bundle bundle) { public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle); super.onActivityCreated(bundle);
this.giphyAdapter = new GiphyAdapter(getActivity(), GlideApp.with(this), new LinkedList<>()); this.giphyAdapter = new GiphyAdapter(getActivity(), Glide.with(this), new LinkedList<>());
this.giphyAdapter.setListener(this); this.giphyAdapter.setListener(this);
setLayoutManager(TextSecurePreferences.isGifSearchInGridLayout(getContext())); setLayoutManager(TextSecurePreferences.isGifSearchInGridLayout(getContext()));

View File

@ -1,9 +1,10 @@
package org.thoughtcrime.securesms.glide; package org.thoughtcrime.securesms.glide;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
import okhttp3.Headers; import okhttp3.Headers;
import okhttp3.Interceptor; import okhttp3.Interceptor;
@ -30,15 +31,15 @@ public class PaddedHeadersInterceptor implements Interceptor {
private @NonNull Headers getPaddedHeaders(@NonNull Headers headers) { private @NonNull Headers getPaddedHeaders(@NonNull Headers headers) {
return headers.newBuilder() return headers.newBuilder()
.add(PADDING_HEADER, getRandomString(new SecureRandom(), MIN_RANDOM_BYTES, MAX_RANDOM_BYTES)) .add(PADDING_HEADER, getRandomString(MIN_RANDOM_BYTES, MAX_RANDOM_BYTES))
.build(); .build();
} }
private static @NonNull String getRandomString(@NonNull SecureRandom secureRandom, int minLength, int maxLength) { private static @NonNull String getRandomString(int minLength, int maxLength) {
char[] buffer = new char[secureRandom.nextInt(maxLength - minLength) + minLength]; char[] buffer = new char[SECURE_RANDOM.nextInt(maxLength - minLength) + minLength];
for (int i = 0 ; i < buffer.length; i++) { for (int i = 0 ; i < buffer.length; i++) {
buffer[i] = (char) (secureRandom.nextInt(74) + 48); // Random char from 0-Z buffer[i] = (char) (SECURE_RANDOM.nextInt(74) + 48); // Random char from 0-Z
} }
return new String(buffer); return new String(buffer);

View File

@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.conversation.start.StartConversationDelegate
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.util.fadeIn import org.thoughtcrime.securesms.util.fadeIn
import org.thoughtcrime.securesms.util.fadeOut import org.thoughtcrime.securesms.util.fadeOut
import javax.inject.Inject import javax.inject.Inject
@ -55,7 +55,7 @@ class CreateGroupFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val adapter = SelectContactsAdapter(requireContext(), GlideApp.with(requireContext())) val adapter = SelectContactsAdapter(requireContext(), Glide.with(requireContext()))
binding.backButton.setOnClickListener { delegate.onDialogBackPressed() } binding.backButton.setOnClickListener { delegate.onDialogBackPressed() }
binding.closeButton.setOnClickListener { delegate.onDialogClosePressed() } binding.closeButton.setOnClickListener { delegate.onDialogClosePressed() }
binding.contactSearch.callbacks = object : KeyboardPageSearchView.Callbacks { binding.contactSearch.callbacks = object : KeyboardPageSearchView.Callbacks {

View File

@ -37,7 +37,7 @@ import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.groups.ClosedGroupManager.updateLegacyGroup import org.thoughtcrime.securesms.groups.ClosedGroupManager.updateLegacyGroup
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.util.fadeIn import org.thoughtcrime.securesms.util.fadeIn
import org.thoughtcrime.securesms.util.fadeOut import org.thoughtcrime.securesms.util.fadeOut
import java.io.IOException import java.io.IOException
@ -76,9 +76,9 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() {
private val memberListAdapter by lazy { private val memberListAdapter by lazy {
if (isSelfAdmin) if (isSelfAdmin)
EditClosedGroupMembersAdapter(this, GlideApp.with(this), isSelfAdmin, this::onMemberClick) EditClosedGroupMembersAdapter(this, Glide.with(this), isSelfAdmin, this::onMemberClick)
else else
EditClosedGroupMembersAdapter(this, GlideApp.with(this), isSelfAdmin) EditClosedGroupMembersAdapter(this, Glide.with(this), isSelfAdmin)
} }
private lateinit var mainContentContainer: LinearLayout private lateinit var mainContentContainer: LinearLayout

View File

@ -5,13 +5,13 @@ import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup import android.view.ViewGroup
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
import org.thoughtcrime.securesms.contacts.UserView import org.thoughtcrime.securesms.contacts.UserView
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
class EditClosedGroupMembersAdapter( class EditClosedGroupMembersAdapter(
private val context: Context, private val context: Context,
private val glide: GlideRequests, private val glide: RequestManager,
private val admin: Boolean, private val admin: Boolean,
private val memberClickListener: ((String) -> Unit)? = null private val memberClickListener: ((String) -> Unit)? = null
) : RecyclerView.Adapter<EditClosedGroupMembersAdapter.ViewHolder>() { ) : RecyclerView.Adapter<EditClosedGroupMembersAdapter.ViewHolder>() {

View File

@ -62,8 +62,8 @@ import org.thoughtcrime.securesms.home.search.GlobalSearchInputLayout
import org.thoughtcrime.securesms.home.search.GlobalSearchResult import org.thoughtcrime.securesms.home.search.GlobalSearchResult
import org.thoughtcrime.securesms.home.search.GlobalSearchViewModel import org.thoughtcrime.securesms.home.search.GlobalSearchViewModel
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.notifications.PushRegistry import org.thoughtcrime.securesms.notifications.PushRegistry
import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.SettingsActivity import org.thoughtcrime.securesms.preferences.SettingsActivity
@ -89,7 +89,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
GlobalSearchInputLayout.GlobalSearchInputLayoutListener { GlobalSearchInputLayout.GlobalSearchInputLayoutListener {
private lateinit var binding: ActivityHomeBinding private lateinit var binding: ActivityHomeBinding
private lateinit var glide: GlideRequests private lateinit var glide: RequestManager
@Inject lateinit var threadDb: ThreadDatabase @Inject lateinit var threadDb: ThreadDatabase
@Inject lateinit var mmsSmsDatabase: MmsSmsDatabase @Inject lateinit var mmsSmsDatabase: MmsSmsDatabase
@ -148,7 +148,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
// Set custom toolbar // Set custom toolbar
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
// Set up Glide // Set up Glide
glide = GlideApp.with(this) glide = Glide.with(this)
// Set up toolbar buttons // Set up toolbar buttons
binding.profileButton.setOnClickListener { openSettings() } binding.profileButton.setOnClickListener { openSettings() }
binding.searchViewContainer.setOnClickListener { binding.searchViewContainer.setOnClickListener {

View File

@ -7,10 +7,10 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListUpdateCallback import androidx.recyclerview.widget.ListUpdateCallback
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.NO_ID import androidx.recyclerview.widget.RecyclerView.NO_ID
import com.bumptech.glide.RequestManager
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.ViewMessageRequestBannerBinding import network.loki.messenger.databinding.ViewMessageRequestBannerBinding
import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.mms.GlideRequests
class HomeAdapter( class HomeAdapter(
private val context: Context, private val context: Context,
@ -74,7 +74,7 @@ class HomeAdapter(
return data.threads[offsetPosition].threadId return data.threads[offsetPosition].threadId
} }
lateinit var glide: GlideRequests lateinit var glide: RequestManager
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
when (viewType) { when (viewType) {
@ -104,7 +104,6 @@ class HomeAdapter(
holder.binding.run { holder.binding.run {
messageRequests?.let { messageRequests?.let {
unreadCountTextView.text = it.count unreadCountTextView.text = it.count
timestampTextView.text = it.timestamp
} }
} }
} }

View File

@ -1,24 +0,0 @@
package org.thoughtcrime.securesms.jobmanager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.Nullable;
/**
* Service that keeps the application in memory while the app is closed.
*
* Important: Should only be used on API < 26.
*/
public class KeepAliveService extends Service {
@Override
public @Nullable IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.logging; package org.thoughtcrime.securesms.logging;
import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK; import static org.session.libsignal.crypto.CipherUtil.CIPHER_LOCK;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -17,7 +18,6 @@ import java.io.IOException;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -64,7 +64,7 @@ class LogFile {
} }
void writeEntry(@NonNull String entry) throws IOException { void writeEntry(@NonNull String entry) throws IOException {
new SecureRandom().nextBytes(ivBuffer); SECURE_RANDOM.nextBytes(ivBuffer);
byte[] plaintext = entry.getBytes(); byte[] plaintext = entry.getBytes();
try { try {

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.logging; package org.thoughtcrime.securesms.logging;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -9,7 +11,6 @@ import org.session.libsignal.utilities.Base64;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom;
class LogSecretProvider { class LogSecretProvider {
@ -40,9 +41,8 @@ class LogSecretProvider {
} }
private static byte[] createAndStoreSecret(@NonNull Context context) { private static byte[] createAndStoreSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32]; byte[] secret = new byte[32];
random.nextBytes(secret); SECURE_RANDOM.nextBytes(secret);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret);

View File

@ -14,7 +14,7 @@ import network.loki.messenger.R;
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.util.StableIdGenerator; import org.thoughtcrime.securesms.util.StableIdGenerator;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,7 +25,7 @@ public class MediaRailAdapter extends RecyclerView.Adapter<MediaRailAdapter.Medi
private static final int TYPE_MEDIA = 1; private static final int TYPE_MEDIA = 1;
private static final int TYPE_BUTTON = 2; private static final int TYPE_BUTTON = 2;
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final List<Media> media; private final List<Media> media;
private final RailItemListener listener; private final RailItemListener listener;
private final boolean editable; private final boolean editable;
@ -34,7 +34,7 @@ public class MediaRailAdapter extends RecyclerView.Adapter<MediaRailAdapter.Medi
private RailItemAddListener addListener; private RailItemAddListener addListener;
private int activePosition; private int activePosition;
public MediaRailAdapter(@NonNull GlideRequests glideRequests, @NonNull RailItemListener listener, boolean editable) { public MediaRailAdapter(@NonNull RequestManager glideRequests, @NonNull RailItemListener listener, boolean editable) {
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.media = new ArrayList<>(); this.media = new ArrayList<>();
this.listener = listener; this.listener = listener;
@ -148,7 +148,7 @@ public class MediaRailAdapter extends RecyclerView.Adapter<MediaRailAdapter.Medi
captionIndicator = itemView.findViewById(R.id.rail_item_caption); captionIndicator = itemView.findViewById(R.id.rail_item_caption);
} }
void bind(@NonNull Media media, boolean isActive, @NonNull GlideRequests glideRequests, void bind(@NonNull Media media, boolean isActive, @NonNull RequestManager glideRequests,
@NonNull RailItemListener railItemListener, int distanceFromActive, boolean editable) @NonNull RailItemListener railItemListener, int distanceFromActive, boolean editable)
{ {
image.setImageResource(glideRequests, media.getUri()); image.setImageResource(glideRequests, media.getUri());

View File

@ -36,7 +36,7 @@ import com.bumptech.glide.request.transition.Transition;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.ServiceUtil;
import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.Stopwatch;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
@ -236,7 +236,7 @@ public class Camera1Fragment extends Fragment implements TextureView.SurfaceText
Transformation<Bitmap> transformation = frontFacing ? new MultiTransformation<>(new CenterCrop(), new FlipTransformation()) Transformation<Bitmap> transformation = frontFacing ? new MultiTransformation<>(new CenterCrop(), new FlipTransformation())
: new CenterCrop(); : new CenterCrop();
GlideApp.with(this) Glide.with(this)
.asBitmap() .asBitmap()
.load(jpegData) .load(jpegData)
.transform(transformation) .transform(transformation)

View File

@ -14,18 +14,18 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
class MediaPickerFolderAdapter extends RecyclerView.Adapter<MediaPickerFolderAdapter.FolderViewHolder> { class MediaPickerFolderAdapter extends RecyclerView.Adapter<MediaPickerFolderAdapter.FolderViewHolder> {
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final EventListener eventListener; private final EventListener eventListener;
private final List<MediaFolder> folders; private final List<MediaFolder> folders;
MediaPickerFolderAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) { MediaPickerFolderAdapter(@NonNull RequestManager glideRequests, @NonNull EventListener eventListener) {
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.eventListener = eventListener; this.eventListener = eventListener;
this.folders = new ArrayList<>(); this.folders = new ArrayList<>();
@ -74,7 +74,7 @@ class MediaPickerFolderAdapter extends RecyclerView.Adapter<MediaPickerFolderAda
count = itemView.findViewById(R.id.mediapicker_folder_item_count); count = itemView.findViewById(R.id.mediapicker_folder_item_count);
} }
void bind(@NonNull MediaFolder folder, @NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) { void bind(@NonNull MediaFolder folder, @NonNull RequestManager glideRequests, @NonNull EventListener eventListener) {
title.setText(folder.getTitle()); title.setText(folder.getTitle());
count.setText(String.valueOf(folder.getItemCount())); count.setText(String.valueOf(folder.getItemCount()));

View File

@ -19,7 +19,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.utilities.guava.Optional; import org.session.libsignal.utilities.guava.Optional;
@ -79,7 +79,7 @@ public class MediaPickerFolderFragment extends Fragment implements MediaPickerFo
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
RecyclerView list = view.findViewById(R.id.mediapicker_folder_list); RecyclerView list = view.findViewById(R.id.mediapicker_folder_list);
MediaPickerFolderAdapter adapter = new MediaPickerFolderAdapter(GlideApp.with(this), this); MediaPickerFolderAdapter adapter = new MediaPickerFolderAdapter(Glide.with(this), this);
layoutManager = new GridLayoutManager(requireContext(), 2); layoutManager = new GridLayoutManager(requireContext(), 2);
onScreenWidthChanged(getScreenWidth()); onScreenWidthChanged(getScreenWidth());

View File

@ -12,7 +12,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.StableIdGenerator; import org.thoughtcrime.securesms.util.StableIdGenerator;
@ -24,7 +24,7 @@ import java.util.List;
public class MediaPickerItemAdapter extends RecyclerView.Adapter<MediaPickerItemAdapter.ItemViewHolder> { public class MediaPickerItemAdapter extends RecyclerView.Adapter<MediaPickerItemAdapter.ItemViewHolder> {
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final EventListener eventListener; private final EventListener eventListener;
private final List<Media> media; private final List<Media> media;
private final List<Media> selected; private final List<Media> selected;
@ -33,7 +33,7 @@ public class MediaPickerItemAdapter extends RecyclerView.Adapter<MediaPickerItem
private boolean forcedMultiSelect; private boolean forcedMultiSelect;
public MediaPickerItemAdapter(@NonNull GlideRequests glideRequests, @NonNull EventListener eventListener, int maxSelection) { public MediaPickerItemAdapter(@NonNull RequestManager glideRequests, @NonNull EventListener eventListener, int maxSelection) {
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.eventListener = eventListener; this.eventListener = eventListener;
this.media = new ArrayList<>(); this.media = new ArrayList<>();
@ -109,7 +109,7 @@ public class MediaPickerItemAdapter extends RecyclerView.Adapter<MediaPickerItem
selectOrder = itemView.findViewById(R.id.mediapicker_select_order); selectOrder = itemView.findViewById(R.id.mediapicker_select_order);
} }
void bind(@NonNull Media media, boolean multiSelect, List<Media> selected, int maxSelection, @NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) { void bind(@NonNull Media media, boolean multiSelect, List<Media> selected, int maxSelection, @NonNull RequestManager glideRequests, @NonNull EventListener eventListener) {
glideRequests.load(media.getUri()) glideRequests.load(media.getUri())
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.transition(DrawableTransitionOptions.withCrossFade()) .transition(DrawableTransitionOptions.withCrossFade())

View File

@ -21,7 +21,7 @@ import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
import java.util.ArrayList; import java.util.ArrayList;
@ -91,7 +91,7 @@ public class MediaPickerItemFragment extends Fragment implements MediaPickerItem
RecyclerView imageList = view.findViewById(R.id.mediapicker_item_list); RecyclerView imageList = view.findViewById(R.id.mediapicker_item_list);
adapter = new MediaPickerItemAdapter(GlideApp.with(this), this, maxSelection); adapter = new MediaPickerItemAdapter(Glide.with(this), this, maxSelection);
layoutManager = new GridLayoutManager(requireContext(), 4); layoutManager = new GridLayoutManager(requireContext(), 4);
imageList.setLayoutManager(layoutManager); imageList.setLayoutManager(layoutManager);

View File

@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.util.SimpleTextWatcher;
import org.thoughtcrime.securesms.imageeditor.model.EditorModel; import org.thoughtcrime.securesms.imageeditor.model.EditorModel;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter; import org.thoughtcrime.securesms.mediapreview.MediaRailAdapter;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.BlobProvider;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.scribbles.ImageEditorFragment; import org.thoughtcrime.securesms.scribbles.ImageEditorFragment;
@ -187,7 +187,7 @@ public class MediaSendFragment extends Fragment implements ViewTreeObserver.OnGl
fragmentPager.addOnPageChangeListener(pageChangeListener); fragmentPager.addOnPageChangeListener(pageChangeListener);
fragmentPager.post(() -> pageChangeListener.onPageSelected(fragmentPager.getCurrentItem())); fragmentPager.post(() -> pageChangeListener.onPageSelected(fragmentPager.getCurrentItem()));
mediaRailAdapter = new MediaRailAdapter(GlideApp.with(this), this, true); mediaRailAdapter = new MediaRailAdapter(Glide.with(this), this, true);
mediaRail.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); mediaRail.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
mediaRail.setAdapter(mediaRailAdapter); mediaRail.setAdapter(mediaRailAdapter);

View File

@ -12,7 +12,7 @@ import android.widget.ImageView;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
public class MediaSendGifFragment extends Fragment implements MediaSendPageFragment { public class MediaSendGifFragment extends Fragment implements MediaSendPageFragment {
@ -40,7 +40,7 @@ public class MediaSendGifFragment extends Fragment implements MediaSendPageFragm
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
uri = getArguments().getParcelable(KEY_URI); uri = getArguments().getParcelable(KEY_URI);
GlideApp.with(this).load(new DecryptableStreamUriLoader.DecryptableUri(uri)).into((ImageView) view); Glide.with(this).load(new DecryptableStreamUriLoader.DecryptableUri(uri)).into((ImageView) view);
} }
@Override @Override

View File

@ -11,7 +11,7 @@ import network.loki.messenger.databinding.ViewMessageRequestBinding
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities.highlightMentions import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities.highlightMentions
import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import java.util.Locale import java.util.Locale
@ -32,7 +32,7 @@ class MessageRequestView : LinearLayout {
// endregion // endregion
// region Updating // region Updating
fun bind(thread: ThreadRecord, glide: GlideRequests) { fun bind(thread: ThreadRecord, glide: RequestManager) {
this.thread = thread this.thread = thread
val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString() val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString()

View File

@ -17,8 +17,8 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
import org.thoughtcrime.securesms.showSessionDialog import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
import org.thoughtcrime.securesms.util.push import org.thoughtcrime.securesms.util.push
@ -28,7 +28,7 @@ import javax.inject.Inject
class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), ConversationClickListener, LoaderManager.LoaderCallbacks<Cursor> { class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), ConversationClickListener, LoaderManager.LoaderCallbacks<Cursor> {
private lateinit var binding: ActivityMessageRequestsBinding private lateinit var binding: ActivityMessageRequestsBinding
private lateinit var glide: GlideRequests private lateinit var glide: RequestManager
@Inject lateinit var threadDb: ThreadDatabase @Inject lateinit var threadDb: ThreadDatabase
@ -43,7 +43,7 @@ class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), Conversat
binding = ActivityMessageRequestsBinding.inflate(layoutInflater) binding = ActivityMessageRequestsBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
glide = GlideApp.with(this) glide = Glide.with(this)
adapter.setHasStableIds(true) adapter.setHasStableIds(true)
adapter.glide = glide adapter.glide = glide

View File

@ -15,7 +15,7 @@ import org.session.libsession.utilities.ThemeUtil
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.mms.GlideRequests import com.bumptech.glide.RequestManager
class MessageRequestsAdapter( class MessageRequestsAdapter(
context: Context, context: Context,
@ -23,7 +23,7 @@ class MessageRequestsAdapter(
val listener: ConversationClickListener val listener: ConversationClickListener
) : CursorRecyclerViewAdapter<MessageRequestsAdapter.ViewHolder>(context, cursor) { ) : CursorRecyclerViewAdapter<MessageRequestsAdapter.ViewHolder>(context, cursor) {
private val threadDatabase = DatabaseComponent.get(context).threadDatabase() private val threadDatabase = DatabaseComponent.get(context).threadDatabase()
lateinit var glide: GlideRequests lateinit var glide: RequestManager
class ViewHolder(val view: MessageRequestView) : RecyclerView.ViewHolder(view) class ViewHolder(val view: MessageRequestView) : RecyclerView.ViewHolder(view)

View File

@ -21,7 +21,6 @@ import android.content.res.Resources
import android.net.Uri import android.net.Uri
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.squareup.phrase.Phrase import com.squareup.phrase.Phrase
import java.security.SecureRandom
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress
@ -29,6 +28,7 @@ import org.session.libsession.messaging.sending_receiving.attachments.UriAttachm
import org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY import org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY
import org.session.libsession.utilities.Util.equals import org.session.libsession.utilities.Util.equals
import org.session.libsession.utilities.Util.hashCode import org.session.libsession.utilities.Util.hashCode
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.conversation.v2.Util import org.thoughtcrime.securesms.conversation.v2.Util
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
@ -160,7 +160,7 @@ abstract class Slide(@JvmField protected val context: Context, protected val att
): Attachment { ): Attachment {
val resolvedType = val resolvedType =
Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime) Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime)
val fastPreflightId = SecureRandom().nextLong().toString() val fastPreflightId = SECURE_RANDOM.nextLong().toString()
return UriAttachment( return UriAttachment(
uri, uri,
if (hasThumbnail) uri else null, if (hasThumbnail) uri else null,

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.net; package org.thoughtcrime.securesms.net;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
@ -15,7 +17,6 @@ import org.session.libsignal.utilities.guava.Optional;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -54,7 +55,7 @@ public class ChunkedDataFetcher {
private RequestController fetchChunksWithUnknownTotalSize(@NonNull String url, @NonNull Callback callback) { private RequestController fetchChunksWithUnknownTotalSize(@NonNull String url, @NonNull Callback callback) {
CompositeRequestController compositeController = new CompositeRequestController(); CompositeRequestController compositeController = new CompositeRequestController();
long chunkSize = new SecureRandom().nextInt(1024) + 1024; long chunkSize = SECURE_RANDOM.nextInt(1024) + 1024;
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.cacheControl(NO_CACHE) .cacheControl(NO_CACHE)

View File

@ -38,7 +38,7 @@ import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.database.SessionContactDatabase; import org.thoughtcrime.securesms.database.SessionContactDatabase;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator; import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
@ -91,7 +91,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
try { try {
// AC: For some reason, if not use ".asBitmap()" method, the returned BitmapDrawable // AC: For some reason, if not use ".asBitmap()" method, the returned BitmapDrawable
// wraps a recycled bitmap and leads to a crash. // wraps a recycled bitmap and leads to a crash.
Bitmap iconBitmap = GlideApp.with(context.getApplicationContext()) Bitmap iconBitmap = Glide.with(context.getApplicationContext())
.asBitmap() .asBitmap()
.load(contactPhoto) .load(contactPhoto)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
@ -293,7 +293,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
Uri uri = slideDeck.getThumbnailSlide().getThumbnailUri(); Uri uri = slideDeck.getThumbnailSlide().getThumbnailUri();
return GlideApp.with(context.getApplicationContext()) return Glide.with(context.getApplicationContext())
.asBitmap() .asBitmap()
.load(new DecryptableStreamUriLoader.DecryptableUri(uri)) .load(new DecryptableStreamUriLoader.DecryptableUri(uri))
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)

View File

@ -1,9 +1,9 @@
package org.thoughtcrime.securesms.permissions; package org.thoughtcrime.securesms.permissions;
import static org.session.libsignal.utilities.Util.SECURE_RANDOM;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
@ -11,9 +11,7 @@ import android.os.Build;
import android.provider.Settings; import android.provider.Settings;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Display; import android.view.Display;
import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Button;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -28,13 +26,10 @@ import org.session.libsession.utilities.ServiceUtil;
import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.LRUCache;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import network.loki.messenger.R;
public class Permissions { public class Permissions {
private static final Map<Integer, PermissionsRequest> OUTSTANDING = new LRUCache<>(2); private static final Map<Integer, PermissionsRequest> OUTSTANDING = new LRUCache<>(2);
@ -172,7 +167,7 @@ public class Permissions {
} }
private void executePermissionsRequest(PermissionsRequest request) { private void executePermissionsRequest(PermissionsRequest request) {
int requestCode = new SecureRandom().nextInt(65434) + 100; int requestCode = SECURE_RANDOM.nextInt(65434) + 100;
synchronized (OUTSTANDING) { synchronized (OUTSTANDING) {
OUTSTANDING.put(requestCode, request); OUTSTANDING.put(requestCode, request);

View File

@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.BlockedContactLayoutBinding import network.loki.messenger.databinding.BlockedContactLayoutBinding
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.util.adapter.SelectableItem import org.thoughtcrime.securesms.util.adapter.SelectableItem
typealias SelectableRecipient = SelectableItem<Recipient> typealias SelectableRecipient = SelectableItem<Recipient>
@ -43,7 +43,7 @@ class BlockedContactsAdapter(val viewModel: BlockedContactsViewModel) : ListAdap
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val glide = GlideApp.with(itemView) val glide = Glide.with(itemView)
val binding = BlockedContactLayoutBinding.bind(itemView) val binding = BlockedContactLayoutBinding.bind(itemView)
fun bind(selectable: SelectableRecipient, toggle: (SelectableRecipient) -> Unit) { fun bind(selectable: SelectableRecipient, toggle: (SelectableRecipient) -> Unit) {

View File

@ -10,7 +10,7 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.ItemSelectableBinding import network.loki.messenger.databinding.ItemSelectableBinding
import org.thoughtcrime.securesms.mms.GlideApp import com.bumptech.glide.Glide
import org.thoughtcrime.securesms.ui.GetString import org.thoughtcrime.securesms.ui.GetString
import java.util.Objects import java.util.Objects
@ -45,7 +45,7 @@ class RadioOptionAdapter<T>(
} }
class ViewHolder<T>(itemView: View): RecyclerView.ViewHolder(itemView) { class ViewHolder<T>(itemView: View): RecyclerView.ViewHolder(itemView) {
val glide = GlideApp.with(itemView) val glide = Glide.with(itemView)
val binding = ItemSelectableBinding.bind(itemView) val binding = ItemSelectableBinding.bind(itemView)
fun bind(option: RadioOption<T>, isSelected: Boolean, toggleSelection: (RadioOption<T>) -> Unit) { fun bind(option: RadioOption<T>, isSelected: Boolean, toggleSelection: (RadioOption<T>) -> Unit) {

View File

@ -65,6 +65,7 @@ import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.truncateIdForDisplay import org.session.libsession.utilities.truncateIdForDisplay
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.avatar.AvatarSelection import org.thoughtcrime.securesms.avatar.AvatarSelection
import org.thoughtcrime.securesms.components.ProfilePictureView import org.thoughtcrime.securesms.components.ProfilePictureView
@ -93,7 +94,6 @@ import org.thoughtcrime.securesms.util.NetworkUtils
import org.thoughtcrime.securesms.util.push import org.thoughtcrime.securesms.util.push
import org.thoughtcrime.securesms.util.show import org.thoughtcrime.securesms.util.show
import java.io.File import java.io.File
import java.security.SecureRandom
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@ -314,7 +314,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
val userConfig = configFactory.user val userConfig = configFactory.user
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
prefs.setProfileAvatarId(SecureRandom().nextInt() ) prefs.setProfileAvatarId(SECURE_RANDOM.nextInt() )
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey) ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
// Attempt to grab the details we require to update the profile picture // Attempt to grab the details we require to update the profile picture

View File

@ -13,7 +13,7 @@ import org.session.libsession.messaging.utilities.AccountId;
import org.thoughtcrime.securesms.components.ProfilePictureView; import org.thoughtcrime.securesms.components.ProfilePictureView;
import org.thoughtcrime.securesms.components.emoji.EmojiImageView; import org.thoughtcrime.securesms.components.emoji.EmojiImageView;
import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View File

@ -8,7 +8,6 @@ import app.cash.copper.Query
import app.cash.copper.flow.observeQuery import app.cash.copper.flow.observeQuery
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -59,15 +58,15 @@ interface ConversationRepository {
fun deleteLocally(recipient: Recipient, message: MessageRecord) fun deleteLocally(recipient: Recipient, message: MessageRecord)
fun deleteAllLocalMessagesInThreadFromSenderOfMessage(messageRecord: MessageRecord) fun deleteAllLocalMessagesInThreadFromSenderOfMessage(messageRecord: MessageRecord)
fun setApproved(recipient: Recipient, isApproved: Boolean) fun setApproved(recipient: Recipient, isApproved: Boolean)
suspend fun deleteForEveryone(threadId: Long, recipient: Recipient, message: MessageRecord): ResultOf<Unit> suspend fun deleteForEveryone(threadId: Long, recipient: Recipient, message: MessageRecord): Result<Unit>
fun buildUnsendRequest(recipient: Recipient, message: MessageRecord): UnsendRequest? fun buildUnsendRequest(recipient: Recipient, message: MessageRecord): UnsendRequest?
suspend fun deleteMessageWithoutUnsendRequest(threadId: Long, messages: Set<MessageRecord>): ResultOf<Unit> suspend fun deleteMessageWithoutUnsendRequest(threadId: Long, messages: Set<MessageRecord>): Result<Unit>
suspend fun banUser(threadId: Long, recipient: Recipient): ResultOf<Unit> suspend fun banUser(threadId: Long, recipient: Recipient): Result<Unit>
suspend fun banAndDeleteAll(threadId: Long, recipient: Recipient): ResultOf<Unit> suspend fun banAndDeleteAll(threadId: Long, recipient: Recipient): Result<Unit>
suspend fun deleteThread(threadId: Long): ResultOf<Unit> suspend fun deleteThread(threadId: Long): Result<Unit>
suspend fun deleteMessageRequest(thread: ThreadRecord): ResultOf<Unit> suspend fun deleteMessageRequest(thread: ThreadRecord): Result<Unit>
suspend fun clearAllMessageRequests(block: Boolean): ResultOf<Unit> suspend fun clearAllMessageRequests(block: Boolean): Result<Unit>
suspend fun acceptMessageRequest(threadId: Long, recipient: Recipient): ResultOf<Unit> suspend fun acceptMessageRequest(threadId: Long, recipient: Recipient): Result<Unit>
fun declineMessageRequest(threadId: Long) fun declineMessageRequest(threadId: Long)
fun hasReceived(threadId: Long): Boolean fun hasReceived(threadId: Long): Boolean
} }
@ -185,7 +184,7 @@ class DefaultConversationRepository @Inject constructor(
threadId: Long, threadId: Long,
recipient: Recipient, recipient: Recipient,
message: MessageRecord message: MessageRecord
): ResultOf<Unit> = suspendCoroutine { continuation -> ): Result<Unit> = suspendCoroutine { continuation ->
buildUnsendRequest(recipient, message)?.let { unsendRequest -> buildUnsendRequest(recipient, message)?.let { unsendRequest ->
MessageSender.send(unsendRequest, recipient.address) MessageSender.send(unsendRequest, recipient.address)
} }
@ -196,10 +195,10 @@ class DefaultConversationRepository @Inject constructor(
OpenGroupApi.deleteMessage(messageServerID, openGroup.room, openGroup.server) OpenGroupApi.deleteMessage(messageServerID, openGroup.room, openGroup.server)
.success { .success {
messageDataProvider.deleteMessage(message.id, !message.isMms) messageDataProvider.deleteMessage(message.id, !message.isMms)
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
}.fail { error -> }.fail { error ->
Log.w("TAG", "Call to OpenGroupApi.deleteForEveryone failed - attempting to resume..") Log.w("TAG", "Call to OpenGroupApi.deleteForEveryone failed - attempting to resume..")
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }
@ -229,10 +228,10 @@ class DefaultConversationRepository @Inject constructor(
} }
SnodeAPI.deleteMessage(publicKey, listOf(serverHash)) SnodeAPI.deleteMessage(publicKey, listOf(serverHash))
.success { .success {
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
}.fail { error -> }.fail { error ->
Log.w("ConversationRepository", "Call to SnodeAPI.deleteMessage failed - attempting to resume..") Log.w("ConversationRepository", "Call to SnodeAPI.deleteMessage failed - attempting to resume..")
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }
} }
@ -250,7 +249,7 @@ class DefaultConversationRepository @Inject constructor(
override suspend fun deleteMessageWithoutUnsendRequest( override suspend fun deleteMessageWithoutUnsendRequest(
threadId: Long, threadId: Long,
messages: Set<MessageRecord> messages: Set<MessageRecord>
): ResultOf<Unit> = suspendCoroutine { continuation -> ): Result<Unit> = suspendCoroutine { continuation ->
val openGroup = lokiThreadDb.getOpenGroupChat(threadId) val openGroup = lokiThreadDb.getOpenGroupChat(threadId)
if (openGroup != null) { if (openGroup != null) {
val messageServerIDs = mutableMapOf<Long, MessageRecord>() val messageServerIDs = mutableMapOf<Long, MessageRecord>()
@ -264,7 +263,7 @@ class DefaultConversationRepository @Inject constructor(
.success { .success {
messageDataProvider.deleteMessage(message.id, !message.isMms) messageDataProvider.deleteMessage(message.id, !message.isMms)
}.fail { error -> }.fail { error ->
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }
} else { } else {
@ -276,22 +275,22 @@ class DefaultConversationRepository @Inject constructor(
} }
} }
} }
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
} }
override suspend fun banUser(threadId: Long, recipient: Recipient): ResultOf<Unit> = override suspend fun banUser(threadId: Long, recipient: Recipient): Result<Unit> =
suspendCoroutine { continuation -> suspendCoroutine { continuation ->
val accountID = recipient.address.toString() val accountID = recipient.address.toString()
val openGroup = lokiThreadDb.getOpenGroupChat(threadId)!! val openGroup = lokiThreadDb.getOpenGroupChat(threadId)!!
OpenGroupApi.ban(accountID, openGroup.room, openGroup.server) OpenGroupApi.ban(accountID, openGroup.room, openGroup.server)
.success { .success {
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
}.fail { error -> }.fail { error ->
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }
override suspend fun banAndDeleteAll(threadId: Long, recipient: Recipient): ResultOf<Unit> = override suspend fun banAndDeleteAll(threadId: Long, recipient: Recipient): Result<Unit> =
suspendCoroutine { continuation -> suspendCoroutine { continuation ->
// Note: This accountId could be the blinded Id // Note: This accountId could be the blinded Id
val accountID = recipient.address.toString() val accountID = recipient.address.toString()
@ -299,25 +298,25 @@ class DefaultConversationRepository @Inject constructor(
OpenGroupApi.banAndDeleteAll(accountID, openGroup.room, openGroup.server) OpenGroupApi.banAndDeleteAll(accountID, openGroup.room, openGroup.server)
.success { .success {
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
}.fail { error -> }.fail { error ->
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }
override suspend fun deleteThread(threadId: Long): ResultOf<Unit> { override suspend fun deleteThread(threadId: Long): Result<Unit> {
sessionJobDb.cancelPendingMessageSendJobs(threadId) sessionJobDb.cancelPendingMessageSendJobs(threadId)
storage.deleteConversation(threadId) storage.deleteConversation(threadId)
return ResultOf.Success(Unit) return Result.success(Unit)
} }
override suspend fun deleteMessageRequest(thread: ThreadRecord): ResultOf<Unit> { override suspend fun deleteMessageRequest(thread: ThreadRecord): Result<Unit> {
sessionJobDb.cancelPendingMessageSendJobs(thread.threadId) sessionJobDb.cancelPendingMessageSendJobs(thread.threadId)
storage.deleteConversation(thread.threadId) storage.deleteConversation(thread.threadId)
return ResultOf.Success(Unit) return Result.success(Unit)
} }
override suspend fun clearAllMessageRequests(block: Boolean): ResultOf<Unit> { override suspend fun clearAllMessageRequests(block: Boolean): Result<Unit> {
threadDb.readerFor(threadDb.unapprovedConversationList).use { reader -> threadDb.readerFor(threadDb.unapprovedConversationList).use { reader ->
while (reader.next != null) { while (reader.next != null) {
deleteMessageRequest(reader.current) deleteMessageRequest(reader.current)
@ -325,18 +324,18 @@ class DefaultConversationRepository @Inject constructor(
if (block) { setBlocked(recipient, true) } if (block) { setBlocked(recipient, true) }
} }
} }
return ResultOf.Success(Unit) return Result.success(Unit)
} }
override suspend fun acceptMessageRequest(threadId: Long, recipient: Recipient): ResultOf<Unit> = suspendCoroutine { continuation -> override suspend fun acceptMessageRequest(threadId: Long, recipient: Recipient): Result<Unit> = suspendCoroutine { continuation ->
storage.setRecipientApproved(recipient, true) storage.setRecipientApproved(recipient, true)
val message = MessageRequestResponse(true) val message = MessageRequestResponse(true)
MessageSender.send(message, Destination.from(recipient.address), isSyncMessage = recipient.isLocalNumber) MessageSender.send(message, Destination.from(recipient.address), isSyncMessage = recipient.isLocalNumber)
.success { .success {
threadDb.setHasSent(threadId, true) threadDb.setHasSent(threadId, true)
continuation.resume(ResultOf.Success(Unit)) continuation.resume(Result.success(Unit))
}.fail { error -> }.fail { error ->
continuation.resumeWithException(error) continuation.resume(Result.failure(error))
} }
} }

View File

@ -1,43 +0,0 @@
package org.thoughtcrime.securesms.repository
import kotlinx.coroutines.CancellationException
sealed class ResultOf<out T> {
data class Success<out R>(val value: R) : ResultOf<R>()
data class Failure(val throwable: Throwable) : ResultOf<Nothing>()
inline fun onFailure(block: (throwable: Throwable) -> Unit) = this.also {
if (this is Failure) {
block(throwable)
}
}
inline fun onSuccess(block: (value: T) -> Unit) = this.also {
if (this is Success) {
block(value)
}
}
inline fun <R> flatMap(mapper: (T) -> R): ResultOf<R> = when (this) {
is Success -> wrap { mapper(value) }
is Failure -> Failure(throwable)
}
fun getOrThrow(): T = when (this) {
is Success -> value
is Failure -> throw throwable
}
companion object {
inline fun <T> wrap(block: () -> T): ResultOf<T> =
try {
Success(block())
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Failure(e)
}
}
}

View File

@ -37,13 +37,13 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.GlideRequests; import com.bumptech.glide.RequestManager;
public class StickerSelectFragment extends Fragment implements LoaderManager.LoaderCallbacks<String[]> { public class StickerSelectFragment extends Fragment implements LoaderManager.LoaderCallbacks<String[]> {
private RecyclerView recyclerView; private RecyclerView recyclerView;
private GlideRequests glideRequests; private RequestManager glideRequests;
private String assetDirectory; private String assetDirectory;
private StickerSelectionListener listener; private StickerSelectionListener listener;
@ -71,7 +71,7 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
public void onActivityCreated(Bundle bundle) { public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle); super.onActivityCreated(bundle);
this.glideRequests = GlideApp.with(this); this.glideRequests = Glide.with(this);
this.assetDirectory = getArguments().getString("assetDirectory"); this.assetDirectory = getArguments().getString("assetDirectory");
getLoaderManager().initLoader(0, null, this); getLoaderManager().initLoader(0, null, this);
@ -99,11 +99,11 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
class StickersAdapter extends RecyclerView.Adapter<StickersAdapter.StickerViewHolder> { class StickersAdapter extends RecyclerView.Adapter<StickersAdapter.StickerViewHolder> {
private final GlideRequests glideRequests; private final RequestManager glideRequests;
private final String[] stickerFiles; private final String[] stickerFiles;
private final LayoutInflater layoutInflater; private final LayoutInflater layoutInflater;
StickersAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @NonNull String[] stickerFiles) { StickersAdapter(@NonNull Context context, @NonNull RequestManager glideRequests, @NonNull String[] stickerFiles) {
this.glideRequests = glideRequests; this.glideRequests = glideRequests;
this.stickerFiles = stickerFiles; this.stickerFiles = stickerFiles;
this.layoutInflater = LayoutInflater.from(context); this.layoutInflater = LayoutInflater.from(context);

View File

@ -11,6 +11,7 @@ import android.os.Parcel;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.SimpleTarget; import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.request.transition.Transition;
@ -20,8 +21,7 @@ import org.thoughtcrime.securesms.imageeditor.Bounds;
import org.thoughtcrime.securesms.imageeditor.Renderer; import org.thoughtcrime.securesms.imageeditor.Renderer;
import org.thoughtcrime.securesms.imageeditor.RendererContext; import org.thoughtcrime.securesms.imageeditor.RendererContext;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.GlideRequest;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -97,8 +97,8 @@ final class UriGlideRenderer implements Renderer {
} }
} }
private GlideRequest<Bitmap> getBitmapGlideRequest(@NonNull Context context) { private RequestBuilder<Bitmap> getBitmapGlideRequest(@NonNull Context context) {
return GlideApp.with(context) return Glide.with(context)
.asBitmap() .asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.override(maxWidth, maxHeight) .override(maxWidth, maxHeight)

View File

@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.ShareActivity;
import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.BitmapUtil;
import java.util.LinkedList; import java.util.LinkedList;
@ -50,7 +50,7 @@ public class DirectShareService extends ChooserTargetService {
if (recipient.getContactPhoto() != null) { if (recipient.getContactPhoto() != null) {
try { try {
avatar = GlideApp.with(this) avatar = Glide.with(this)
.asBitmap() .asBitmap()
.load(recipient.getContactPhoto()) .load(recipient.getContactPhoto())
.circleCrop() .circleCrop()

View File

@ -1,128 +0,0 @@
package org.thoughtcrime.securesms.service;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Preconditions;
import org.thoughtcrime.securesms.home.HomeActivity;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
import network.loki.messenger.R;
public class GenericForegroundService extends Service {
private static final String TAG = GenericForegroundService.class.getSimpleName();
private static final int NOTIFICATION_ID = 827353982;
private static final String EXTRA_TITLE = "extra_title";
private static final String EXTRA_CHANNEL_ID = "extra_channel_id";
private static final String EXTRA_ICON_RES = "extra_icon_res";
private static final String ACTION_START = "start";
private static final String ACTION_STOP = "stop";
private int foregroundCount;
private String activeTitle;
private String activeChannelId;
private int activeIconRes;
@Override
public void onCreate() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
synchronized (GenericForegroundService.class) {
if (intent != null && ACTION_START.equals(intent.getAction())) handleStart(intent);
else if (intent != null && ACTION_STOP.equals(intent.getAction())) handleStop();
else throw new IllegalStateException("Action needs to be START or STOP.");
return START_NOT_STICKY;
}
}
private void handleStart(@NonNull Intent intent) {
String title = Preconditions.checkNotNull(intent.getStringExtra(EXTRA_TITLE));
String channelId = Preconditions.checkNotNull(intent.getStringExtra(EXTRA_CHANNEL_ID));
int iconRes = intent.getIntExtra(EXTRA_ICON_RES, R.drawable.ic_notification);
Log.i(TAG, "handleStart() Title: " + title + " ChannelId: " + channelId);
foregroundCount++;
if (foregroundCount == 1) {
Log.d(TAG, "First request. Title: " + title + " ChannelId: " + channelId);
activeTitle = title;
activeChannelId = channelId;
activeIconRes = iconRes;
}
postObligatoryForegroundNotification(activeTitle, activeChannelId, activeIconRes);
}
private void handleStop() {
Log.i(TAG, "handleStop()");
postObligatoryForegroundNotification(activeTitle, activeChannelId, activeIconRes);
foregroundCount--;
if (foregroundCount == 0) {
Log.d(TAG, "Last request. Ending foreground service.");
stopForeground(true);
stopSelf();
}
}
private void postObligatoryForegroundNotification(String title, String channelId, @DrawableRes int iconRes) {
startForeground(NOTIFICATION_ID, new NotificationCompat.Builder(this, channelId)
.setSmallIcon(iconRes)
.setContentTitle(title)
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, HomeActivity.class), PendingIntent.FLAG_IMMUTABLE))
.build());
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void startForegroundTask(@NonNull Context context, @NonNull String task) {
startForegroundTask(context, task, NotificationChannels.OTHER);
}
public static void startForegroundTask(@NonNull Context context, @NonNull String task, @NonNull String channelId) {
startForegroundTask(context, task, channelId, R.drawable.ic_notification);
}
public static void startForegroundTask(@NonNull Context context, @NonNull String task, @NonNull String channelId, @DrawableRes int iconRes) {
Intent intent = new Intent(context, GenericForegroundService.class);
intent.setAction(ACTION_START);
intent.putExtra(EXTRA_TITLE, task);
intent.putExtra(EXTRA_CHANNEL_ID, channelId);
intent.putExtra(EXTRA_ICON_RES, iconRes);
ContextCompat.startForegroundService(context, intent);
}
public static void stopForegroundTask(@NonNull Context context) {
Intent intent = new Intent(context, GenericForegroundService.class);
intent.setAction(ACTION_STOP);
ContextCompat.startForegroundService(context, intent);
}
}

View File

@ -35,6 +35,7 @@ import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;
import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.ServiceUtil;
import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.TextSecurePreferences;
@ -252,11 +253,18 @@ public class KeyCachingService extends Service {
builder.setContentIntent(buildLaunchIntent()); builder.setContentIntent(buildLaunchIntent());
stopForeground(true); stopForeground(true);
int type = 0;
if (Build.VERSION.SDK_INT >= 34) { if (Build.VERSION.SDK_INT >= 34) {
startForeground(SERVICE_RUNNING_ID, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE); type = ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
} else {
startForeground(SERVICE_RUNNING_ID, builder.build());
} }
ServiceCompat.startForeground(
this,
SERVICE_RUNNING_ID,
builder.build(),
type
);
} }
private PendingIntent buildLockIntent() { private PendingIntent buildLockIntent() {

View File

@ -7,9 +7,12 @@ import android.content.Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.ServiceInfo
import android.media.AudioManager import android.media.AudioManager
import android.os.Build
import android.os.ResultReceiver import android.os.ResultReceiver
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import androidx.core.app.ServiceCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.LifecycleService import androidx.lifecycle.LifecycleService
@ -723,9 +726,11 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
private fun setCallInProgressNotification(type: Int, recipient: Recipient?) { private fun setCallInProgressNotification(type: Int, recipient: Recipient?) {
try { try {
startForeground( ServiceCompat.startForeground(
this,
CallNotificationBuilder.WEBRTC_NOTIFICATION, CallNotificationBuilder.WEBRTC_NOTIFICATION,
CallNotificationBuilder.getCallInProgressNotification(this, type, recipient) CallNotificationBuilder.getCallInProgressNotification(this, type, recipient),
if (Build.VERSION.SDK_INT >= 30) ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE else 0
) )
} catch (e: IllegalStateException) { } catch (e: IllegalStateException) {
Log.e(TAG, "Failed to setCallInProgressNotification as a foreground service for type: ${type}, trying to update instead", e) Log.e(TAG, "Failed to setCallInProgressNotification as a foreground service for type: ${type}, trying to update instead", e)

View File

@ -20,7 +20,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.session.libsession.utilities.MediaTypes; import org.session.libsession.utilities.MediaTypes;
import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.MediaConstraints; import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
@ -98,7 +98,7 @@ public class BitmapUtil {
int attempts = 0; int attempts = 0;
byte[] bytes; byte[] bytes;
Bitmap scaledBitmap = GlideApp.with(context.getApplicationContext()) Bitmap scaledBitmap = Glide.with(context.getApplicationContext())
.asBitmap() .asBitmap()
.load(model) .load(model)
.skipMemoryCache(true) .skipMemoryCache(true)
@ -164,7 +164,7 @@ public class BitmapUtil {
throws BitmapDecodingException throws BitmapDecodingException
{ {
try { try {
return GlideApp.with(context.getApplicationContext()) return Glide.with(context.getApplicationContext())
.asBitmap() .asBitmap()
.load(model) .load(model)
.centerInside() .centerInside()

View File

@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.mms.AudioSlide;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.DocumentSlide; import org.thoughtcrime.securesms.mms.DocumentSlide;
import org.thoughtcrime.securesms.mms.GifSlide; import org.thoughtcrime.securesms.mms.GifSlide;
import org.thoughtcrime.securesms.mms.GlideApp; import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.ImageSlide;
import org.thoughtcrime.securesms.mms.MmsSlide; import org.thoughtcrime.securesms.mms.MmsSlide;
import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.PartAuthority;
@ -115,7 +115,7 @@ public class MediaUtil {
if (MediaUtil.isGif(contentType)) { if (MediaUtil.isGif(contentType)) {
try { try {
GifDrawable drawable = GlideApp.with(context) GifDrawable drawable = Glide.with(context)
.asGif() .asGif()
.skipMemoryCache(true) .skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)

View File

@ -1,8 +1,10 @@
package org.thoughtcrime.securesms.webrtc package org.thoughtcrime.securesms.webrtc
import android.content.Context import android.content.Context
import org.session.libsignal.crypto.shuffledRandom
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.SettableFuture import org.session.libsignal.utilities.SettableFuture
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import org.thoughtcrime.securesms.webrtc.video.Camera import org.thoughtcrime.securesms.webrtc.video.Camera
import org.thoughtcrime.securesms.webrtc.video.CameraEventListener import org.thoughtcrime.securesms.webrtc.video.CameraEventListener
import org.thoughtcrime.securesms.webrtc.video.CameraState import org.thoughtcrime.securesms.webrtc.video.CameraState
@ -22,9 +24,7 @@ import org.webrtc.SurfaceTextureHelper
import org.webrtc.VideoSink import org.webrtc.VideoSink
import org.webrtc.VideoSource import org.webrtc.VideoSource
import org.webrtc.VideoTrack import org.webrtc.VideoTrack
import java.security.SecureRandom
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import kotlin.random.asKotlinRandom
class PeerConnectionWrapper(private val context: Context, class PeerConnectionWrapper(private val context: Context,
private val factory: PeerConnectionFactory, private val factory: PeerConnectionFactory,
@ -49,8 +49,7 @@ class PeerConnectionWrapper(private val context: Context,
private var isInitiator = false private var isInitiator = false
private fun initPeerConnection() { private fun initPeerConnection() {
val random = SecureRandom().asKotlinRandom() val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffledRandom().take(2).map { sub ->
val iceServers = listOf("freyr","angus","hereford","holstein", "brahman").shuffled(random).take(2).map { sub ->
PeerConnection.IceServer.builder("turn:$sub.getsession.org") PeerConnection.IceServer.builder("turn:$sub.getsession.org")
.setUsername("session202111") .setUsername("session202111")
.setPassword("053c268164bc7bd7") .setPassword("053c268164bc7bd7")

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/conversation_view_background" android:background="@drawable/conversation_unread_background"
android:contentDescription="@string/AccessibilityId_message_request_banner" android:contentDescription="@string/AccessibilityId_message_request_banner"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
@ -19,7 +19,8 @@
android:layout_marginStart="@dimen/medium_spacing" android:layout_marginStart="@dimen/medium_spacing"
android:padding="10dp" android:padding="10dp"
android:src="@drawable/ic_outline_message_requests_24" android:src="@drawable/ic_outline_message_requests_24"
app:circleColor="#585858" android:tint="?unreadIndicatorTextColor"
app:circleColor="?unreadIndicatorBackgroundColor"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -47,7 +48,7 @@
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginStart="4dp" android:layout_marginStart="4dp"
android:background="@drawable/circle_tintable" android:background="@drawable/circle_tintable"
android:backgroundTint="#585858" android:backgroundTint="?unreadIndicatorBackgroundColor"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/conversationViewDisplayNameTextView" app:layout_constraintStart_toEndOf="@id/conversationViewDisplayNameTextView"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
@ -57,30 +58,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:textColor="@color/white" android:textColor="?unreadIndicatorTextColor"
android:textSize="@dimen/very_small_font_size" android:textSize="@dimen/very_small_font_size"
android:textStyle="bold" android:textStyle="bold"
tools:text="8" /> tools:text="8" />
</RelativeLayout> </RelativeLayout>
<TextView
android:id="@+id/timestampTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/medium_spacing"
android:alpha="0.4"
android:ellipsize="end"
android:maxLines="1"
android:textAlignment="textEnd"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toEndOf="@id/unreadCountIndicator"
app:layout_constraintTop_toTopOf="parent"
tools:text="11 Apr, 9:41 AM" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<bool name="enable_alarm_manager">false</bool>
<bool name="enable_job_service">true</bool> <bool name="enable_job_service">true</bool>
</resources> </resources>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<bool name="enable_alarm_manager">true</bool>
<bool name="enable_job_service">false</bool> <bool name="enable_job_service">false</bool>
<attr name="searchBackgroundColor" format="color"/> <attr name="searchBackgroundColor" format="color"/>
<attr name="searchIconColor" format="color|reference"/> <attr name="searchIconColor" format="color|reference"/>

View File

@ -0,0 +1,52 @@
package org.session.libsignal.utilities
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class SnodeVersionTest(
private val v1: String,
private val v2: String,
private val expectedEqual: Boolean,
private val expectedLessThan: Boolean
) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{index}: testVersion({0},{1}) = (equalTo: {2}, lessThan: {3})")
fun data(): Collection<Array<Any>> = listOf(
arrayOf("1", "1", true, false),
arrayOf("1", "2", false, true),
arrayOf("2", "1", false, false),
arrayOf("1.0", "1", true, false),
arrayOf("1.0", "1.0.0", true, false),
arrayOf("1.0", "1.0.0.0", true, false),
arrayOf("1.0", "1.0.0.0.0.0", true, false),
arrayOf("2.0", "1.2", false, false),
arrayOf("1.0.0.0", "1.0.0.1", false, true),
// Snode.Version only considers the first 4 integers, so these are equal
arrayOf("1.0.0.0", "1.0.0.0.1", true, false),
arrayOf("1.0.0.1", "1.0.0.1", true, false),
// parts can be up to 16 bits, around 65,535
arrayOf("65535.65535.65535.65535", "65535.65535.65535.65535", true, false),
// values higher than this are coerced to 65535 (:
arrayOf("65535.65535.65535.65535", "65535.65535.65535.99999", true, false),
)
}
@Test
fun testVersionEqual() {
val version1 = Snode.Version(v1)
val version2 = Snode.Version(v2)
assertThat(version1 == version2, equalTo(expectedEqual))
}
@Test
fun testVersionOnePartLessThan() {
val version1 = Snode.Version(v1)
val version2 = Snode.Version(v2)
assertThat(version1 < version2, equalTo(expectedLessThan))
}
}

View File

@ -3,14 +3,12 @@ package org.thoughtcrime.securesms.conversation.v2
import com.goterl.lazysodium.utils.KeyPair import com.goterl.lazysodium.utils.KeyPair
import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.hamcrest.CoreMatchers.endsWith import org.hamcrest.CoreMatchers.endsWith
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.notNullValue import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.CoreMatchers.nullValue import org.hamcrest.CoreMatchers.nullValue
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test import org.junit.Test
import org.mockito.Mockito import org.mockito.Mockito
import org.mockito.Mockito.anyLong import org.mockito.Mockito.anyLong
@ -20,14 +18,11 @@ import org.mockito.kotlin.any
import org.mockito.kotlin.mock import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever import org.mockito.kotlin.whenever
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.BaseViewModelTest import org.thoughtcrime.securesms.BaseViewModelTest
import org.thoughtcrime.securesms.NoOpLogger
import org.thoughtcrime.securesms.database.MmsDatabase import org.thoughtcrime.securesms.database.MmsDatabase
import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.repository.ConversationRepository import org.thoughtcrime.securesms.repository.ConversationRepository
import org.thoughtcrime.securesms.repository.ResultOf
class ConversationViewModelTest: BaseViewModelTest() { class ConversationViewModelTest: BaseViewModelTest() {
@ -107,7 +102,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
val message = mock<MessageRecord>() val message = mock<MessageRecord>()
val error = Throwable() val error = Throwable()
whenever(repository.deleteForEveryone(anyLong(), any(), any())) whenever(repository.deleteForEveryone(anyLong(), any(), any()))
.thenReturn(ResultOf.Failure(error)) .thenReturn(Result.failure(error))
viewModel.deleteForEveryone(message) viewModel.deleteForEveryone(message)
@ -120,7 +115,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
val message = mock<MessageRecord>() val message = mock<MessageRecord>()
val error = Throwable() val error = Throwable()
whenever(repository.deleteMessageWithoutUnsendRequest(anyLong(), anySet())) whenever(repository.deleteMessageWithoutUnsendRequest(anyLong(), anySet()))
.thenReturn(ResultOf.Failure(error)) .thenReturn(Result.failure(error))
viewModel.deleteMessagesWithoutUnsendRequest(setOf(message)) viewModel.deleteMessagesWithoutUnsendRequest(setOf(message))
@ -130,7 +125,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
@Test @Test
fun `should emit error message on ban user failure`() = runBlockingTest { fun `should emit error message on ban user failure`() = runBlockingTest {
val error = Throwable() val error = Throwable()
whenever(repository.banUser(anyLong(), any())).thenReturn(ResultOf.Failure(error)) whenever(repository.banUser(anyLong(), any())).thenReturn(Result.failure(error))
viewModel.banUser(recipient) viewModel.banUser(recipient)
@ -139,7 +134,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
@Test @Test
fun `should emit a message on ban user success`() = runBlockingTest { fun `should emit a message on ban user success`() = runBlockingTest {
whenever(repository.banUser(anyLong(), any())).thenReturn(ResultOf.Success(Unit)) whenever(repository.banUser(anyLong(), any())).thenReturn(Result.success(Unit))
viewModel.banUser(recipient) viewModel.banUser(recipient)
@ -152,7 +147,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
@Test @Test
fun `should emit error message on ban user and delete all failure`() = runBlockingTest { fun `should emit error message on ban user and delete all failure`() = runBlockingTest {
val error = Throwable() val error = Throwable()
whenever(repository.banAndDeleteAll(anyLong(), any())).thenReturn(ResultOf.Failure(error)) whenever(repository.banAndDeleteAll(anyLong(), any())).thenReturn(Result.failure(error))
viewModel.banAndDeleteAll(messageRecord) viewModel.banAndDeleteAll(messageRecord)
@ -161,7 +156,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
@Test @Test
fun `should emit a message on ban user and delete all success`() = runBlockingTest { fun `should emit a message on ban user and delete all success`() = runBlockingTest {
whenever(repository.banAndDeleteAll(anyLong(), any())).thenReturn(ResultOf.Success(Unit)) whenever(repository.banAndDeleteAll(anyLong(), any())).thenReturn(Result.success(Unit))
viewModel.banAndDeleteAll(messageRecord) viewModel.banAndDeleteAll(messageRecord)
@ -188,7 +183,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
@Test @Test
fun `should remove shown message`() = runBlockingTest { fun `should remove shown message`() = runBlockingTest {
// Given that a message is generated // Given that a message is generated
whenever(repository.banUser(anyLong(), any())).thenReturn(ResultOf.Success(Unit)) whenever(repository.banUser(anyLong(), any())).thenReturn(Result.success(Unit))
viewModel.banUser(recipient) viewModel.banUser(recipient)
assertThat(viewModel.uiState.value.uiMessages.size, equalTo(1)) assertThat(viewModel.uiState.value.uiMessages.size, equalTo(1))
// When the message is shown // When the message is shown

View File

@ -17,13 +17,15 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
classpath "com.google.gms:google-services:$googleServicesVersion" classpath "com.google.gms:google-services:$googleServicesVersion"
classpath "com.squareup:javapoet:1.13.0" classpath "com.squareup:javapoet:1.13.0"
classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion"
if (project.hasProperty('huawei')) classpath 'com.huawei.agconnect:agcp:1.9.1.300' if (project.hasProperty('huawei')) classpath 'com.huawei.agconnect:agcp:1.9.1.300'
} }
} }
// List plugins AND their versions here, but don't apply. This allows you to use the plugin
// in your module without specifying the version.
plugins { plugins {
id("com.google.dagger.hilt.android") version "2.44" apply false id 'com.google.devtools.ksp' version "$kotlinVersion-1.0.20" apply false
id 'com.google.dagger.hilt.android' version "$daggerHiltVersion" apply false
} }
allprojects { allprojects {

View File

@ -14,19 +14,19 @@
android.enableJetifier=true android.enableJetifier=true
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
#org.gradle.unsafe.configuration-cache=true
gradlePluginVersion=7.3.1 gradlePluginVersion=7.3.1
googleServicesVersion=4.3.12 googleServicesVersion=4.3.12
kotlinVersion=1.8.21 kotlinVersion=1.9.24
android.useAndroidX=true android.useAndroidX=true
appcompatVersion=1.6.1 appcompatVersion=1.6.1
coreVersion=1.13.1 coreVersion=1.13.1
composeVersion=1.6.4 composeVersion=1.6.4
coroutinesVersion=1.6.4 coroutinesVersion=1.6.4
curve25519Version=0.6.0 curve25519Version=0.6.0
daggerVersion=2.46.1 jetpackHiltVersion=1.2.0
glideVersion=4.11.0 daggerHiltVersion=2.51.1
glideVersion=4.16.0
jacksonDatabindVersion=2.9.8 jacksonDatabindVersion=2.9.8
junitVersion=4.13.2 junitVersion=4.13.2
kotlinxJsonVersion=1.3.3 kotlinxJsonVersion=1.3.3

View File

@ -2,6 +2,8 @@ plugins {
id 'com.android.library' id 'com.android.library'
id 'kotlin-android' id 'kotlin-android'
id 'kotlinx-serialization' id 'kotlinx-serialization'
id 'com.google.devtools.ksp'
id 'com.google.dagger.hilt.android'
} }
android { android {
@ -21,6 +23,11 @@ dependencies {
implementation project(":libsignal") implementation project(":libsignal")
implementation project(":libsession-util") implementation project(":libsession-util")
implementation project(":liblazysodium") implementation project(":liblazysodium")
implementation("com.google.dagger:hilt-android:$daggerHiltVersion")
ksp("com.google.dagger:hilt-compiler:$daggerHiltVersion")
ksp("androidx.hilt:hilt-compiler:$jetpackHiltVersion")
implementation "net.java.dev.jna:jna:5.12.1@aar" implementation "net.java.dev.jna:jna:5.12.1@aar"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "androidx.core:core-ktx:$coreVersion" implementation "androidx.core:core-ktx:$coreVersion"
@ -28,7 +35,6 @@ dependencies {
implementation "androidx.preference:preference-ktx:$preferenceVersion" implementation "androidx.preference:preference-ktx:$preferenceVersion"
implementation "com.google.android.material:material:$materialVersion" implementation "com.google.android.material:material:$materialVersion"
implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "com.google.protobuf:protobuf-java:$protobufVersion"
implementation "com.google.dagger:hilt-android:$daggerVersion"
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "com.github.bumptech.glide:glide:$glideVersion" implementation "com.github.bumptech.glide:glide:$glideVersion"

View File

@ -63,7 +63,6 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
// return a list of batch request objects // return a list of batch request objects
val snodeMessage = MessageSender.buildConfigMessageToSnode(destination.destinationPublicKey(), message) val snodeMessage = MessageSender.buildConfigMessageToSnode(destination.destinationPublicKey(), message)
val authenticated = SnodeAPI.buildAuthenticatedStoreBatchInfo( val authenticated = SnodeAPI.buildAuthenticatedStoreBatchInfo(
destination.destinationPublicKey(),
config.configNamespace(), config.configNamespace(),
snodeMessage snodeMessage
) ?: return@map null // this entry will be null otherwise ) ?: return@map null // this entry will be null otherwise

View File

@ -12,11 +12,11 @@ import org.session.libsession.utilities.Util.equals
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.streams.ProfileCipherInputStream import org.session.libsignal.streams.ProfileCipherInputStream
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.security.SecureRandom
import java.util.concurrent.ConcurrentSkipListSet import java.util.concurrent.ConcurrentSkipListSet
class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipientAddress: Address): Job { class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipientAddress: Address): Job {
@ -64,7 +64,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize()) Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize())
if (recipient.isLocalNumber) { if (recipient.isLocalNumber) {
setProfileAvatarId(context, SecureRandom().nextInt()) setProfileAvatarId(context, SECURE_RANDOM.nextInt())
setProfilePictureURL(context, null) setProfilePictureURL(context, null)
} }
@ -83,7 +83,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient
decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address)) decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address))
if (recipient.isLocalNumber) { if (recipient.isLocalNumber) {
setProfileAvatarId(context, SecureRandom().nextInt()) setProfileAvatarId(context, SECURE_RANDOM.nextInt())
setProfilePictureURL(context, profileAvatar) setProfilePictureURL(context, profileAvatar)
} }

View File

@ -10,7 +10,7 @@ import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.MessageReceiveParameters import org.session.libsession.messaging.jobs.MessageReceiveParameters
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.crypto.getRandomElementOrNull import org.session.libsignal.crypto.secureRandomOrNull
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Namespace import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.defaultRequiresAuth import org.session.libsignal.utilities.defaultRequiresAuth
@ -104,7 +104,7 @@ class ClosedGroupPollerV2 {
fun poll(groupPublicKey: String): Promise<Unit, Exception> { fun poll(groupPublicKey: String): Promise<Unit, Exception> {
if (!isPolling(groupPublicKey)) { return Promise.of(Unit) } if (!isPolling(groupPublicKey)) { return Promise.of(Unit) }
val promise = SnodeAPI.getSwarm(groupPublicKey).bind { swarm -> val promise = SnodeAPI.getSwarm(groupPublicKey).bind { swarm ->
val snode = swarm.getRandomElementOrNull() ?: throw InsufficientSnodesException() // Should be cryptographically secure val snode = swarm.secureRandomOrNull() ?: throw InsufficientSnodesException() // Should be cryptographically secure
if (!isPolling(groupPublicKey)) { throw PollingCanceledException() } if (!isPolling(groupPublicKey)) { throw PollingCanceledException() }
val currentForkInfo = SnodeAPI.forkInfo val currentForkInfo = SnodeAPI.forkInfo
when { when {

View File

@ -19,8 +19,6 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.MessageReceiveParameters import org.session.libsession.messaging.jobs.MessageReceiveParameters
import org.session.libsession.messaging.messages.control.SharedConfigurationMessage
import org.session.libsession.messaging.sending_receiving.MessageReceiver
import org.session.libsession.snode.RawResponse import org.session.libsession.snode.RawResponse
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeModule import org.session.libsession.snode.SnodeModule
@ -29,7 +27,7 @@ import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Namespace import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.Snode import org.session.libsignal.utilities.Snode
import java.security.SecureRandom import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.util.Timer import java.util.Timer
import java.util.TimerTask import java.util.TimerTask
import kotlin.time.Duration.Companion.days import kotlin.time.Duration.Companion.days
@ -106,7 +104,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
val swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf() val swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf()
val unusedSnodes = swarm.subtract(usedSnodes) val unusedSnodes = swarm.subtract(usedSnodes)
if (unusedSnodes.isNotEmpty()) { if (unusedSnodes.isNotEmpty()) {
val index = SecureRandom().nextInt(unusedSnodes.size) val index = SECURE_RANDOM.nextInt(unusedSnodes.size)
val nextSnode = unusedSnodes.elementAt(index) val nextSnode = unusedSnodes.elementAt(index)
usedSnodes.add(nextSnode) usedSnodes.add(nextSnode)
Log.d(TAG, "Polling $nextSnode.") Log.d(TAG, "Polling $nextSnode.")
@ -142,8 +140,7 @@ class Poller(private val configFactory: ConfigFactoryProtocol, debounceTimer: Ti
val messages = rawMessages["messages"] as? List<*> val messages = rawMessages["messages"] as? List<*>
val processed = if (!messages.isNullOrEmpty()) { val processed = if (!messages.isNullOrEmpty()) {
SnodeAPI.updateLastMessageHashValueIfPossible(snode, userPublicKey, messages, namespace) SnodeAPI.updateLastMessageHashValueIfPossible(snode, userPublicKey, messages, namespace)
SnodeAPI.removeDuplicates(userPublicKey, messages, namespace, true).mapNotNull { messageBody -> SnodeAPI.removeDuplicates(userPublicKey, messages, namespace, true).mapNotNull { rawMessageAsJSON ->
val rawMessageAsJSON = messageBody as? Map<*, *> ?: return@mapNotNull null
val hashValue = rawMessageAsJSON["hash"] as? String ?: return@mapNotNull null val hashValue = rawMessageAsJSON["hash"] as? String ?: return@mapNotNull null
val b64EncodedBody = rawMessageAsJSON["data"] as? String ?: return@mapNotNull null val b64EncodedBody = rawMessageAsJSON["data"] as? String ?: return@mapNotNull null
val timestamp = rawMessageAsJSON["t"] as? Long ?: SnodeAPI.nowWithOffset val timestamp = rawMessageAsJSON["t"] as? Long ?: SnodeAPI.nowWithOffset

View File

@ -28,7 +28,7 @@ object MessageWrapper {
val webSocketMessage = createWebSocketMessage(envelope) val webSocketMessage = createWebSocketMessage(envelope)
return webSocketMessage.toByteArray() return webSocketMessage.toByteArray()
} catch (e: Exception) { } catch (e: Exception) {
throw if (e is Error) { e } else { Error.FailedToWrapData } throw if (e is Error) e else Error.FailedToWrapData
} }
} }
@ -49,15 +49,15 @@ object MessageWrapper {
private fun createWebSocketMessage(envelope: Envelope): WebSocketMessage { private fun createWebSocketMessage(envelope: Envelope): WebSocketMessage {
try { try {
val requestBuilder = WebSocketRequestMessage.newBuilder() return WebSocketMessage.newBuilder().apply {
requestBuilder.verb = "PUT" request = WebSocketRequestMessage.newBuilder().apply {
requestBuilder.path = "/api/v1/message" verb = "PUT"
requestBuilder.id = SecureRandom.getInstance("SHA1PRNG").nextLong() path = "/api/v1/message"
requestBuilder.body = envelope.toByteString() id = SecureRandom.getInstance("SHA1PRNG").nextLong()
val messageBuilder = WebSocketMessage.newBuilder() body = envelope.toByteString()
messageBuilder.request = requestBuilder.build() }.build()
messageBuilder.type = WebSocketMessage.Type.REQUEST type = WebSocketMessage.Type.REQUEST
return messageBuilder.build() }.build()
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.") Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.")
throw Error.FailedToWrapEnvelopeInWebSocketMessage throw Error.FailedToWrapEnvelopeInWebSocketMessage

View File

@ -10,11 +10,10 @@ import okhttp3.Request
import org.session.libsession.messaging.file_server.FileServerApi import org.session.libsession.messaging.file_server.FileServerApi
import org.session.libsession.utilities.AESGCM import org.session.libsession.utilities.AESGCM
import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsession.utilities.AESGCM.EncryptionResult
import org.session.libsession.utilities.Util
import org.session.libsession.utilities.getBodyForOnionRequest import org.session.libsession.utilities.getBodyForOnionRequest
import org.session.libsession.utilities.getHeadersForOnionRequest import org.session.libsession.utilities.getHeadersForOnionRequest
import org.session.libsignal.crypto.getRandomElement import org.session.libsignal.crypto.secureRandom
import org.session.libsignal.crypto.getRandomElementOrNull import org.session.libsignal.crypto.secureRandomOrNull
import org.session.libsignal.database.LokiAPIDatabaseProtocol import org.session.libsignal.database.LokiAPIDatabaseProtocol
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Broadcaster import org.session.libsignal.utilities.Broadcaster
@ -149,7 +148,7 @@ object OnionRequestAPI {
val reusableGuardSnodeCount = reusableGuardSnodes.count() val reusableGuardSnodeCount = reusableGuardSnodes.count()
if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() } if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() }
fun getGuardSnode(): Promise<Snode, Exception> { fun getGuardSnode(): Promise<Snode, Exception> {
val candidate = unusedSnodes.getRandomElementOrNull() val candidate = unusedSnodes.secureRandomOrNull()
?: return Promise.ofFail(InsufficientSnodesException()) ?: return Promise.ofFail(InsufficientSnodesException())
unusedSnodes = unusedSnodes.minus(candidate) unusedSnodes = unusedSnodes.minus(candidate)
Log.d("Loki", "Testing guard snode: $candidate.") Log.d("Loki", "Testing guard snode: $candidate.")
@ -191,7 +190,7 @@ object OnionRequestAPI {
// Don't test path snodes as this would reveal the user's IP to them // Don't test path snodes as this would reveal the user's IP to them
guardSnodes.minus(reusableGuardSnodes).map { guardSnode -> guardSnodes.minus(reusableGuardSnodes).map { guardSnode ->
val result = listOf( guardSnode ) + (0 until (pathSize - 1)).mapIndexed() { index, _ -> val result = listOf( guardSnode ) + (0 until (pathSize - 1)).mapIndexed() { index, _ ->
var pathSnode = unusedSnodes.getRandomElement() var pathSnode = unusedSnodes.secureRandom()
// remove the snode from the unused list and return it // remove the snode from the unused list and return it
unusedSnodes = unusedSnodes.minus(pathSnode) unusedSnodes = unusedSnodes.minus(pathSnode)
@ -228,9 +227,9 @@ object OnionRequestAPI {
OnionRequestAPI.guardSnodes = guardSnodes OnionRequestAPI.guardSnodes = guardSnodes
fun getPath(paths: List<Path>): Path { fun getPath(paths: List<Path>): Path {
return if (snodeToExclude != null) { return if (snodeToExclude != null) {
paths.filter { !it.contains(snodeToExclude) }.getRandomElement() paths.filter { !it.contains(snodeToExclude) }.secureRandom()
} else { } else {
paths.getRandomElement() paths.secureRandom()
} }
} }
when { when {
@ -273,7 +272,7 @@ object OnionRequestAPI {
path.removeAt(snodeIndex) path.removeAt(snodeIndex)
val unusedSnodes = SnodeAPI.snodePool.minus(oldPaths.flatten()) val unusedSnodes = SnodeAPI.snodePool.minus(oldPaths.flatten())
if (unusedSnodes.isEmpty()) { throw InsufficientSnodesException() } if (unusedSnodes.isEmpty()) { throw InsufficientSnodesException() }
path.add(unusedSnodes.getRandomElement()) path.add(unusedSnodes.secureRandom())
// Don't test the new snode as this would reveal the user's IP // Don't test the new snode as this would reveal the user's IP
oldPaths.removeAt(pathIndex) oldPaths.removeAt(pathIndex)
val newPaths = oldPaths + listOf( path ) val newPaths = oldPaths + listOf( path )

Some files were not shown because too many files have changed in this diff Show More