Skip to content

Commit

Permalink
Fix disk LRU cache key formatting error
Browse files Browse the repository at this point in the history
We check and modify all the alphabetic ascii to lowercase, and then we
replace not permitted char with "_"

We also add a checksum to the key to avoid collisions in some cases.

Fix the issue related to:
Failed to get Bitmap from DiskLruCache:keys must match regex [a-z0-9_-]{1,64}:
"https://igalia.github.io/wolvic-3D-environments/spring/spring.png"
-> "585e57a6_https___igalia_github_io_wolvic-3d-environments_spring_"

Now we can access the external environments bitmap offline after
they have been loaded once.

Signed-off-by: Songlin Jiang <[email protected]>
  • Loading branch information
HollowMan6 committed Dec 5, 2023
1 parent c86d8cf commit 8be0c27
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions app/src/common/shared/com/igalia/wolvic/utils/BitmapCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.zip.CRC32;

public class BitmapCache {
private Context mContext;
Expand All @@ -32,6 +33,16 @@ public class BitmapCache {
private Surface mCaptureSurface;
private boolean mCapturedAcquired;

private String normalizeKey(@NonNull String input) {
// DiskLruCache keys must match the regex [a-z0-9_-]{1,64}
final int MAX_LENGTH = 64;
CRC32 crc = new CRC32();
crc.update(input.getBytes());

String key = Long.toHexString(crc.getValue()) + '_' + input.toLowerCase().replaceAll("[^a-z0-9_-]", "_");
return key.substring(0, Math.min(key.length(), MAX_LENGTH));
}

public static BitmapCache getInstance(Context aContext) {
return ((VRBrowserApplication)aContext.getApplicationContext()).getBitmapCache();
}
Expand Down Expand Up @@ -75,11 +86,13 @@ void initDiskCache() {
}

public void addBitmap(@NonNull String aKey, @NonNull Bitmap aBitmap) {
aKey = normalizeKey(aKey);
mMemoryCache.put(aKey, aBitmap);
String finalAKey = aKey;
runIO(() -> {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit(aKey);
editor = mDiskCache.edit(finalAKey);
if (editor != null) {
aBitmap.compress(Bitmap.CompressFormat.PNG, 80, editor.newOutputStream(0));
editor.commit();
Expand All @@ -100,21 +113,23 @@ public void addBitmap(@NonNull String aKey, @NonNull Bitmap aBitmap) {
}

public @NonNull CompletableFuture<Bitmap> getBitmap(@NonNull String aKey) {
aKey = normalizeKey(aKey);
Bitmap cached = mMemoryCache.get(aKey);
if (cached != null) {
return CompletableFuture.completedFuture(cached);
} else {
CompletableFuture<Bitmap> result = new CompletableFuture<>();
String finalAKey = aKey;
runIO(() -> {
try (DiskLruCache.Snapshot snapshot = mDiskCache.get(aKey)){
try (DiskLruCache.Snapshot snapshot = mDiskCache.get(finalAKey)){
if (snapshot != null) {
Bitmap bitmap = BitmapFactory.decodeStream(snapshot.getInputStream(0));
if (bitmap != null) {
mMainThreadExecutor.execute(() -> {
if (mMemoryCache.get(aKey) == null) {
if (mMemoryCache.get(finalAKey) == null) {
// Do not update cache if it already contains a value
// A tab could have saved a new image while we were loading the cached disk image.
mMemoryCache.put(aKey, bitmap);
mMemoryCache.put(finalAKey, bitmap);
}
result.complete(bitmap);
});
Expand All @@ -135,17 +150,20 @@ public void addBitmap(@NonNull String aKey, @NonNull Bitmap aBitmap) {
}

public void removeBitmap(@NonNull String aKey) {
aKey = normalizeKey(aKey);
mMemoryCache.remove(aKey);
String finalAKey = aKey;
runIO(() -> {
try {
mDiskCache.remove(aKey);
mDiskCache.remove(finalAKey);
} catch (Exception ex) {
Log.e(LOGTAG, "Failed to remove Bitmap from DiskLruCache:" + ex.getMessage());
}
});
}

public boolean hasBitmap(@NonNull String aKey) {
aKey = normalizeKey(aKey);
return mMemoryCache.get(aKey) != null;
}

Expand Down

0 comments on commit 8be0c27

Please sign in to comment.