Revert emoji cache to old pattern.

This commit is contained in:
Alex Hart 2021-05-06 18:47:36 -03:00 committed by GitHub
parent cb9ab61b6b
commit 138f9476ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 103 deletions

View file

@ -15,22 +15,16 @@ 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.EmojiPage;
import org.thoughtcrime.securesms.emoji.EmojiPageCache;
import org.thoughtcrime.securesms.emoji.EmojiSource;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.util.DeviceProperties;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import java.util.concurrent.ExecutionException;
class EmojiProvider {
@ -96,27 +90,20 @@ class EmojiProvider {
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())
.priority(Priority.HIGH)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.apply(new RequestOptions().set(EmojiPage.IN_SAMPLE_SIZE, lowMemoryDecodeScale))
.addListener(new RequestListener<Bitmap>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
Log.d(TAG, "Failed to load emoji bitmap resource", e);
return false;
}
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
ThreadUtil.runOnMain(() -> drawable.setBitmap(resource));
return true;
}
})
.submit();
EmojiPageCache.INSTANCE
.load(context, drawInfo.getPage(), lowMemoryDecodeScale)
.addListener(new FutureTaskListener<Bitmap>() {
@Override
public void onSuccess(Bitmap result) {
ThreadUtil.runOnMain(() -> drawable.setBitmap(result));
}
@Override
public void onFailure(ExecutionException exception) {
Log.d(TAG, "Failed to load emoji bitmap resource", exception);
}
});
return drawable;
}

View file

@ -1,85 +1,17 @@
package org.thoughtcrime.securesms.emoji
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.Key
import com.bumptech.glide.load.Option
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import org.thoughtcrime.securesms.mms.PartAuthority
import java.io.InputStream
import java.security.MessageDigest
typealias EmojiPageFactory = (Uri) -> EmojiPage
sealed class EmojiPage(private val uri: Uri) : Key {
sealed class EmojiPage(open val uri: Uri) : Key {
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("EmojiPage".encodeToByteArray())
messageDigest.update(uri.toString().encodeToByteArray())
}
data class Asset(private val uri: Uri) : EmojiPage(uri)
data class Disk(private val uri: Uri) : EmojiPage(uri)
class Loader(private val context: Context) : ModelLoader<EmojiPage, Bitmap> {
override fun buildLoadData(
model: EmojiPage,
width: Int,
height: Int,
options: Options
): ModelLoader.LoadData<Bitmap> {
return ModelLoader.LoadData(model, Fetcher(context, model, options.get(IN_SAMPLE_SIZE) ?: 1))
}
override fun handles(model: EmojiPage): Boolean = true
class Factory(private val context: Context) : ModelLoaderFactory<EmojiPage, Bitmap> {
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<EmojiPage, Bitmap> {
return Loader(context)
}
override fun teardown() = Unit
}
}
class Fetcher(private val context: Context, private val model: EmojiPage, private val inSampleSize: Int) : DataFetcher<Bitmap> {
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in Bitmap>) {
try {
val inputStream: InputStream = when (model) {
is Asset -> context.assets.open(model.uri.toString().replace("file:///android_asset/", ""))
is Disk -> EmojiFiles.openForReading(context, PartAuthority.getEmojiFilename(model.uri))
}
val bitmapOptions = BitmapFactory.Options()
bitmapOptions.inSampleSize = inSampleSize
callback.onDataReady(BitmapFactory.decodeStream(inputStream, null, bitmapOptions))
} catch (e: Exception) {
callback.onLoadFailed(e)
}
}
override fun cleanup() = Unit
override fun cancel() = Unit
override fun getDataClass(): Class<Bitmap> {
return Bitmap::class.java
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
}
}
companion object {
@JvmField
val IN_SAMPLE_SIZE: Option<Int> = Option.memory("emoji_page_in_sample_size", 1)
}
data class Asset(override val uri: Uri) : EmojiPage(uri)
data class Disk(override val uri: Uri) : EmojiPage(uri)
}

View file

@ -0,0 +1,73 @@
package org.thoughtcrime.securesms.emoji
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.annotation.MainThread
import androidx.annotation.WorkerThread
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.util.ListenableFutureTask
import org.thoughtcrime.securesms.util.SoftHashMap
import org.thoughtcrime.securesms.util.concurrent.SimpleTask
import java.io.IOException
import java.io.InputStream
object EmojiPageCache {
private val TAG = Log.tag(EmojiPageCache::class.java)
private val cache: SoftHashMap<EmojiPageRequest, Bitmap> = SoftHashMap()
private val tasks: HashMap<EmojiPageRequest, ListenableFutureTask<Bitmap>> = hashMapOf()
@MainThread
fun load(context: Context, emojiPage: EmojiPage, inSampleSize: Int): ListenableFutureTask<Bitmap> {
val applicationContext = context.applicationContext
val emojiPageRequest = EmojiPageRequest(emojiPage, inSampleSize)
val bitmap: Bitmap? = cache[emojiPageRequest]
val task: ListenableFutureTask<Bitmap>? = tasks[emojiPageRequest]
return when {
bitmap != null -> ListenableFutureTask(bitmap)
task != null -> task
else -> {
val newTask = ListenableFutureTask<Bitmap> {
try {
Log.i(TAG, "Loading page $emojiPageRequest")
loadInternal(applicationContext, emojiPageRequest)
} catch (e: IOException) {
Log.w(TAG, e)
null
}
}
tasks[emojiPageRequest] = newTask
SimpleTask.run(newTask::run) {
try {
cache[emojiPageRequest] = newTask.get()
} finally {
tasks.remove(emojiPageRequest)
}
}
newTask
}
}
}
@WorkerThread
private fun loadInternal(context: Context, emojiPageRequest: EmojiPageRequest): Bitmap? {
val inputStream: InputStream = when (emojiPageRequest.emojiPage) {
is EmojiPage.Asset -> context.assets.open(emojiPageRequest.emojiPage.uri.toString().replace("file:///android_asset/", ""))
is EmojiPage.Disk -> EmojiFiles.openForReading(context, PartAuthority.getEmojiFilename(emojiPageRequest.emojiPage.uri))
}
val bitmapOptions = BitmapFactory.Options()
bitmapOptions.inSampleSize = emojiPageRequest.inSampleSize
return BitmapFactory.decodeStream(inputStream, null, bitmapOptions)
}
private data class EmojiPageRequest(val emojiPage: EmojiPage, val inSampleSize: Int)
}

View file

@ -29,7 +29,6 @@ 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.EmojiPage;
import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl;
import org.thoughtcrime.securesms.glide.ChunkedImageUrlLoader;
import org.thoughtcrime.securesms.glide.ContactPhotoLoader;
@ -91,7 +90,6 @@ public class SignalGlideModule extends AppGlideModule {
registry.prepend(BlurHash.class, Bitmap.class, new BlurHashResourceDecoder());
registry.append(EmojiPage.class, Bitmap.class, new EmojiPage.Loader.Factory(context));
registry.append(ConversationShortcutPhoto.class, Bitmap.class, new ConversationShortcutPhoto.Loader.Factory(context));
registry.append(ContactPhoto.class, InputStream.class, new ContactPhotoLoader.Factory(context));
registry.append(DecryptableUri.class, InputStream.class, new DecryptableStreamUriLoader.Factory(context));