Change the implementation of fresco plugin on android

Summary: This updates the implementation of the export of the fresco plugin on the android side. Initially we used to send all the images info in one call, but its not scalable, as the images increase, the payload size of the rsocket can increase which will lead rsocket to drop messages. This diff updates the implementation of android side to match the one on the iOS side.

Reviewed By: passy

Differential Revision: D16627823

fbshipit-source-id: 563bf5fb20595c198b6447bb4e41f04af6e46644
This commit is contained in:
Pritesh Nandgaonkar
2019-08-08 09:13:32 -07:00
committed by Facebook Github Bot
parent 72d23f190b
commit 53c1eee641
2 changed files with 64 additions and 144 deletions

View File

@@ -127,54 +127,13 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
public void onConnect(FlipperConnection connection) { public void onConnect(FlipperConnection connection) {
super.onConnect(connection); super.onConnect(connection);
connection.receive( connection.receive(
"getAllImageData", "getAllImageEventsInfo",
new FlipperReceiver() { new FlipperReceiver() {
@Override @Override
public void onReceive(FlipperObject params, FlipperResponder responder) { public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
if (!ensureFrescoInitialized(responder)) { if (!ensureFrescoInitialized(responder)) {
return; return;
} }
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
final CountingMemoryCacheInspector.DumpInfo memoryCache =
new CountingMemoryCacheInspector<>(
imagePipelineFactory.getBitmapCountingMemoryCache())
.dumpCacheContent();
final FlipperArray memoryCacheSharedEntries =
buildImageIdList(memoryCache.sharedEntries);
final FlipperArray memoryCacheLRUEntries = buildImageIdList(memoryCache.lruEntries);
final FlipperArray.Builder imageIDListBuilder = new FlipperArray.Builder();
for (int i = 0; i < memoryCacheSharedEntries.length(); ++i) {
final String imageID = memoryCacheSharedEntries.getString(i);
imageIDListBuilder.put(imageID);
}
for (int i = 0; i < memoryCacheLRUEntries.length(); ++i) {
final String imageID = memoryCacheLRUEntries.getString(i);
imageIDListBuilder.put(imageID);
}
final FlipperArray imageIDs = imageIDListBuilder.build();
final FlipperObject levels =
getImageList(memoryCache, memoryCacheSharedEntries, memoryCacheLRUEntries);
final FlipperArray.Builder imageDataListBuilder = new FlipperArray.Builder();
for (int i = 0; i < imageIDs.length(); ++i) {
final String imageID = imageIDs.getString(i);
final CacheKey cacheKey = mFlipperImageTracker.getCacheKey(imageID);
if (cacheKey == null) {
continue;
}
final CloseableReference<CloseableImage> ref =
imagePipelineFactory.getBitmapCountingMemoryCache().get(cacheKey);
if (ref == null) {
continue;
}
final CloseableBitmap bitmap = (CloseableBitmap) ref.get();
final String encodedBitmap =
bitmapToBase64Preview(bitmap.getUnderlyingBitmap(), mPlatformBitmapFactory);
imageDataListBuilder.put(
getImageData(
imageID, encodedBitmap, bitmap, mFlipperImageTracker.getUriString(cacheKey)));
}
FlipperArray.Builder arrayBuilder = new FlipperArray.Builder(); FlipperArray.Builder arrayBuilder = new FlipperArray.Builder();
for (FlipperObject obj : mEvents) { for (FlipperObject obj : mEvents) {
@@ -183,14 +142,11 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
mEvents.clear(); mEvents.clear();
FlipperObject object = FlipperObject object =
new FlipperObject.Builder() new FlipperObject.Builder().put("events", arrayBuilder.build()).build();
.put("levels", levels)
.put("imageDataList", imageDataListBuilder.build())
.put("events", arrayBuilder.build())
.build();
responder.success(object); responder.success(object);
} }
}); });
connection.receive( connection.receive(
"listImages", "listImages",
new FlipperReceiver() { new FlipperReceiver() {
@@ -241,6 +197,8 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
mPerfLogger.cancelMarker("Sonar.Fresco.getImage"); mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
return; return;
} }
if (ref.get() instanceof CloseableBitmap) {
final CloseableBitmap bitmap = (CloseableBitmap) ref.get(); final CloseableBitmap bitmap = (CloseableBitmap) ref.get();
String encodedBitmap = String encodedBitmap =
bitmapToBase64Preview(bitmap.getUnderlyingBitmap(), mPlatformBitmapFactory); bitmapToBase64Preview(bitmap.getUnderlyingBitmap(), mPlatformBitmapFactory);
@@ -248,7 +206,11 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
responder.success( responder.success(
getImageData( getImageData(
imageId, encodedBitmap, bitmap, mFlipperImageTracker.getUriString(cacheKey))); imageId, encodedBitmap, bitmap, mFlipperImageTracker.getUriString(cacheKey)));
} else {
// TODO: T48376327, it might happened that ref.get() may not be casted to
// CloseableBitmap, this issue is tracked in the before mentioned task
responder.success();
}
mPerfLogger.endMarker("Sonar.Fresco.getImage"); mPerfLogger.endMarker("Sonar.Fresco.getImage");
} }
}); });

