Skip to content

Commit 1b391c4

Browse files
committedAug 14, 2019
Include day/night mode in resource id cache keys.
1 parent 502ba75 commit 1b391c4

File tree

3 files changed

+152
-9
lines changed

3 files changed

+152
-9
lines changed
 

‎library/src/main/java/com/bumptech/glide/RequestBuilder.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import com.bumptech.glide.request.target.PreloadTarget;
3131
import com.bumptech.glide.request.target.Target;
3232
import com.bumptech.glide.request.target.ViewTarget;
33-
import com.bumptech.glide.signature.ApplicationVersionSignature;
33+
import com.bumptech.glide.signature.AndroidResourceSignature;
3434
import com.bumptech.glide.util.Executors;
3535
import com.bumptech.glide.util.Preconditions;
3636
import com.bumptech.glide.util.Synthetic;
@@ -495,12 +495,12 @@ public RequestBuilder<TranscodeType> load(@Nullable File file) {
495495
* load the image represented by the given {@link Integer} resource id. Defaults to {@link
496496
* com.bumptech.glide.load.model.ResourceLoader} to load resource id models.
497497
*
498-
* <p>By default this method adds a version code based signature to the cache key used to cache
499-
* this resource in Glide. This signature is sufficient to guarantee that end users will see the
500-
* most up to date versions of your Drawables, but during development if you do not increment your
501-
* version code before each install and you replace a Drawable with different data without
502-
* changing the Drawable name, you may see inconsistent cached data. To get around this, consider
503-
* using {@link com.bumptech.glide.load.engine.DiskCacheStrategy#NONE} via {@link
498+
* <p>By default this method adds a version code and night mode based signature to the cache key
499+
* used to cache this resource in Glide. This signature is sufficient to guarantee that end users
500+
* will see the most up to date versions of your Drawables, but during development if you do not
501+
* increment your version code before each install and you replace a Drawable with different data
502+
* without changing the Drawable name, you may see inconsistent cached data. To get around this,
503+
* consider using {@link com.bumptech.glide.load.engine.DiskCacheStrategy#NONE} via {@link
504504
* RequestOptions#diskCacheStrategy(com.bumptech.glide.load.engine.DiskCacheStrategy)} during
505505
* development, and re-enabling the default {@link
506506
* com.bumptech.glide.load.engine.DiskCacheStrategy#RESOURCE} for release builds.
@@ -519,13 +519,13 @@ public RequestBuilder<TranscodeType> load(@Nullable File file) {
519519
* caution for non-{@link Bitmap} {@link Drawable}s.
520520
*
521521
* @see #load(Integer)
522-
* @see com.bumptech.glide.signature.ApplicationVersionSignature
522+
* @see com.bumptech.glide.signature.AndroidResourceSignature
523523
*/
524524
@NonNull
525525
@CheckResult
526526
@Override
527527
public RequestBuilder<TranscodeType> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
528-
return loadGeneric(resourceId).apply(signatureOf(ApplicationVersionSignature.obtain(context)));
528+
return loadGeneric(resourceId).apply(signatureOf(AndroidResourceSignature.obtain(context)));
529529
}
530530

531531
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.bumptech.glide.signature;
2+
3+
import android.content.Context;
4+
import android.content.res.Configuration;
5+
import androidx.annotation.NonNull;
6+
import com.bumptech.glide.load.Key;
7+
import com.bumptech.glide.util.Util;
8+
import java.nio.ByteBuffer;
9+
import java.security.MessageDigest;
10+
11+
public final class AndroidResourceSignature implements Key {
12+
13+
private final int nightMode;
14+
private final Key applicationVersion;
15+
16+
@NonNull
17+
public static Key obtain(@NonNull Context context) {
18+
Key signature = ApplicationVersionSignature.obtain(context);
19+
int nightMode =
20+
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
21+
return new AndroidResourceSignature(nightMode, signature);
22+
}
23+
24+
private AndroidResourceSignature(int nightMode, Key applicationVersion) {
25+
this.nightMode = nightMode;
26+
this.applicationVersion = applicationVersion;
27+
}
28+
29+
@Override
30+
public boolean equals(Object o) {
31+
if (o instanceof AndroidResourceSignature) {
32+
AndroidResourceSignature that = (AndroidResourceSignature) o;
33+
return nightMode == that.nightMode && applicationVersion.equals(that.applicationVersion);
34+
}
35+
return false;
36+
}
37+
38+
@Override
39+
public int hashCode() {
40+
return Util.hashCode(applicationVersion, nightMode);
41+
}
42+
43+
@Override
44+
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
45+
applicationVersion.updateDiskCacheKey(messageDigest);
46+
byte[] nightModeData = ByteBuffer.allocate(4).putInt(nightMode).array();
47+
messageDigest.update(nightModeData);
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.bumptech.glide.signature;
2+
3+
import static org.junit.Assert.assertNotNull;
4+
import static org.mockito.Mockito.mock;
5+
import static org.mockito.Mockito.when;
6+
7+
import android.content.Context;
8+
import android.content.pm.PackageManager.NameNotFoundException;
9+
import androidx.test.core.app.ApplicationProvider;
10+
import com.bumptech.glide.load.Key;
11+
import com.bumptech.glide.tests.KeyTester;
12+
import org.junit.Before;
13+
import org.junit.Rule;
14+
import org.junit.Test;
15+
import org.junit.runner.RunWith;
16+
import org.mockito.Answers;
17+
import org.robolectric.RobolectricTestRunner;
18+
import org.robolectric.RuntimeEnvironment;
19+
import org.robolectric.annotation.Config;
20+
21+
@RunWith(RobolectricTestRunner.class)
22+
@Config(sdk = 28)
23+
public class AndroidResourceSignatureTest {
24+
@Rule public final KeyTester keyTester = new KeyTester();
25+
private Context context;
26+
27+
@Before
28+
public void setUp() {
29+
context = ApplicationProvider.getApplicationContext();
30+
}
31+
32+
@Test
33+
public void testCanGetKeyForSignature() {
34+
Key key = AndroidResourceSignature.obtain(context);
35+
assertNotNull(key);
36+
}
37+
38+
@Test
39+
public void testKeyForSignatureIsTheSameAcrossCallsInTheSamePackage() {
40+
keyTester
41+
.addEquivalenceGroup(
42+
AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
43+
.addEquivalenceGroup(new ObjectKey("test"))
44+
.addRegressionTest(
45+
ApplicationVersionSignature.obtain(context),
46+
"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9")
47+
.test();
48+
}
49+
50+
@Test
51+
public void testKeyForSignatureDiffersByNightMode() {
52+
RuntimeEnvironment.setQualifiers("notnight");
53+
keyTester
54+
.addEquivalenceGroup(
55+
AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
56+
.addRegressionTest(
57+
AndroidResourceSignature.obtain(context),
58+
"265d958bdae1bea56e45cc31f4db672c22893b66fef85617bbc78742bd912207");
59+
RuntimeEnvironment.setQualifiers("night");
60+
keyTester
61+
.addEquivalenceGroup(
62+
AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
63+
.addRegressionTest(
64+
AndroidResourceSignature.obtain(context),
65+
"96c9b8d5bb071ccd67df50cd9a0059640ebd02db78d08f07611ec145ce44a638");
66+
67+
keyTester.test();
68+
}
69+
70+
@Test
71+
public void testUnresolvablePackageInfo() throws NameNotFoundException {
72+
Context context = mock(Context.class, Answers.RETURNS_DEEP_STUBS);
73+
String packageName = "my.package";
74+
when(context.getPackageName()).thenReturn(packageName);
75+
when(context.getPackageManager().getPackageInfo(packageName, 0))
76+
.thenThrow(new NameNotFoundException("test"));
77+
78+
Key key = AndroidResourceSignature.obtain(context);
79+
80+
assertNotNull(key);
81+
}
82+
83+
@Test
84+
public void testMissingPackageInfo() throws NameNotFoundException {
85+
Context context = mock(Context.class, Answers.RETURNS_DEEP_STUBS);
86+
String packageName = "my.package";
87+
when(context.getPackageName()).thenReturn(packageName);
88+
when(context.getPackageManager().getPackageInfo(packageName, 0)).thenReturn(null);
89+
90+
Key key = AndroidResourceSignature.obtain(context);
91+
92+
assertNotNull(key);
93+
}
94+
}

0 commit comments

Comments
 (0)
Please sign in to comment.