-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is relatively early stage at this point. The API is likely to change in breaking ways. Ideally the migrations are not large, but I'd expect a few iterations. There's already a TODO to improve the Prealoader API and make the GlideImage API less reliant on GlideBuilder. Early feedback and usage would be welcome, with the caveat that it'll mean some migration work down the road. PiperOrigin-RevId: 475696354
- Loading branch information
1 parent
790c351
commit 8bef56e
Showing
18 changed files
with
857 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
public abstract interface annotation class com/bumptech/glide/integration/compose/ExperimentalGlideComposeApi : java/lang/annotation/Annotation { | ||
} | ||
|
||
public final class com/bumptech/glide/integration/compose/GlideImageKt { | ||
public static final fun GlideImage (Ljava/lang/Object;Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V | ||
} | ||
|
||
public final class com/bumptech/glide/integration/compose/PreloadKt { | ||
public static final fun GlideLazyListPreloader-u6VnWhU (Landroidx/compose/foundation/lazy/LazyListState;Ljava/util/List;JILjava/lang/Integer;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
plugins { | ||
id 'com.android.library' | ||
id 'kotlin-android' | ||
} | ||
|
||
android { | ||
compileSdk 32 | ||
|
||
defaultConfig { | ||
minSdk 21 | ||
targetSdk 32 | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildFeatures { | ||
compose = true | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
} | ||
} | ||
|
||
composeOptions { | ||
kotlinCompilerExtensionVersion '1.2.0' | ||
} | ||
|
||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
|
||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
} | ||
|
||
// Enable strict mode, but exclude tests. | ||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { | ||
if (!it.name.contains("Test")) { | ||
kotlinOptions.freeCompilerArgs += "-Xexplicit-api=strict" | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation project(':library') | ||
implementation project(':integration:ktx') | ||
implementation(project(':integration:recyclerview')) { | ||
transitive = false | ||
} | ||
implementation "androidx.compose.foundation:foundation:$ANDROID_X_COMPOSE_VERSION" | ||
implementation "androidx.compose.ui:ui:$ANDROID_X_COMPOSE_VERSION" | ||
implementation "com.google.accompanist:accompanist-drawablepainter:$ACCOMPANIEST_VERSION" | ||
implementation "androidx.core:core-ktx:$ANDROID_X_CORE_KTX_VERSION" | ||
debugImplementation "androidx.compose.ui:ui-test-manifest:$ANDROID_X_COMPOSE_VERSION" | ||
androidTestImplementation "junit:junit:$JUNIT_VERSION" | ||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$ANDROID_X_COMPOSE_VERSION" | ||
androidTestImplementation "androidx.test.espresso:espresso-core:$ANDROID_X_TEST_ESPRESSO_VERSION" | ||
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$ANDROID_X_TEST_ESPRESSO_VERSION" | ||
androidTestImplementation "androidx.test.ext:junit:$ANDROID_X_TEST_JUNIT_VERSION" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
POM_NAME=Glide Compose Integration | ||
POM_ARTIFACT_ID=compose | ||
POM_PACKAGING=aar | ||
POM_DESCRIPTION=An integration library to integrate with Jetpack Compose | ||
|
||
VERSION_MAJOR=1 | ||
VERSION_MINOR=0 | ||
VERSION_PATCH=0 | ||
VERSION_NAME=1.0.0-alpha.0-SNAPSHOT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
""" | ||
Workaround for the lack of kt_android_library_test_rule (b/243549140). | ||
""" | ||
|
||
load("//tools/build_defs/kotlin:rules.bzl", "kt_android_library") | ||
load("//tools/build_defs/android:rules.bzl", "android_library_test") | ||
|
||
def kt_android_library_test(name, size, srcs, custom_package, manifest, manifest_values, deps, target_devices, test_class): | ||
"""A simple equivalent of android_library_test that works with Kotlin. | ||
This is not well generalized. A better solution is b/243549140, which would | ||
mean adding a real kt_android_library_test to Android's test_macros: | ||
http://google3/tools/build_defs/android/dev/test_macros.bzl;l=17;rcl=470614953 | ||
While this is only used in one place and we could theoretically move a bunch | ||
of constants out of the test rule into this one, it seems better not to do | ||
so. Leaving the constant values in the calling BUILD file should make a | ||
migration to a real kt_android_library_test rule easier in the future. | ||
Args: | ||
name: The test name | ||
size: The test size, probably large | ||
srcs: The test library source set | ||
custom_package: The test library and android_library_test package | ||
manifest: The android_library_test manifest | ||
manifest_values: The android_library_test manifest values | ||
deps: the test library and android_library_test dependencies | ||
target_devices: the target devices passed to android_library_test | ||
test_class: the test class for the android_library_test | ||
""" | ||
library_attrs = {} | ||
library_attrs["srcs"] = srcs | ||
library_attrs["deps"] = deps | ||
library_attrs["testonly"] = 1 | ||
library_attrs["custom_package"] = custom_package | ||
|
||
libname = name + "_lib" | ||
|
||
test_attrs = {} | ||
test_attrs["deps"] = [":" + libname] | ||
test_attrs["size"] = size | ||
test_attrs["manifest"] = manifest | ||
test_attrs["multidex"] = "legacy" | ||
|
||
test_attrs["target_devices"] = target_devices | ||
test_attrs["manifest"] = manifest | ||
test_attrs["manifest_values"] = manifest_values | ||
test_attrs["test_class"] = test_class | ||
|
||
kt_android_library(libname, **library_attrs) | ||
android_library_test(name, **test_attrs) |
148 changes: 148 additions & 0 deletions
148
...n/compose/src/androidTest/java/com/bumptech/glide/integration/compose/GlideComposeTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
@file:OptIn(ExperimentalGlideComposeApi::class, InternalGlideApi::class) | ||
|
||
package com.bumptech.glide.integration.compose | ||
|
||
import android.content.Context | ||
import android.graphics.drawable.BitmapDrawable | ||
import android.graphics.drawable.Drawable | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.runtime.MutableState | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.LocalDensity | ||
import androidx.compose.ui.semantics.SemanticsPropertyKey | ||
import androidx.compose.ui.test.SemanticsMatcher | ||
import androidx.compose.ui.test.assert | ||
import androidx.compose.ui.test.junit4.createComposeRule | ||
import androidx.compose.ui.test.onNodeWithContentDescription | ||
import androidx.compose.ui.unit.dp | ||
import androidx.test.core.app.ApplicationProvider | ||
import com.bumptech.glide.Glide | ||
import com.bumptech.glide.integration.ktx.InternalGlideApi | ||
import com.bumptech.glide.integration.ktx.Size | ||
import com.bumptech.glide.load.engine.executor.GlideIdlingResourceInit | ||
import java.util.concurrent.atomic.AtomicReference | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
|
||
class GlideComposeTest { | ||
private val context: Context = ApplicationProvider.getApplicationContext() | ||
@get:Rule val composeRule = createComposeRule() | ||
|
||
@Before | ||
fun setUp() { | ||
GlideIdlingResourceInit.initGlide(composeRule) | ||
} | ||
|
||
@Test | ||
fun glideImage_noModifierSize_resourceDrawable_displaysDrawable() { | ||
val description = "test" | ||
val resourceId = android.R.drawable.star_big_on | ||
composeRule.setContent { GlideImage(model = resourceId, contentDescription = description) } | ||
|
||
composeRule.waitForIdle() | ||
|
||
val expectedSize = resourceId.bitmapSize() | ||
composeRule | ||
.onNodeWithContentDescription(description) | ||
.assert(expectDisplayedDrawableSize(expectedSize)) | ||
} | ||
|
||
@Test | ||
fun glideImage_withSizeLargerThanImage_noTransformSet_doesNotUpscaleImage() { | ||
val description = "test" | ||
val resourceId = android.R.drawable.star_big_on | ||
composeRule.setContent { | ||
GlideImage( | ||
model = resourceId, | ||
contentDescription = description, | ||
modifier = Modifier.size(300.dp, 300.dp) | ||
) | ||
} | ||
|
||
composeRule.waitForIdle() | ||
|
||
val expectedSize = resourceId.bitmapSize() | ||
composeRule | ||
.onNodeWithContentDescription(description) | ||
.assert(expectDisplayedDrawableSize(expectedSize)) | ||
} | ||
|
||
@Test | ||
fun glideImage_withSizeLargerThanImage_upscaleTransformSet_upscalesImage() { | ||
val viewDimension = 300 | ||
val description = "test" | ||
val sizeRef = AtomicReference<Size>() | ||
composeRule.setContent { | ||
GlideImage( | ||
model = android.R.drawable.star_big_on, | ||
requestBuilderTransform = { it.fitCenter() }, | ||
contentDescription = description, | ||
modifier = Modifier.size(viewDimension.dp, viewDimension.dp) | ||
) | ||
|
||
with(LocalDensity.current) { | ||
val pixels = viewDimension.dp.roundToPx() | ||
sizeRef.set(Size(pixels, pixels)) | ||
} | ||
} | ||
|
||
composeRule.waitForIdle() | ||
|
||
val pixels = sizeRef.get() | ||
composeRule | ||
.onNodeWithContentDescription(description) | ||
.assert(expectDisplayedDrawableSize(pixels)) | ||
} | ||
|
||
@Test | ||
fun glideImage_withThumbnail_prefersFullSizeImage() { | ||
val description = "test" | ||
val thumbnailDrawable = context.getDrawable(android.R.drawable.star_big_off) | ||
val fullsizeDrawable = context.getDrawable(android.R.drawable.star_big_on) | ||
|
||
val fullsizeBitmap = (fullsizeDrawable as BitmapDrawable).bitmap | ||
|
||
composeRule.setContent { | ||
GlideImage( | ||
model = fullsizeDrawable, | ||
requestBuilderTransform = { it.thumbnail(Glide.with(context).load(thumbnailDrawable)) }, | ||
contentDescription = description, | ||
) | ||
} | ||
|
||
composeRule.waitForIdle() | ||
|
||
composeRule | ||
.onNodeWithContentDescription(description) | ||
.assert(expectDisplayedDrawable(fullsizeBitmap) { (it as BitmapDrawable).bitmap }) | ||
} | ||
|
||
private fun Int.bitmapSize() = context.resources.getDrawable(this, context.theme).size() | ||
} | ||
|
||
private fun Drawable.size() = (this as BitmapDrawable).bitmap.let { Size(it.width, it.height) } | ||
|
||
private fun expectDisplayedDrawableSize(widthPixels: Int, heightPixels: Int): SemanticsMatcher = | ||
expectDisplayedDrawable(Size(widthPixels, heightPixels)) { it?.size() } | ||
|
||
private fun expectDisplayedDrawableSize(expectedSize: Size): SemanticsMatcher = | ||
expectDisplayedDrawable(expectedSize) { it?.size() } | ||
|
||
private fun <ValueT> expectDisplayedDrawable( | ||
expectedValue: ValueT, | ||
transform: (Drawable?) -> ValueT | ||
): SemanticsMatcher = expectStateValue(DisplayedDrawableKey, expectedValue) { transform(it) } | ||
|
||
private fun <ValueT, TransformedValueT> expectStateValue( | ||
key: SemanticsPropertyKey<MutableState<ValueT?>>, | ||
expectedValue: TransformedValueT, | ||
transform: (ValueT?) -> TransformedValueT? | ||
): SemanticsMatcher = | ||
SemanticsMatcher("${key.name} = '$expectedValue'") { | ||
val value = transform(it.config.getOrElseNullable(key) { null }?.value) | ||
if (value != expectedValue) { | ||
throw AssertionError("Expected: $expectedValue, but was: $value") | ||
} | ||
true | ||
} |
39 changes: 39 additions & 0 deletions
39
...e/src/androidTest/java/com/bumptech/glide/load/engine/executor/GlideIdlingResourceInit.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.bumptech.glide.load.engine.executor | ||
|
||
import androidx.compose.ui.test.IdlingResource | ||
import androidx.compose.ui.test.junit4.ComposeTestRule | ||
import androidx.test.core.app.ApplicationProvider | ||
import androidx.test.espresso.idling.concurrent.IdlingThreadPoolExecutor | ||
import com.bumptech.glide.Glide | ||
import com.bumptech.glide.GlideBuilder | ||
import java.util.concurrent.LinkedBlockingQueue | ||
import java.util.concurrent.TimeUnit | ||
|
||
object GlideIdlingResourceInit { | ||
|
||
fun initGlide(composeRule: ComposeTestRule) { | ||
val executor = | ||
IdlingThreadPoolExecutor( | ||
"glide_test_thread", | ||
/* corePoolSize= */ 1, | ||
/* maximumPoolSize= */ 1, | ||
/* keepAliveTime= */ 1, | ||
TimeUnit.SECONDS, | ||
LinkedBlockingQueue() | ||
) { Thread(it) } | ||
composeRule.registerIdlingResource( | ||
object : IdlingResource { | ||
override val isIdleNow: Boolean | ||
get() = executor.isIdleNow | ||
} | ||
) | ||
val glideExecutor = GlideExecutor(executor) | ||
Glide.init( | ||
ApplicationProvider.getApplicationContext(), | ||
GlideBuilder() | ||
.setSourceExecutor(glideExecutor) | ||
.setAnimationExecutor(glideExecutor) | ||
.setDiskCacheExecutor(glideExecutor) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.bumptech.glide.integration.compose"> | ||
<uses-sdk android:minSdkVersion="21" /> | ||
</manifest> |
11 changes: 11 additions & 0 deletions
11
...mpose/src/main/java/com/bumptech/glide/integration/compose/ExperimentalGlideComposeApi.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.bumptech.glide.integration.compose | ||
|
||
@RequiresOptIn( | ||
level = RequiresOptIn.Level.ERROR, | ||
message = | ||
"Glide's Compose integration is experimental. APIs may change or be removed without" + | ||
" warning." | ||
) | ||
@Retention(AnnotationRetention.BINARY) | ||
@kotlin.annotation.Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) | ||
public annotation class ExperimentalGlideComposeApi |
Oops, something went wrong.