View File

@@ -109,7 +109,6 @@ export default class FlipperImagesPlugin extends FlipperPlugin<
return defaultPromise; return defaultPromise;
} }
const selectedDevice = store.getState().connections.selectedDevice; const selectedDevice = store.getState().connections.selectedDevice;
if (selectedDevice && selectedDevice.os === 'iOS') {
return Promise.all([ return Promise.all([
callClient('listImages'), callClient('listImages'),
callClient('getAllImageEventsInfo'), callClient('getAllImageEventsInfo'),
@@ -118,64 +117,7 @@ export default class FlipperImagesPlugin extends FlipperPlugin<
const events: Array<ImageEventWithId> = responseEvents.events; const events: Array<ImageEventWithId> = responseEvents.events;
let pluginData: PersistedState = { let pluginData: PersistedState = {
...persistedState, ...persistedState,
images: persistedState images: persistedState ? [...persistedState.images, ...levels] : levels,
? [...persistedState.images, ...levels]
: levels,
closeableReferenceLeaks:
(persistedState && persistedState.closeableReferenceLeaks) || [],
};
events.forEach((event: ImageEventWithId, index) => {
if (!event) {
return;
}
const {attribution} = event;
if (
attribution &&
attribution instanceof Array &&
attribution.length > 0
) {
const surface = attribution[0].trim();
if (surface.length > 0) {
pluginData.surfaceList.add(surface);
}
}
pluginData = {
...pluginData,
events: [{eventId: index, ...event}, ...pluginData.events],
};
});
const idSet: Set<string> = levels.reduce((acc, level: CacheInfo) => {
level.imageIds.forEach(id => {
acc.add(id);
});
return acc;
}, new Set());
const imageDataList: Array<ImageData> = [];
for (const id: string of idSet) {
const imageData: ImageData = await callClient('getImage', {
imageId: id,
});
imageDataList.push(imageData);
}
imageDataList.forEach((data: ImageData) => {
const imagesMap = {...pluginData.imagesMap};
imagesMap[data.imageId] = data;
pluginData.imagesMap = imagesMap;
});
return pluginData;
});
} else {
return callClient('getAllImageData').then((data: ImagesMetaData) => {
if (!data) {
return;
}
const {levels, events, imageDataList} = data;
let pluginData: PersistedState = {
...persistedState,
images: persistedState
? [...persistedState.images, ...levels.levels]
: levels.levels,
closeableReferenceLeaks: closeableReferenceLeaks:
(persistedState && persistedState.closeableReferenceLeaks) || [], (persistedState && persistedState.closeableReferenceLeaks) || [],
}; };
@@ -200,14 +142,30 @@ export default class FlipperImagesPlugin extends FlipperPlugin<
events: [{eventId: index, ...event}, ...pluginData.events], events: [{eventId: index, ...event}, ...pluginData.events],
}; };
}); });
const idSet: Set<string> = levels.reduce((acc, level: CacheInfo) => {
imageDataList.forEach((imageData: ImageData) => { level.imageIds.forEach(id => {
const {imageId} = imageData; acc.add(id);
pluginData.imagesMap[imageId] = imageData; });
return acc;
}, new Set());
const imageDataList: Array<ImageData> = [];
for (const id: string of idSet) {
try {
const imageData: ImageData = await callClient('getImage', {
imageId: id,
});
imageDataList.push(imageData);
} catch (e) {
console.error(e);
}
}
imageDataList.forEach((data: ImageData) => {
const imagesMap = {...pluginData.imagesMap};
imagesMap[data.imageId] = data;
pluginData.imagesMap = imagesMap;
}); });
return pluginData; return pluginData;
}); });
}
}; };
static persistedStateReducer = ( static persistedStateReducer = (