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:
committed by
Facebook Github Bot
parent
72d23f190b
commit
53c1eee641
@@ -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,14 +197,20 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin
|
|||||||
mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
|
mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final CloseableBitmap bitmap = (CloseableBitmap) ref.get();
|
|
||||||
String encodedBitmap =
|
|
||||||
bitmapToBase64Preview(bitmap.getUnderlyingBitmap(), mPlatformBitmapFactory);
|
|
||||||
|
|
||||||
responder.success(
|
if (ref.get() instanceof CloseableBitmap) {
|
||||||
getImageData(
|
final CloseableBitmap bitmap = (CloseableBitmap) ref.get();
|
||||||
imageId, encodedBitmap, bitmap, mFlipperImageTracker.getUriString(cacheKey)));
|
String encodedBitmap =
|
||||||
|
bitmapToBase64Preview(bitmap.getUnderlyingBitmap(), mPlatformBitmapFactory);
|
||||||
|
|
||||||
|
responder.success(
|
||||||
|
getImageData(
|
||||||
|
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");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -109,105 +109,63 @@ 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'),
|
]).then(async ([responseImages, responseEvents]) => {
|
||||||
]).then(async ([responseImages, responseEvents]) => {
|
const levels: ImagesList = responseImages.levels;
|
||||||
const levels: ImagesList = responseImages.levels;
|
const events: Array<ImageEventWithId> = responseEvents.events;
|
||||||
const events: Array<ImageEventWithId> = responseEvents.events;
|
let pluginData: PersistedState = {
|
||||||
let pluginData: PersistedState = {
|
...persistedState,
|
||||||
...persistedState,
|
images: persistedState ? [...persistedState.images, ...levels] : levels,
|
||||||
images: persistedState
|
closeableReferenceLeaks:
|
||||||
? [...persistedState.images, ...levels]
|
(persistedState && persistedState.closeableReferenceLeaks) || [],
|
||||||
: levels,
|
};
|
||||||
closeableReferenceLeaks:
|
|
||||||
(persistedState && persistedState.closeableReferenceLeaks) || [],
|
|
||||||
};
|
|
||||||
|
|
||||||
events.forEach((event: ImageEventWithId, index) => {
|
events.forEach((event: ImageEventWithId, index) => {
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
const {attribution} = event;
|
||||||
|
if (
|
||||||
|
attribution &&
|
||||||
|
attribution instanceof Array &&
|
||||||
|
attribution.length > 0
|
||||||
|
) {
|
||||||
|
const surface = attribution[0] ? attribution[0].trim() : undefined;
|
||||||
|
if (surface && surface.length > 0) {
|
||||||
|
pluginData.surfaceList.add(surface);
|
||||||
}
|
}
|
||||||
const {attribution} = event;
|
}
|
||||||
if (
|
pluginData = {
|
||||||
attribution &&
|
...pluginData,
|
||||||
attribution instanceof Array &&
|
events: [{eventId: index, ...event}, ...pluginData.events],
|
||||||
attribution.length > 0
|
};
|
||||||
) {
|
});
|
||||||
const surface = attribution[0].trim();
|
const idSet: Set<string> = levels.reduce((acc, level: CacheInfo) => {
|
||||||
if (surface.length > 0) {
|
level.imageIds.forEach(id => {
|
||||||
pluginData.surfaceList.add(surface);
|
acc.add(id);
|
||||||
}
|
|
||||||
}
|
|
||||||
pluginData = {
|
|
||||||
...pluginData,
|
|
||||||
events: [{eventId: index, ...event}, ...pluginData.events],
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
const idSet: Set<string> = levels.reduce((acc, level: CacheInfo) => {
|
return acc;
|
||||||
level.imageIds.forEach(id => {
|
}, new Set());
|
||||||
acc.add(id);
|
const imageDataList: Array<ImageData> = [];
|
||||||
});
|
for (const id: string of idSet) {
|
||||||
return acc;
|
try {
|
||||||
}, new Set());
|
|
||||||
const imageDataList: Array<ImageData> = [];
|
|
||||||
for (const id: string of idSet) {
|
|
||||||
const imageData: ImageData = await callClient('getImage', {
|
const imageData: ImageData = await callClient('getImage', {
|
||||||
imageId: id,
|
imageId: id,
|
||||||
});
|
});
|
||||||
imageDataList.push(imageData);
|
imageDataList.push(imageData);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
imageDataList.forEach((data: ImageData) => {
|
}
|
||||||
const imagesMap = {...pluginData.imagesMap};
|
imageDataList.forEach((data: ImageData) => {
|
||||||
imagesMap[data.imageId] = data;
|
const imagesMap = {...pluginData.imagesMap};
|
||||||
pluginData.imagesMap = imagesMap;
|
imagesMap[data.imageId] = data;
|
||||||
});
|
pluginData.imagesMap = imagesMap;
|
||||||
return pluginData;
|
|
||||||
});
|
});
|
||||||
} else {
|
return pluginData;
|
||||||
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:
|
|
||||||
(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] ? attribution[0].trim() : undefined;
|
|
||||||
if (surface && surface.length > 0) {
|
|
||||||
pluginData.surfaceList.add(surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pluginData = {
|
|
||||||
...pluginData,
|
|
||||||
events: [{eventId: index, ...event}, ...pluginData.events],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
imageDataList.forEach((imageData: ImageData) => {
|
|
||||||
const {imageId} = imageData;
|
|
||||||
pluginData.imagesMap[imageId] = imageData;
|
|
||||||
});
|
|
||||||
return pluginData;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static persistedStateReducer = (
|
static persistedStateReducer = (
|
||||||
|
|||||||
Reference in New Issue
Block a user