Fix issue with gif search and emoji loading on lowmem devices.

fork-5.53.8
Alex Hart 2021-05-05 09:59:05 -03:00 zatwierdzone przez Cody Henthorne
rodzic 5e2a3ac644
commit 02d060ca0a
5 zmienionych plików z 85 dodań i 10 usunięć

Wyświetl plik

@ -135,6 +135,7 @@ android {
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
buildConfigField "String", "DEFAULT_CURRENCIES", "\"EUR,AUD,GBP,CAD,CNY\""
buildConfigField "int[]", "MOBILE_COIN_REGIONS", "new int[]{44}"
buildConfigField "String", "GIPHY_API_KEY", "\"3o6ZsYH6U6Eri53TXy\""
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'

Wyświetl plik

@ -15,18 +15,22 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiDrawInfo;
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
import org.thoughtcrime.securesms.emoji.EmojiBitmapDecoder;
import org.thoughtcrime.securesms.emoji.EmojiSource;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.util.DeviceProperties;
class EmojiProvider {
@ -89,12 +93,16 @@ class EmojiProvider {
return null;
}
final EmojiSource source = EmojiSource.getLatest();
final EmojiDrawable drawable = new EmojiDrawable(source, drawInfo);
final int lowMemoryDecodeScale = DeviceProperties.isLowMemoryDevice(context) ? 2 : 1;
final EmojiSource source = EmojiSource.getLatest();
final EmojiDrawable drawable = new EmojiDrawable(source, drawInfo, lowMemoryDecodeScale);
GlideApp.with(context)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.load(drawInfo.getPage().getModel())
.priority(Priority.HIGH)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.apply(new RequestOptions().set(EmojiBitmapDecoder.OPTION, lowMemoryDecodeScale))
.addListener(new RequestListener<Bitmap>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
@ -130,12 +138,12 @@ class EmojiProvider {
return (int) intrinsicHeight;
}
EmojiDrawable(@NonNull EmojiSource source, @NonNull EmojiDrawInfo info) {
this.intrinsicWidth = source.getMetrics().getRawWidth() * source.getDecodeScale();
this.intrinsicHeight = source.getMetrics().getRawHeight() * source.getDecodeScale();
EmojiDrawable(@NonNull EmojiSource source, @NonNull EmojiDrawInfo info, int lowMemoryDecodeScale) {
this.intrinsicWidth = (source.getMetrics().getRawWidth() * source.getDecodeScale()) / lowMemoryDecodeScale;
this.intrinsicHeight = (source.getMetrics().getRawHeight() * source.getDecodeScale()) / lowMemoryDecodeScale;
final int glyphWidth = (int) (source.getMetrics().getRawWidth() * source.getDecodeScale());
final int glyphHeight = (int) (source.getMetrics().getRawHeight() * source.getDecodeScale());
final int glyphWidth = (int) (intrinsicWidth);
final int glyphHeight = (int) (intrinsicHeight);
final int index = info.getIndex();
final int emojiPerRow = source.getMetrics().getPerRow();
final int xStart = (index % emojiPerRow) * glyphWidth;

Wyświetl plik

@ -0,0 +1,40 @@
package org.thoughtcrime.securesms.emoji
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.bumptech.glide.load.Option
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.ResourceDecoder
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapResource
import java.io.InputStream
/**
* Allows fine grain control over how we decode Emoji pages via a scale factor.
*
* This can be set via RequestOptions on a Glide request:
*
* ```
* .apply(RequestOptions().set(EmojiBitmapDecoder.OPTION, inSampleSize)
* ```
*/
class EmojiBitmapDecoder(private val bitmapPool: BitmapPool) : ResourceDecoder<InputStream, Bitmap> {
override fun handles(source: InputStream, options: Options): Boolean {
return options.get(OPTION)?.let { it > 1 } ?: false
}
override fun decode(source: InputStream, width: Int, height: Int, options: Options): Resource<Bitmap>? {
val bitmapOptions = BitmapFactory.Options()
bitmapOptions.inSampleSize = requireNotNull(options.get(OPTION))
return BitmapResource.obtain(BitmapFactory.decodeStream(source, null, bitmapOptions), bitmapPool)
}
companion object {
@JvmField
val OPTION: Option<Int> = Option.memory("emoji_sample_size", 1)
}
}

Wyświetl plik

@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.paging.PagedDataSource;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.giph.model.GiphyImage;
import org.thoughtcrime.securesms.giph.model.GiphyResponse;
@ -27,6 +28,20 @@ import okhttp3.Response;
*/
final class GiphyMp4PagedDataSource implements PagedDataSource<GiphyImage> {
private static final Uri BASE_GIPHY_URI = Uri.parse("https://api.giphy.com/v1/gifs/")
.buildUpon()
.appendQueryParameter("api_key", BuildConfig.GIPHY_API_KEY)
.build();
private static final Uri TRENDING_URI = BASE_GIPHY_URI.buildUpon()
.appendPath("trending")
.build();
private static final Uri SEARCH_URI = BASE_GIPHY_URI.buildUpon()
.appendPath("search")
.build();
private static final String TAG = Log.tag(GiphyMp4PagedDataSource.class);
private final String searchString;
@ -64,7 +79,7 @@ final class GiphyMp4PagedDataSource implements PagedDataSource<GiphyImage> {
String url;
if (TextUtils.isEmpty(searchString)) url = getTrendingUrl(start, length);
else url = getSearchUrl(start, length, Uri.encode(searchString));
else url = getSearchUrl(start, length, searchString);
Request request = new Request.Builder().url(url).build();
@ -83,10 +98,19 @@ final class GiphyMp4PagedDataSource implements PagedDataSource<GiphyImage> {
}
private String getTrendingUrl(int start, int length) {
return "https://api.giphy.com/v1/gifs/trending?api_key=3o6ZsYH6U6Eri53TXy&offset=" + start + "&limit=" + length;
return TRENDING_URI.buildUpon()
.appendQueryParameter("offset", String.valueOf(start))
.appendQueryParameter("limit", String.valueOf(length))
.build()
.toString();
}
private String getSearchUrl(int start, int length, @NonNull String query) {
return "https://api.giphy.com/v1/gifs/search?api_key=3o6ZsYH6U6Eri53TXy&offset=" + start + "&limit=" + length + "&q=" + Uri.encode(query);
return SEARCH_URI.buildUpon()
.appendQueryParameter("offset", String.valueOf(start))
.appendQueryParameter("limit", String.valueOf(length))
.appendQueryParameter("q", query)
.build()
.toString();
}
}

Wyświetl plik

@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.blurhash.BlurHashResourceDecoder;
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
import org.thoughtcrime.securesms.crypto.AttachmentSecret;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
import org.thoughtcrime.securesms.emoji.EmojiBitmapDecoder;
import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl;
import org.thoughtcrime.securesms.glide.ChunkedImageUrlLoader;
import org.thoughtcrime.securesms.glide.ContactPhotoLoader;
@ -82,6 +83,7 @@ public class SignalGlideModule extends AppGlideModule {
ApngBufferCacheDecoder apngBufferCacheDecoder = new ApngBufferCacheDecoder();
ApngStreamCacheDecoder apngStreamCacheDecoder = new ApngStreamCacheDecoder(apngBufferCacheDecoder);
registry.prepend(InputStream.class, Bitmap.class, new EmojiBitmapDecoder(glide.getBitmapPool()));
registry.prepend(InputStream.class, APNGDecoder.class, apngStreamCacheDecoder);
registry.prepend(ByteBuffer.class, APNGDecoder.class, apngBufferCacheDecoder);
registry.prepend(APNGDecoder.class, new EncryptedApngCacheEncoder(secret));