Show Encoded Cache in Flipper Image plugins.

Summary: load encoded cache and pass to flipper to show.

Reviewed By: oprisnik, passy

Differential Revision: D18643671

fbshipit-source-id: 2df34e0f67ccc585834f02760a1e28079bcf4a6f
This commit is contained in:
Rong Tang
2019-11-28 04:27:52 -08:00
committed by Facebook Github Bot
parent 111ee2079d
commit 83641ff05c

View File

@@ -9,8 +9,12 @@ package com.facebook.flipper.plugins.fresco;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.util.Base64; import android.util.Base64;
import android.util.Pair;
import com.facebook.cache.common.CacheKey; import com.facebook.cache.common.CacheKey;
import com.facebook.common.internal.ByteStreams;
import com.facebook.common.internal.Predicate; import com.facebook.common.internal.Predicate;
import com.facebook.common.memory.PooledByteBuffer;
import com.facebook.common.memory.PooledByteBufferInputStream;
import com.facebook.common.memory.manager.DebugMemoryManager; import com.facebook.common.memory.manager.DebugMemoryManager;
import com.facebook.common.memory.manager.NoOpDebugMemoryManager; import com.facebook.common.memory.manager.NoOpDebugMemoryManager;
import com.facebook.common.references.CloseableReference; import com.facebook.common.references.CloseableReference;
@@ -38,6 +42,7 @@ import com.facebook.imagepipeline.debug.DebugImageTracker;
import com.facebook.imagepipeline.debug.FlipperImageTracker; import com.facebook.imagepipeline.debug.FlipperImageTracker;
import com.facebook.imagepipeline.image.CloseableBitmap; import com.facebook.imagepipeline.image.CloseableBitmap;
import com.facebook.imagepipeline.image.CloseableImage; import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imageutils.BitmapUtil;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -159,15 +164,17 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
mPerfLogger.startMarker("Sonar.Fresco.listImages"); mPerfLogger.startMarker("Sonar.Fresco.listImages");
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory(); final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
final CountingMemoryCacheInspector.DumpInfo memoryCache =
final CountingMemoryCacheInspector.DumpInfo bitmapMemoryCache =
new CountingMemoryCacheInspector<>( new CountingMemoryCacheInspector<>(
imagePipelineFactory.getBitmapCountingMemoryCache()) imagePipelineFactory.getBitmapCountingMemoryCache())
.dumpCacheContent(); .dumpCacheContent();
responder.success( final CountingMemoryCacheInspector.DumpInfo encodedMemoryCache =
getImageList( new CountingMemoryCacheInspector<>(
memoryCache, imagePipelineFactory.getEncodedCountingMemoryCache())
buildImageIdList(memoryCache.sharedEntries), .dumpCacheContent();
buildImageIdList(memoryCache.lruEntries)));
responder.success(getImageList(bitmapMemoryCache, encodedMemoryCache));
mPerfLogger.endMarker("Sonar.Fresco.listImages"); mPerfLogger.endMarker("Sonar.Fresco.listImages");
} }
}); });
@@ -190,15 +197,35 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
mPerfLogger.cancelMarker("Sonar.Fresco.getImage"); mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
return; return;
} }
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory(); final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
// load from bitmap cache
CloseableReference<CloseableImage> ref = CloseableReference<CloseableImage> ref =
imagePipelineFactory.getBitmapCountingMemoryCache().get(cacheKey); imagePipelineFactory.getBitmapCountingMemoryCache().get(cacheKey);
if (ref == null) { if (ref != null) {
respondError(responder, "no bitmap withId=" + imageId); loadFromBitmapCache(ref, imageId, cacheKey, responder);
mPerfLogger.cancelMarker("Sonar.Fresco.getImage"); } else {
return; // try to load from encoded cache
CloseableReference<PooledByteBuffer> encodedRef =
imagePipelineFactory.getEncodedCountingMemoryCache().get(cacheKey);
if (encodedRef != null) {
loadFromEncodedCache(encodedRef, imageId, cacheKey, responder);
} else {
respondError(responder, "no bitmap withId=" + imageId);
mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
return;
}
} }
mPerfLogger.endMarker("Sonar.Fresco.getImage");
}
private void loadFromBitmapCache(
final CloseableReference<CloseableImage> ref,
final String imageId,
final CacheKey cacheKey,
final FlipperResponder responder) {
if (ref.get() instanceof CloseableBitmap) { if (ref.get() instanceof CloseableBitmap) {
final CloseableBitmap bitmap = (CloseableBitmap) ref.get(); final CloseableBitmap bitmap = (CloseableBitmap) ref.get();
String encodedBitmap = String encodedBitmap =
@@ -212,7 +239,34 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
// CloseableBitmap, this issue is tracked in the before mentioned task // CloseableBitmap, this issue is tracked in the before mentioned task
responder.success(); responder.success();
} }
mPerfLogger.endMarker("Sonar.Fresco.getImage"); }
private void loadFromEncodedCache(
final CloseableReference<PooledByteBuffer> encodedRef,
final String imageId,
final CacheKey cacheKey,
final FlipperResponder responder)
throws Exception {
byte[] encodedArray =
ByteStreams.toByteArray(new PooledByteBufferInputStream(encodedRef.get()));
Pair<Integer, Integer> dimensions = BitmapUtil.decodeDimensions(encodedArray);
if (dimensions == null) {
respondError(responder, "can not get dimensions withId=" + imageId);
return;
}
responder.success(
new FlipperObject.Builder()
.put("imageId", imageId)
.put("uri", mFlipperImageTracker.getUriString(cacheKey))
.put("width", dimensions.first)
.put("height", dimensions.second)
.put("sizeBytes", encodedArray.length)
.put(
"data",
"data:image/jpeg;base64,"
+ Base64.encodeToString(encodedArray, Base64.DEFAULT))
.build());
} }
}); });
@@ -285,33 +339,44 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
} }
private FlipperObject getImageList( private FlipperObject getImageList(
CountingMemoryCacheInspector.DumpInfo memoryCache, final CountingMemoryCacheInspector.DumpInfo bitmapMemoryCache,
FlipperArray memoryCacheSharedEntries, final CountingMemoryCacheInspector.DumpInfo encodedMemoryCache) {
FlipperArray memoryCacheLRUEntries) {
return new FlipperObject.Builder() return new FlipperObject.Builder()
.put( .put(
"levels", "levels",
new FlipperArray.Builder() new FlipperArray.Builder()
.put( // bitmap
new FlipperObject.Builder() .put(getUsedStats("On screen bitmaps", bitmapMemoryCache))
.put("cacheType", "On screen bitmaps") .put(getCachedStats("Bitmap memory cache", bitmapMemoryCache))
.put("sizeBytes", memoryCache.size - memoryCache.lruSize) // encoded
.put("imageIds", memoryCacheSharedEntries) .put(getUsedStats("Used encoded images", encodedMemoryCache))
.build()) .put(getCachedStats("Cached encoded images", encodedMemoryCache))
.put(
new FlipperObject.Builder()
.put("cacheType", "Bitmap memory cache")
.put("clearKey", "memory")
.put("sizeBytes", memoryCache.size)
.put("maxSizeBytes", memoryCache.maxSize)
.put("imageIds", memoryCacheLRUEntries)
.build())
// TODO (t31947642): list images on disk // TODO (t31947642): list images on disk
.build()) .build())
.build(); .build();
} }
private FlipperObject getImageData( private FlipperObject getUsedStats(
final String cacheType, final CountingMemoryCacheInspector.DumpInfo memoryCache) {
return new FlipperObject.Builder()
.put("cacheType", cacheType)
.put("sizeBytes", memoryCache.size - memoryCache.lruSize)
.put("imageIds", buildImageIdList(memoryCache.sharedEntries))
.build();
}
private FlipperObject getCachedStats(
final String cacheType, final CountingMemoryCacheInspector.DumpInfo memoryCache) {
return new FlipperObject.Builder()
.put("cacheType", cacheType)
.put("clearKey", "memory")
.put("sizeBytes", memoryCache.size)
.put("maxSizeBytes", memoryCache.maxSize)
.put("imageIds", buildImageIdList(memoryCache.lruEntries))
.build();
}
private static FlipperObject getImageData(
String imageID, String encodedBitmap, CloseableBitmap bitmap, String uriString) { String imageID, String encodedBitmap, CloseableBitmap bitmap, String uriString) {
return new FlipperObject.Builder() return new FlipperObject.Builder()
.put("imageId", imageID) .put("imageId", imageID)