Merge pull request #4880 from k9mail/update_glide
Update to Glide 4.11.0
This commit is contained in:
commit
50cbb5cca8
16 changed files with 274 additions and 112 deletions
|
@ -29,6 +29,9 @@ dependencies {
|
|||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidxLifecycle}"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidxLifecycle}"
|
||||
|
||||
implementation "com.github.bumptech.glide:glide:${versions.glide}"
|
||||
kapt "com.github.bumptech.glide:compiler:${versions.glide}"
|
||||
|
||||
// Required for DependencyInjectionTest to be able to resolve OpenPgpApiManager
|
||||
testImplementation project(':plugins:openpgp-api-lib:openpgp-api')
|
||||
|
||||
|
|
8
app/k9mail-jmap/proguard-rules.pro
vendored
8
app/k9mail-jmap/proguard-rules.pro
vendored
|
@ -18,6 +18,14 @@
|
|||
-dontwarn okio.**
|
||||
-dontwarn com.squareup.moshi.**
|
||||
|
||||
# Glide
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.LibraryGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
# Project specific rules
|
||||
-dontnote com.fsck.k9.ui.messageview.**
|
||||
-dontnote com.fsck.k9.view.**
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.fsck.k9.glide;
|
||||
|
||||
import com.bumptech.glide.annotation.GlideModule;
|
||||
import com.bumptech.glide.module.AppGlideModule;
|
||||
|
||||
@GlideModule
|
||||
public class K9AppGlideModule extends AppGlideModule {
|
||||
}
|
|
@ -24,6 +24,9 @@ dependencies {
|
|||
implementation "com.jakewharton.timber:timber:${versions.timber}"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlinCoroutines}"
|
||||
|
||||
implementation "com.github.bumptech.glide:glide:${versions.glide}"
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:${versions.glide}"
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
|
||||
|
||||
// Required for DependencyInjectionTest to be able to resolve OpenPgpApiManager
|
||||
|
|
8
app/k9mail/proguard-rules.pro
vendored
8
app/k9mail/proguard-rules.pro
vendored
|
@ -17,6 +17,14 @@
|
|||
-dontwarn okio.**
|
||||
-dontwarn com.squareup.moshi.**
|
||||
|
||||
# Glide
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.LibraryGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
# Project specific rules
|
||||
-dontnote com.fsck.k9.ui.messageview.**
|
||||
-dontnote com.fsck.k9.view.**
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.fsck.k9.glide;
|
||||
|
||||
import com.bumptech.glide.annotation.GlideModule;
|
||||
import com.bumptech.glide.module.AppGlideModule;
|
||||
|
||||
@GlideModule
|
||||
public class K9AppGlideModule extends AppGlideModule {
|
||||
}
|
|
@ -34,7 +34,6 @@ dependencies {
|
|||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation "com.google.android.material:material:${versions.materialComponents}"
|
||||
implementation "de.cketti.library.changelog:ckchangelog:1.2.1"
|
||||
implementation "com.github.bumptech.glide:glide:3.6.1"
|
||||
implementation "com.splitwise:tokenautocomplete:2.0.7"
|
||||
implementation "de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0"
|
||||
implementation "com.xwray:groupie:2.8.0"
|
||||
|
@ -53,6 +52,9 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlinCoroutines}"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlinCoroutines}"
|
||||
|
||||
implementation "com.github.bumptech.glide:glide:${versions.glide}"
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:${versions.glide}"
|
||||
|
||||
testImplementation project(':mail:testing')
|
||||
testImplementation project(':app:storage')
|
||||
testImplementation project(':app:testing')
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.fsck.k9.contacts
|
||||
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.fsck.k9.mail.Address
|
||||
import java.security.MessageDigest
|
||||
|
||||
/**
|
||||
* Contains all information necessary for [ContactImageBitmapDecoder] to load the contact picture in the desired format.
|
||||
*/
|
||||
class ContactImage(
|
||||
val contactLetterOnly: Boolean,
|
||||
val backgroundCacheId: String,
|
||||
val contactLetterBitmapCreator: ContactLetterBitmapCreator,
|
||||
val address: Address
|
||||
) : Key {
|
||||
private val contactLetterSignature = contactLetterBitmapCreator.signatureOf(address)
|
||||
|
||||
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||
messageDigest.update(toString().toByteArray(Key.CHARSET))
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ContactImage
|
||||
|
||||
if (contactLetterOnly != other.contactLetterOnly) return false
|
||||
if (backgroundCacheId != other.backgroundCacheId) return false
|
||||
if (address != other.address) return false
|
||||
if (contactLetterSignature != other.contactLetterSignature) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = contactLetterOnly.hashCode()
|
||||
result = 31 * result + backgroundCacheId.hashCode()
|
||||
result = 31 * result + address.hashCode()
|
||||
result = 31 * result + contactLetterSignature.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ContactImage(" +
|
||||
"contactLetterOnly=$contactLetterOnly, " +
|
||||
"backgroundCacheId='$backgroundCacheId', " +
|
||||
"address=$address, " +
|
||||
"contactLetterSignature='$contactLetterSignature'" +
|
||||
")"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.fsck.k9.contacts
|
||||
|
||||
import android.graphics.Bitmap
|
||||
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 kotlin.math.max
|
||||
|
||||
/**
|
||||
* [ResourceDecoder] implementation that takes a [ContactImage] and fetches the corresponding contact photo using
|
||||
* [ContactPhotoLoader] or generates a fallback image using [ContactLetterBitmapCreator].
|
||||
*/
|
||||
internal class ContactImageBitmapDecoder(
|
||||
private val contactPhotoLoader: ContactPhotoLoader,
|
||||
private val bitmapPool: BitmapPool
|
||||
) : ResourceDecoder<ContactImage, Bitmap> {
|
||||
|
||||
override fun decode(contactImage: ContactImage, width: Int, height: Int, options: Options): Resource<Bitmap>? {
|
||||
val size = max(width, height)
|
||||
|
||||
val bitmap = loadContactPhoto(contactImage) ?: createContactLetterBitmap(contactImage, size)
|
||||
|
||||
return BitmapResource.obtain(bitmap, bitmapPool)
|
||||
}
|
||||
|
||||
private fun loadContactPhoto(contactImage: ContactImage): Bitmap? {
|
||||
if (contactImage.contactLetterOnly) return null
|
||||
|
||||
return contactPhotoLoader.loadContactPhoto(contactImage.address.address)
|
||||
}
|
||||
|
||||
private fun createContactLetterBitmap(contactImage: ContactImage, size: Int): Bitmap {
|
||||
val bitmap = bitmapPool.getDirty(size, size, Bitmap.Config.ARGB_8888)
|
||||
return contactImage.contactLetterBitmapCreator.drawBitmap(bitmap, size, contactImage.address)
|
||||
}
|
||||
|
||||
override fun handles(source: ContactImage, options: Options) = true
|
||||
}
|
||||
|
||||
internal class ContactImageBitmapDecoderFactory(private val contactPhotoLoader: ContactPhotoLoader) {
|
||||
fun create(bitmapPool: BitmapPool): ContactImageBitmapDecoder {
|
||||
return ContactImageBitmapDecoder(contactPhotoLoader, bitmapPool)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.fsck.k9.contacts
|
||||
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.ResourceDecoder
|
||||
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
|
||||
|
||||
/**
|
||||
* [ModelLoader] implementation that does nothing put pass through [ContactImage] to be handled by our custom
|
||||
* [ResourceDecoder] implementation, [ContactImageBitmapDecoder].
|
||||
*/
|
||||
class ContactImageModelLoader : ModelLoader<ContactImage, ContactImage> {
|
||||
override fun buildLoadData(
|
||||
contactImage: ContactImage,
|
||||
width: Int,
|
||||
height: Int,
|
||||
options: Options
|
||||
): ModelLoader.LoadData<ContactImage> {
|
||||
return ModelLoader.LoadData(contactImage, ContactImageDataFetcher(contactImage))
|
||||
}
|
||||
|
||||
override fun handles(model: ContactImage) = true
|
||||
}
|
||||
|
||||
class ContactImageDataFetcher(private val contactImage: ContactImage) : DataFetcher<ContactImage> {
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in ContactImage>) {
|
||||
callback.onDataReady(contactImage)
|
||||
}
|
||||
|
||||
override fun getDataClass() = ContactImage::class.java
|
||||
|
||||
override fun getDataSource() = DataSource.LOCAL
|
||||
|
||||
override fun cleanup() = Unit
|
||||
|
||||
override fun cancel() = Unit
|
||||
}
|
||||
|
||||
class ContactImageModelLoaderFactory : ModelLoaderFactory<ContactImage, ContactImage> {
|
||||
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<ContactImage, ContactImage> {
|
||||
return ContactImageModelLoader()
|
||||
}
|
||||
|
||||
override fun teardown() = Unit
|
||||
}
|
|
@ -4,8 +4,6 @@ import android.graphics.Bitmap
|
|||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.bumptech.glide.signature.StringSignature
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.ui.helper.MaterialColors
|
||||
|
||||
|
@ -57,10 +55,8 @@ class ContactLetterBitmapCreator(
|
|||
}
|
||||
}
|
||||
|
||||
fun signatureOf(address: Address): Key {
|
||||
val letter = letterExtractor.extractContactLetter(address)
|
||||
val backgroundColor = calcUnknownContactColor(address)
|
||||
return StringSignature(letter + backgroundColor)
|
||||
fun signatureOf(address: Address): String {
|
||||
return calcUnknownContactColor(address).toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.fsck.k9.contacts
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import com.fsck.k9.helper.Contacts
|
||||
import timber.log.Timber
|
||||
|
||||
internal class ContactPhotoLoader(private val contentResolver: ContentResolver, private val contacts: Contacts) {
|
||||
fun loadContactPhoto(emailAddress: String): Bitmap? {
|
||||
val photoUri = contacts.getPhotoUri(emailAddress) ?: return null
|
||||
return try {
|
||||
contentResolver.openInputStream(photoUri).use { inputStream ->
|
||||
BitmapFactory.decodeStream(inputStream)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Couldn't load contact photo: $photoUri")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.fsck.k9.contacts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.Registry;
|
||||
import com.bumptech.glide.annotation.GlideModule;
|
||||
import com.bumptech.glide.module.LibraryGlideModule;
|
||||
import com.fsck.k9.DI;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@GlideModule
|
||||
public class ContactPictureGlideModule extends LibraryGlideModule {
|
||||
@Override
|
||||
public void registerComponents(@NotNull Context context, @NotNull Glide glide, Registry registry) {
|
||||
registry.append(ContactImage.class, ContactImage.class, new ContactImageModelLoaderFactory());
|
||||
|
||||
ContactImageBitmapDecoderFactory factory = DI.get(ContactImageBitmapDecoderFactory.class);
|
||||
ContactImageBitmapDecoder contactImageBitmapDecoder = factory.create(glide.getBitmapPool());
|
||||
registry.append(ContactImage.class, Bitmap.class, contactImageBitmapDecoder);
|
||||
}
|
||||
}
|
|
@ -2,32 +2,20 @@ package com.fsck.k9.contacts
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.ResourceDecoder
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapResource
|
||||
import com.bumptech.glide.request.FutureTarget
|
||||
import com.fsck.k9.helper.Contacts
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.view.RecipientSelectView.Recipient
|
||||
import kotlin.math.max
|
||||
import timber.log.Timber
|
||||
|
||||
class ContactPictureLoader(
|
||||
private val context: Context,
|
||||
private val contactLetterBitmapCreator: ContactLetterBitmapCreator
|
||||
) {
|
||||
private val contactsHelper: Contacts = Contacts.getInstance(context)
|
||||
private val pictureSizeInPx: Int = PICTURE_SIZE.toDip(context)
|
||||
private val backgroundCacheId: String = with(contactLetterBitmapCreator.config) {
|
||||
if (hasDefaultBackgroundColor) defaultBackgroundColor.toString() else "*"
|
||||
|
@ -35,15 +23,10 @@ class ContactPictureLoader(
|
|||
|
||||
fun setContactPicture(imageView: ImageView, address: Address) {
|
||||
Glide.with(imageView.context)
|
||||
.using(AddressModelLoader(backgroundCacheId), Address::class.java)
|
||||
.from(Address::class.java)
|
||||
.`as`(Bitmap::class.java)
|
||||
.decoder(ContactImageBitmapDecoder())
|
||||
.signature(contactLetterBitmapCreator.signatureOf(address))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(address)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
.load(createContactImage(address, contactLetterOnly = false))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
fun setContactPicture(imageView: ImageView, recipient: Recipient) {
|
||||
|
@ -57,24 +40,19 @@ class ContactPictureLoader(
|
|||
|
||||
private fun setContactPicture(imageView: ImageView, contactPictureUri: Uri) {
|
||||
Glide.with(imageView.context)
|
||||
.load(contactPictureUri)
|
||||
.error(R.drawable.ic_contact_picture)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
.load(contactPictureUri)
|
||||
.error(R.drawable.ic_contact_picture)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
private fun setFallbackPicture(imageView: ImageView, address: Address) {
|
||||
Glide.with(imageView.context)
|
||||
.using(AddressModelLoader(backgroundCacheId), Address::class.java)
|
||||
.from(Address::class.java)
|
||||
.`as`(Bitmap::class.java)
|
||||
.decoder(ContactImageBitmapDecoder(contactLetterOnly = true))
|
||||
.signature(contactLetterBitmapCreator.signatureOf(address))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(address)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
.load(createContactImage(address, contactLetterOnly = true))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
@ -91,79 +69,32 @@ class ContactPictureLoader(
|
|||
|
||||
private fun getContactPicture(contactPictureUri: Uri): Bitmap? {
|
||||
return Glide.with(context)
|
||||
.load(contactPictureUri)
|
||||
.asBitmap()
|
||||
.error(R.drawable.ic_contact_picture)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(pictureSizeInPx, pictureSizeInPx)
|
||||
.getOrNull()
|
||||
.asBitmap()
|
||||
.load(contactPictureUri)
|
||||
.error(R.drawable.ic_contact_picture)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.submit(pictureSizeInPx, pictureSizeInPx)
|
||||
.getOrNull()
|
||||
}
|
||||
|
||||
private fun getFallbackPicture(address: Address): Bitmap? {
|
||||
return Glide.with(context)
|
||||
.using(AddressModelLoader(backgroundCacheId), Address::class.java)
|
||||
.from(Address::class.java)
|
||||
.`as`(Bitmap::class.java)
|
||||
.decoder(ContactImageBitmapDecoder(contactLetterOnly = true))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(address)
|
||||
.dontAnimate()
|
||||
.into(pictureSizeInPx, pictureSizeInPx)
|
||||
.getOrNull()
|
||||
.asBitmap()
|
||||
.load(createContactImage(address, contactLetterOnly = true))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.submit(pictureSizeInPx, pictureSizeInPx)
|
||||
.getOrNull()
|
||||
}
|
||||
|
||||
private inner class ContactImageBitmapDecoder(
|
||||
private val contactLetterOnly: Boolean = false
|
||||
) : ResourceDecoder<Address, Bitmap> {
|
||||
|
||||
override fun decode(address: Address, width: Int, height: Int): Resource<Bitmap> {
|
||||
val pool = Glide.get(context).bitmapPool
|
||||
|
||||
val size = max(width, height)
|
||||
|
||||
val bitmap = loadContactPicture(address) ?: createContactLetterBitmap(address, size, pool)
|
||||
|
||||
return BitmapResource.obtain(bitmap, pool)
|
||||
}
|
||||
|
||||
private fun loadContactPicture(address: Address): Bitmap? {
|
||||
if (contactLetterOnly) return null
|
||||
|
||||
val photoUri = contactsHelper.getPhotoUri(address.address) ?: return null
|
||||
return try {
|
||||
context.contentResolver.openInputStream(photoUri).use { inputStream ->
|
||||
BitmapFactory.decodeStream(inputStream)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Couldn't load contact picture: $photoUri")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createContactLetterBitmap(address: Address, size: Int, pool: BitmapPool): Bitmap {
|
||||
val bitmap = pool.getDirty(size, size, Bitmap.Config.ARGB_8888)
|
||||
?: Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
||||
|
||||
return contactLetterBitmapCreator.drawBitmap(bitmap, size, address)
|
||||
}
|
||||
|
||||
override fun getId(): String {
|
||||
return "fallback-photo"
|
||||
}
|
||||
}
|
||||
|
||||
private class AddressModelLoader(val backgroundCacheId: String) : ModelLoader<Address, Address> {
|
||||
override fun getResourceFetcher(address: Address, width: Int, height: Int): DataFetcher<Address> {
|
||||
return object : DataFetcher<Address> {
|
||||
override fun getId() = "${address.address}-${address.personal}-$backgroundCacheId"
|
||||
|
||||
override fun loadData(priority: Priority?): Address = address
|
||||
|
||||
override fun cleanup() = Unit
|
||||
override fun cancel() = Unit
|
||||
}
|
||||
}
|
||||
private fun createContactImage(address: Address, contactLetterOnly: Boolean): ContactImage {
|
||||
return ContactImage(
|
||||
contactLetterOnly = contactLetterOnly,
|
||||
backgroundCacheId = backgroundCacheId,
|
||||
contactLetterBitmapCreator = contactLetterBitmapCreator,
|
||||
address = address
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T> FutureTarget<T>.getOrNull(): T? {
|
||||
|
|
|
@ -4,7 +4,9 @@ import org.koin.dsl.module
|
|||
|
||||
val contactsModule = module {
|
||||
single { ContactLetterExtractor() }
|
||||
factory { ContactLetterBitmapConfig(get(), get()) }
|
||||
factory { ContactLetterBitmapCreator(get(), get()) }
|
||||
factory { ContactPictureLoader(get(), get()) }
|
||||
factory { ContactLetterBitmapConfig(context = get(), themeManager = get()) }
|
||||
factory { ContactLetterBitmapCreator(letterExtractor = get(), config = get()) }
|
||||
factory { ContactPhotoLoader(contentResolver = get(), contacts = get()) }
|
||||
factory { ContactPictureLoader(context = get(), contactLetterBitmapCreator = get()) }
|
||||
factory { ContactImageBitmapDecoderFactory(contactPhotoLoader = get()) }
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ buildscript {
|
|||
'mime4j': '0.8.3',
|
||||
'okhttp': '4.8.0',
|
||||
'minidns': '0.3.4',
|
||||
'glide': '4.11.0',
|
||||
|
||||
'androidxTestRunner': '1.2.0',
|
||||
'junit': '4.13',
|
||||
|
|
Loading…
Reference in a new issue