Move flipper-fresco-plugin to fresco's repo from flipper's repo (#4546)
Summary: Pull Request resolved: https://github.com/facebook/flipper/pull/4546 Move flipper-fresco-plugin to fresco's repo from flipper's repo Reviewed By: passy Differential Revision: D43467895 fbshipit-source-id: efea88563cf931baf4bda0c8bbdfbe41d0f769c5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
11f5330d7c
commit
2e31247486
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.compileSdkVersion
|
||||
buildToolsVersion rootProject.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.minSdkVersion
|
||||
targetSdkVersion rootProject.targetSdkVersion
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':android')
|
||||
implementation deps.fresco
|
||||
implementation deps.frescoFlipper
|
||||
compileOnly deps.jsr305
|
||||
|
||||
api deps.boltsTasks
|
||||
|
||||
// Exclude the actual stetho dep as we only want some of the fresco APIs here
|
||||
implementation(deps.frescoStetho) {
|
||||
exclude group: 'com.facebook.stetho'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.vanniktech.maven.publish'
|
||||
@@ -1,12 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the LICENSE
|
||||
# file in the root directory of this source tree.
|
||||
#
|
||||
|
||||
POM_NAME=Flipper Fresco Plugin
|
||||
POM_DESCRIPTION=Images plugin for Flipper
|
||||
POM_ARTIFACT_ID=flipper-fresco-plugin
|
||||
POM_PACKAGING=aar
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
~
|
||||
~ This source code is licensed under the MIT license found in the LICENSE
|
||||
~ file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.facebook.flipper.plugins.fresco">
|
||||
</manifest>
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.fresco;
|
||||
|
||||
public interface FrescoFlipperDebugPrefHelper {
|
||||
|
||||
interface Listener {
|
||||
void onEnabledStatusChanged(boolean enabled);
|
||||
}
|
||||
|
||||
void setDebugOverlayEnabled(boolean enabled);
|
||||
|
||||
boolean isDebugOverlayEnabled();
|
||||
|
||||
void setDebugOverlayEnabledListener(Listener l);
|
||||
}
|
||||
@@ -1,651 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.fresco;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Base64;
|
||||
import android.util.Pair;
|
||||
import bolts.Continuation;
|
||||
import bolts.Task;
|
||||
import com.facebook.cache.common.CacheKey;
|
||||
import com.facebook.cache.common.SimpleCacheKey;
|
||||
import com.facebook.cache.disk.DiskStorage;
|
||||
import com.facebook.common.internal.ByteStreams;
|
||||
import com.facebook.common.internal.Preconditions;
|
||||
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.NoOpDebugMemoryManager;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.common.references.SharedReference;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImageLoadStatus;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImageOriginUtils;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImagePerfData;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImagePerfDataListener;
|
||||
import com.facebook.flipper.core.FlipperArray;
|
||||
import com.facebook.flipper.core.FlipperConnection;
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.core.FlipperReceiver;
|
||||
import com.facebook.flipper.core.FlipperResponder;
|
||||
import com.facebook.flipper.perflogger.FlipperPerfLogger;
|
||||
import com.facebook.flipper.perflogger.NoOpFlipperPerfLogger;
|
||||
import com.facebook.flipper.plugins.common.BufferingFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.objecthelper.FlipperObjectHelper;
|
||||
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory;
|
||||
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector;
|
||||
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector.DumpInfoEntry;
|
||||
import com.facebook.imagepipeline.core.ImagePipelineFactory;
|
||||
import com.facebook.imagepipeline.debug.CloseableReferenceLeakTracker;
|
||||
import com.facebook.imagepipeline.debug.DebugImageTracker;
|
||||
import com.facebook.imagepipeline.debug.FlipperImageTracker;
|
||||
import com.facebook.imagepipeline.image.CloseableBitmap;
|
||||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.image.EncodedImage;
|
||||
import com.facebook.imageutils.BitmapUtil;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Allows Sonar to display the contents of Fresco's caches. This is useful for developers to debug
|
||||
* what images are being held in cache as they navigate through their app.
|
||||
*/
|
||||
public class FrescoFlipperPlugin extends BufferingFlipperPlugin
|
||||
implements ImagePerfDataListener, CloseableReferenceLeakTracker.Listener {
|
||||
|
||||
private static final String FRESCO_EVENT = "events";
|
||||
private static final String FRESCO_DEBUGOVERLAY_EVENT = "debug_overlay_event";
|
||||
private static final String FRESCO_CLOSEABLE_REFERENCE_LEAK_EVENT =
|
||||
"closeable_reference_leak_event";
|
||||
|
||||
private static final int BITMAP_PREVIEW_WIDTH = 150;
|
||||
private static final int BITMAP_PREVIEW_HEIGHT = 150;
|
||||
private static final int BITMAP_SCALING_THRESHOLD_WIDTH = 200;
|
||||
private static final int BITMAP_SCALING_THRESHOLD_HEIGHT = 200;
|
||||
|
||||
/** Helper for clearing cache. */
|
||||
private static final Predicate<CacheKey> ALWAYS_TRUE_PREDICATE =
|
||||
new Predicate<CacheKey>() {
|
||||
@Override
|
||||
public boolean apply(CacheKey cacheKey) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private final FlipperImageTracker mFlipperImageTracker;
|
||||
private final PlatformBitmapFactory mPlatformBitmapFactory;
|
||||
@Nullable private final FlipperObjectHelper mSonarObjectHelper;
|
||||
private final DebugMemoryManager mMemoryManager;
|
||||
private final FlipperPerfLogger mPerfLogger;
|
||||
@Nullable private final FrescoFlipperDebugPrefHelper mDebugPrefHelper;
|
||||
private final List<FlipperObject> mEvents = new ArrayList<>();
|
||||
|
||||
public FrescoFlipperPlugin(
|
||||
DebugImageTracker imageTracker,
|
||||
PlatformBitmapFactory bitmapFactory,
|
||||
@Nullable FlipperObjectHelper flipperObjectHelper,
|
||||
DebugMemoryManager memoryManager,
|
||||
FlipperPerfLogger perfLogger,
|
||||
@Nullable FrescoFlipperDebugPrefHelper debugPrefHelper,
|
||||
@Nullable CloseableReferenceLeakTracker closeableReferenceLeakTracker) {
|
||||
mFlipperImageTracker =
|
||||
imageTracker instanceof FlipperImageTracker
|
||||
? (FlipperImageTracker) imageTracker
|
||||
: new FlipperImageTracker();
|
||||
mPlatformBitmapFactory = bitmapFactory;
|
||||
mSonarObjectHelper = flipperObjectHelper;
|
||||
mMemoryManager = memoryManager;
|
||||
mPerfLogger = perfLogger;
|
||||
mDebugPrefHelper = debugPrefHelper;
|
||||
|
||||
if (closeableReferenceLeakTracker != null) {
|
||||
closeableReferenceLeakTracker.setListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public FrescoFlipperPlugin() {
|
||||
this(
|
||||
new FlipperImageTracker(),
|
||||
Fresco.getImagePipelineFactory().getPlatformBitmapFactory(),
|
||||
null,
|
||||
new NoOpDebugMemoryManager(),
|
||||
new NoOpFlipperPerfLogger(),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
public FlipperImageTracker getFlipperImageTracker() {
|
||||
return mFlipperImageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "Fresco";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect(FlipperConnection connection) {
|
||||
super.onConnect(connection);
|
||||
connection.receive(
|
||||
"getAllImageEventsInfo",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FlipperArray.Builder arrayBuilder = new FlipperArray.Builder();
|
||||
for (FlipperObject obj : mEvents) {
|
||||
arrayBuilder.put(obj);
|
||||
}
|
||||
mEvents.clear();
|
||||
|
||||
FlipperObject object =
|
||||
new FlipperObject.Builder().put("events", arrayBuilder.build()).build();
|
||||
responder.success(object);
|
||||
}
|
||||
});
|
||||
|
||||
connection.receive(
|
||||
"listImages",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPerfLogger.startMarker("Sonar.Fresco.listImages");
|
||||
final boolean showDiskImages = params.getBoolean("showDiskImages");
|
||||
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
|
||||
|
||||
final CountingMemoryCacheInspector.DumpInfo bitmapMemoryCache =
|
||||
new CountingMemoryCacheInspector<>(
|
||||
imagePipelineFactory.getBitmapCountingMemoryCache())
|
||||
.dumpCacheContent();
|
||||
final CountingMemoryCacheInspector.DumpInfo encodedMemoryCache =
|
||||
new CountingMemoryCacheInspector<>(
|
||||
imagePipelineFactory.getEncodedCountingMemoryCache())
|
||||
.dumpCacheContent();
|
||||
|
||||
try {
|
||||
responder.success(
|
||||
getImageList(bitmapMemoryCache, encodedMemoryCache, showDiskImages));
|
||||
mPerfLogger.endMarker("Sonar.Fresco.listImages");
|
||||
} finally {
|
||||
bitmapMemoryCache.release();
|
||||
encodedMemoryCache.release();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connection.receive(
|
||||
"getImage",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, final FlipperResponder responder)
|
||||
throws Exception {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPerfLogger.startMarker("Sonar.Fresco.getImage");
|
||||
final String imageId = params.getString("imageId");
|
||||
final CacheKey cacheKey = mFlipperImageTracker.getCacheKey(imageId);
|
||||
if (cacheKey == null) {
|
||||
respondError(responder, "ImageId " + imageId + " was evicted from cache");
|
||||
mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
|
||||
return;
|
||||
}
|
||||
|
||||
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
|
||||
|
||||
// try to load from bitmap cache
|
||||
@Nullable
|
||||
CloseableImage closeableImage =
|
||||
imagePipelineFactory.getBitmapCountingMemoryCache().inspect(cacheKey);
|
||||
if (closeableImage instanceof CloseableBitmap) {
|
||||
@Nullable Bitmap bitmap = ((CloseableBitmap) closeableImage).getUnderlyingBitmap();
|
||||
if (bitmap != null) {
|
||||
loadFromBitmapCache(bitmap, imageId, cacheKey, responder);
|
||||
mPerfLogger.endMarker("Sonar.Fresco.getImage");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// try to load from encoded cache
|
||||
PooledByteBuffer encoded =
|
||||
imagePipelineFactory.getEncodedCountingMemoryCache().inspect(cacheKey);
|
||||
if (encoded != null) {
|
||||
loadFromEncodedCache(encoded, imageId, cacheKey, responder);
|
||||
mPerfLogger.endMarker("Sonar.Fresco.getImage");
|
||||
return;
|
||||
}
|
||||
|
||||
// try to load from disk
|
||||
loadFromDisk(imageId, cacheKey, responder);
|
||||
}
|
||||
|
||||
private void loadFromBitmapCache(
|
||||
final Bitmap bitmap,
|
||||
final String imageId,
|
||||
final CacheKey cacheKey,
|
||||
final FlipperResponder responder) {
|
||||
String encodedBitmap = bitmapToBase64Preview(bitmap, mPlatformBitmapFactory);
|
||||
responder.success(
|
||||
getImageData(
|
||||
imageId,
|
||||
mFlipperImageTracker.getUriString(cacheKey),
|
||||
bitmap.getWidth(),
|
||||
bitmap.getHeight(),
|
||||
BitmapUtil.getSizeInBytes(bitmap),
|
||||
encodedBitmap));
|
||||
}
|
||||
|
||||
private void loadFromEncodedCache(
|
||||
final PooledByteBuffer encoded,
|
||||
final String imageId,
|
||||
final CacheKey cacheKey,
|
||||
final FlipperResponder responder)
|
||||
throws Exception {
|
||||
byte[] encodedArray = ByteStreams.toByteArray(new PooledByteBufferInputStream(encoded));
|
||||
Pair<Integer, Integer> dimensions = BitmapUtil.decodeDimensions(encodedArray);
|
||||
if (dimensions == null) {
|
||||
respondError(responder, "can not get dimensions withId=" + imageId);
|
||||
return;
|
||||
}
|
||||
|
||||
responder.success(
|
||||
getImageData(
|
||||
imageId,
|
||||
mFlipperImageTracker.getUriString(cacheKey),
|
||||
dimensions.first,
|
||||
dimensions.second,
|
||||
encodedArray.length,
|
||||
dataFromEncodedArray(encodedArray)));
|
||||
}
|
||||
|
||||
private void loadFromDisk(
|
||||
final String imageId, final CacheKey cacheKey, final FlipperResponder responder) {
|
||||
Task<EncodedImage> t =
|
||||
Fresco.getImagePipelineFactory()
|
||||
.getMainBufferedDiskCache()
|
||||
.get(cacheKey, new AtomicBoolean(false));
|
||||
|
||||
t.continueWith(
|
||||
new Continuation<EncodedImage, Void>() {
|
||||
public Void then(Task<EncodedImage> task) throws Exception {
|
||||
if (task.isCancelled() || task.isFaulted()) {
|
||||
respondError(responder, "no bitmap withId=" + imageId);
|
||||
mPerfLogger.cancelMarker("Sonar.Fresco.getImage");
|
||||
return null;
|
||||
}
|
||||
Preconditions.checkNotNull(task);
|
||||
final EncodedImage image = task.getResult();
|
||||
try {
|
||||
InputStream stream = Preconditions.checkNotNull(image.getInputStream());
|
||||
byte[] encodedArray = ByteStreams.toByteArray(stream);
|
||||
|
||||
responder.success(
|
||||
getImageData(
|
||||
imageId,
|
||||
Preconditions.checkNotNull(
|
||||
mFlipperImageTracker.getLocalPath(cacheKey)),
|
||||
image.getWidth(),
|
||||
image.getHeight(),
|
||||
encodedArray.length,
|
||||
dataFromEncodedArray(encodedArray)));
|
||||
} finally {
|
||||
EncodedImage.closeSafely(image);
|
||||
}
|
||||
mPerfLogger.endMarker("Sonar.Fresco.getImage");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
connection.receive(
|
||||
"clear",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPerfLogger.startMarker("Sonar.Fresco.clear");
|
||||
final String type = params.getString("type");
|
||||
switch (type) {
|
||||
case "memory":
|
||||
final ImagePipelineFactory imagePipelineFactory = Fresco.getImagePipelineFactory();
|
||||
imagePipelineFactory.getBitmapMemoryCache().removeAll(ALWAYS_TRUE_PREDICATE);
|
||||
break;
|
||||
case "disk":
|
||||
Fresco.getImagePipeline().clearDiskCaches();
|
||||
break;
|
||||
}
|
||||
mPerfLogger.endMarker("Sonar.Fresco.clear");
|
||||
}
|
||||
});
|
||||
|
||||
connection.receive(
|
||||
"trimMemory",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mMemoryManager != null) {
|
||||
mMemoryManager.trimMemory(
|
||||
DebugMemoryManager.ON_SYSTEM_LOW_MEMORY_WHILE_APP_IN_FOREGROUND);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connection.receive(
|
||||
"enableDebugOverlay",
|
||||
new FlipperReceiver() {
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
if (!ensureFrescoInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean enabled = params.getBoolean("enabled");
|
||||
if (mDebugPrefHelper != null) {
|
||||
mDebugPrefHelper.setDebugOverlayEnabled(enabled);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (mDebugPrefHelper != null) {
|
||||
mDebugPrefHelper.setDebugOverlayEnabledListener(
|
||||
new FrescoFlipperDebugPrefHelper.Listener() {
|
||||
@Override
|
||||
public void onEnabledStatusChanged(boolean enabled) {
|
||||
sendDebugOverlayEnabledEvent(enabled);
|
||||
}
|
||||
});
|
||||
sendDebugOverlayEnabledEvent(mDebugPrefHelper.isDebugOverlayEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
private static String dataFromEncodedArray(byte[] encodedArray) {
|
||||
return "data:image/jpeg;base64," + Base64.encodeToString(encodedArray, Base64.DEFAULT);
|
||||
}
|
||||
|
||||
private FlipperObject getImageList(
|
||||
final CountingMemoryCacheInspector.DumpInfo bitmapMemoryCache,
|
||||
final CountingMemoryCacheInspector.DumpInfo encodedMemoryCache,
|
||||
final boolean showDiskImages)
|
||||
throws IOException {
|
||||
FlipperArray.Builder levelsBuilder =
|
||||
new FlipperArray.Builder()
|
||||
// bitmap
|
||||
.put(getUsedStats("On screen bitmaps", bitmapMemoryCache))
|
||||
.put(getCachedStats("Bitmap memory cache", bitmapMemoryCache))
|
||||
// encoded
|
||||
.put(getUsedStats("Used encoded images", encodedMemoryCache))
|
||||
.put(getCachedStats("Cached encoded images", encodedMemoryCache));
|
||||
if (showDiskImages) {
|
||||
levelsBuilder.put(
|
||||
getDiskStats(
|
||||
"Disk images",
|
||||
Fresco.getImagePipelineFactory().getMainFileCache().getDumpInfo().entries));
|
||||
}
|
||||
|
||||
return new FlipperObject.Builder().put("levels", levelsBuilder.build()).build();
|
||||
}
|
||||
|
||||
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 FlipperObject getDiskStats(
|
||||
final String cacheType, List<DiskStorage.DiskDumpInfoEntry> diskEntries) {
|
||||
return new FlipperObject.Builder()
|
||||
.put("cacheType", cacheType)
|
||||
.put("clearKey", "disk")
|
||||
.put("sizeBytes", Fresco.getImagePipelineFactory().getMainFileCache().getSize())
|
||||
.put("imageIds", buildImageIdListDisk(diskEntries))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static FlipperObject getImageData(
|
||||
String imageID, String uriString, int width, int height, int sizeBytes, String data) {
|
||||
return new FlipperObject.Builder()
|
||||
.put("imageId", imageID)
|
||||
.put("uri", uriString)
|
||||
.put("width", width)
|
||||
.put("height", height)
|
||||
.put("sizeBytes", sizeBytes)
|
||||
.put("data", data)
|
||||
.build();
|
||||
}
|
||||
|
||||
private boolean ensureFrescoInitialized() {
|
||||
mPerfLogger.startMarker("Sonar.Fresco.ensureFrescoInitialized");
|
||||
try {
|
||||
Fresco.getImagePipelineFactory();
|
||||
return true;
|
||||
} catch (NullPointerException e) {
|
||||
return false;
|
||||
} finally {
|
||||
mPerfLogger.endMarker("Sonar.Fresco.ensureFrescoInitialized");
|
||||
}
|
||||
}
|
||||
|
||||
private FlipperArray buildImageIdList(List<DumpInfoEntry<CacheKey, CloseableImage>> images) {
|
||||
FlipperArray.Builder builder = new FlipperArray.Builder();
|
||||
for (DumpInfoEntry<CacheKey, CloseableImage> entry : images) {
|
||||
final FlipperImageTracker.ImageDebugData imageDebugData =
|
||||
mFlipperImageTracker.getImageDebugData(entry.key);
|
||||
|
||||
if (imageDebugData == null) {
|
||||
builder.put(mFlipperImageTracker.trackImage(entry.key).getUniqueId());
|
||||
} else {
|
||||
builder.put(imageDebugData.getUniqueId());
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private FlipperArray buildImageIdListDisk(List<DiskStorage.DiskDumpInfoEntry> diskEntries) {
|
||||
FlipperArray.Builder builder = new FlipperArray.Builder();
|
||||
for (DiskStorage.DiskDumpInfoEntry entry : diskEntries) {
|
||||
final CacheKey entryCacheKey = new SimpleCacheKey(entry.id, true);
|
||||
final FlipperImageTracker.ImageDebugData imageDebugData =
|
||||
mFlipperImageTracker.getImageDebugData(entryCacheKey);
|
||||
|
||||
if (imageDebugData == null) {
|
||||
builder.put(mFlipperImageTracker.trackImage(entry.path, entryCacheKey).getUniqueId());
|
||||
} else {
|
||||
builder.put(imageDebugData.getUniqueId());
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private String bitmapToBase64Preview(Bitmap bitmap, PlatformBitmapFactory bitmapFactory) {
|
||||
if (bitmap.getWidth() < BITMAP_SCALING_THRESHOLD_WIDTH
|
||||
&& bitmap.getHeight() < BITMAP_SCALING_THRESHOLD_HEIGHT) {
|
||||
return bitmapToBase64WithoutScaling(bitmap);
|
||||
}
|
||||
mPerfLogger.startMarker("Sonar.Fresco.bitmap2base64-resize");
|
||||
|
||||
// TODO (t19034797): properly load images
|
||||
CloseableReference<Bitmap> scaledBitmapReference = null;
|
||||
try {
|
||||
float previewAspectRatio = BITMAP_PREVIEW_WIDTH / BITMAP_PREVIEW_HEIGHT;
|
||||
float imageAspectRatio = bitmap.getWidth() / bitmap.getHeight();
|
||||
|
||||
int scaledWidth;
|
||||
int scaledHeight;
|
||||
if (previewAspectRatio > imageAspectRatio) {
|
||||
scaledWidth = bitmap.getWidth() * BITMAP_PREVIEW_HEIGHT / bitmap.getHeight();
|
||||
scaledHeight = BITMAP_PREVIEW_HEIGHT;
|
||||
} else {
|
||||
scaledWidth = BITMAP_PREVIEW_WIDTH;
|
||||
scaledHeight = bitmap.getHeight() * BITMAP_PREVIEW_WIDTH / bitmap.getWidth();
|
||||
}
|
||||
scaledBitmapReference =
|
||||
bitmapFactory.createScaledBitmap(bitmap, scaledWidth, scaledHeight, false);
|
||||
return bitmapToBase64WithoutScaling(scaledBitmapReference.get());
|
||||
} finally {
|
||||
CloseableReference.closeSafely(scaledBitmapReference);
|
||||
mPerfLogger.endMarker("Sonar.Fresco.bitmap2base64-resize");
|
||||
}
|
||||
}
|
||||
|
||||
private String bitmapToBase64WithoutScaling(Bitmap bitmap) {
|
||||
mPerfLogger.startMarker("Sonar.Fresco.bitmap2base64-orig");
|
||||
ByteArrayOutputStream byteArrayOutputStream = null;
|
||||
try {
|
||||
byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
||||
|
||||
return "data:image/png;base64,"
|
||||
+ Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
|
||||
} finally {
|
||||
if (byteArrayOutputStream != null) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
mPerfLogger.endMarker("Sonar.Fresco.bitmap2base64-orig");
|
||||
}
|
||||
}
|
||||
|
||||
public void onImageLoadStatusUpdated(
|
||||
ImagePerfData imagePerfData, @ImageLoadStatus int imageLoadStatus) {
|
||||
if (imageLoadStatus != ImageLoadStatus.SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
String requestId = imagePerfData.getRequestId();
|
||||
if (requestId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FlipperImageTracker.ImageDebugData data =
|
||||
mFlipperImageTracker.getDebugDataForRequestId(requestId);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FlipperArray.Builder imageIdsBuilder = new FlipperArray.Builder();
|
||||
Set<CacheKey> cks = data.getCacheKeys();
|
||||
if (cks != null) {
|
||||
for (CacheKey ck : cks) {
|
||||
FlipperImageTracker.ImageDebugData d = mFlipperImageTracker.getImageDebugData(ck);
|
||||
if (d != null) {
|
||||
imageIdsBuilder.put(d.getUniqueId());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
imageIdsBuilder.put(data.getUniqueId());
|
||||
}
|
||||
|
||||
FlipperArray attribution;
|
||||
Object callerContext = imagePerfData.getCallerContext();
|
||||
if (callerContext == null) {
|
||||
attribution = new FlipperArray.Builder().put("unknown").build();
|
||||
} else if (mSonarObjectHelper == null) {
|
||||
attribution = new FlipperArray.Builder().put(callerContext.toString()).build();
|
||||
} else {
|
||||
attribution = mSonarObjectHelper.fromCallerContext(callerContext);
|
||||
}
|
||||
|
||||
FlipperObject.Builder response =
|
||||
new FlipperObject.Builder()
|
||||
.put("imageIds", imageIdsBuilder.build())
|
||||
.put("attribution", attribution)
|
||||
.put("startTime", imagePerfData.getControllerSubmitTimeMs())
|
||||
.put("endTime", imagePerfData.getControllerFinalImageSetTimeMs())
|
||||
.put("source", ImageOriginUtils.toString(imagePerfData.getImageOrigin()));
|
||||
|
||||
if (!imagePerfData.isPrefetch()) {
|
||||
response.put(
|
||||
"viewport",
|
||||
new FlipperObject.Builder()
|
||||
// TODO (t31947746): scan times
|
||||
.put("width", imagePerfData.getOnScreenWidthPx())
|
||||
.put("height", imagePerfData.getOnScreenHeightPx())
|
||||
.build());
|
||||
}
|
||||
FlipperObject responseObject = response.build();
|
||||
mEvents.add(responseObject);
|
||||
send(FRESCO_EVENT, responseObject);
|
||||
}
|
||||
|
||||
public void onImageVisibilityUpdated(ImagePerfData imagePerfData, int visibilityState) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
public void sendDebugOverlayEnabledEvent(final boolean enabled) {
|
||||
final FlipperObject.Builder builder = new FlipperObject.Builder().put("enabled", enabled);
|
||||
send(FRESCO_DEBUGOVERLAY_EVENT, builder.build());
|
||||
}
|
||||
|
||||
private static void respondError(FlipperResponder responder, String errorReason) {
|
||||
responder.error(new FlipperObject.Builder().put("reason", errorReason).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCloseableReferenceLeak(
|
||||
SharedReference<Object> reference, @Nullable Throwable stacktrace) {
|
||||
Object object = reference.get();
|
||||
Preconditions.checkNotNull(object);
|
||||
final FlipperObject.Builder builder =
|
||||
new FlipperObject.Builder()
|
||||
.put("identityHashCode", System.identityHashCode(reference))
|
||||
.put("className", object.getClass().getName());
|
||||
if (stacktrace != null) {
|
||||
builder.put("stacktrace", getStackTraceString(stacktrace));
|
||||
}
|
||||
send(FRESCO_CLOSEABLE_REFERENCE_LEAK_EVENT, builder.build());
|
||||
}
|
||||
|
||||
public static String getStackTraceString(Throwable tr) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
tr.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.fresco;
|
||||
|
||||
import com.facebook.imagepipeline.debug.DebugImageTracker;
|
||||
import com.facebook.imagepipeline.listener.BaseRequestListener;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
|
||||
/** Fresco image {@link RequestListener} that logs events for Sonar. */
|
||||
public class FrescoFlipperRequestListener extends BaseRequestListener {
|
||||
|
||||
private final DebugImageTracker mDebugImageTracker;
|
||||
|
||||
public FrescoFlipperRequestListener(DebugImageTracker debugImageTracker) {
|
||||
mDebugImageTracker = debugImageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestStart(
|
||||
ImageRequest request, Object callerContext, String requestId, boolean isPrefetch) {
|
||||
mDebugImageTracker.trackImageRequest(request, requestId);
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.flipper.plugins.fresco.objecthelper;
|
||||
|
||||
import static com.facebook.flipper.plugins.inspector.InspectorValue.Type.Color;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImageOriginUtils;
|
||||
import com.facebook.drawee.backends.pipeline.info.ImagePerfData;
|
||||
import com.facebook.drawee.generic.RoundingParams;
|
||||
import com.facebook.flipper.core.FlipperArray;
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorValue;
|
||||
import com.facebook.imagepipeline.common.ImageDecodeOptions;
|
||||
import com.facebook.imagepipeline.common.ResizeOptions;
|
||||
import com.facebook.imagepipeline.common.RotationOptions;
|
||||
import com.facebook.imagepipeline.debug.FlipperImageTracker;
|
||||
import com.facebook.imagepipeline.image.ImageInfo;
|
||||
import com.facebook.imagepipeline.image.QualityInfo;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Serialization helper to create {@link FlipperObject}s. */
|
||||
public abstract class FlipperObjectHelper {
|
||||
|
||||
public FlipperObject keyValuePair(String key, @Nullable String value) {
|
||||
return new FlipperObject.Builder().put(key, value).build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable Map<String, String> stringMap) {
|
||||
if (stringMap == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
for (Map.Entry<String, String> entry : stringMap.entrySet()) {
|
||||
optionsJson.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable ImageRequest imageRequest) {
|
||||
if (imageRequest == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
return addImageRequestProperties(optionsJson, imageRequest).build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(
|
||||
@Nullable FlipperImageTracker.ImageDebugData imageDebugData) {
|
||||
if (imageDebugData == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
optionsJson.put("imageId", imageDebugData.getUniqueId());
|
||||
optionsJson.put("imageRequest", toFlipperObject(imageDebugData.getImageRequest()));
|
||||
optionsJson.put(
|
||||
"requestId",
|
||||
imageDebugData.getRequestIds() != null
|
||||
? TextUtils.join(", ", imageDebugData.getRequestIds())
|
||||
: "");
|
||||
optionsJson.put("imagePerfData", toFlipperObject(imageDebugData.getImagePerfData()));
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable ImageDecodeOptions options) {
|
||||
if (options == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
optionsJson.put("minDecodeIntervalMs", options.minDecodeIntervalMs);
|
||||
optionsJson.put("decodePreviewFrame", options.decodePreviewFrame);
|
||||
optionsJson.put("useLastFrameForPreview", options.useLastFrameForPreview);
|
||||
optionsJson.put("decodeAllFrames", options.decodeAllFrames);
|
||||
optionsJson.put("forceStaticImage", options.forceStaticImage);
|
||||
optionsJson.put("bitmapConfig", options.bitmapConfig.name());
|
||||
optionsJson.put(
|
||||
"customImageDecoder",
|
||||
options.customImageDecoder == null ? "" : options.customImageDecoder.toString());
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable ResizeOptions resizeOptions) {
|
||||
if (resizeOptions == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
optionsJson.put("width", resizeOptions.width);
|
||||
optionsJson.put("height", resizeOptions.height);
|
||||
optionsJson.put("maxBitmapSize", resizeOptions.maxBitmapSize);
|
||||
optionsJson.put("roundUpFraction", resizeOptions.roundUpFraction);
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable RotationOptions rotationOptions) {
|
||||
if (rotationOptions == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
optionsJson.put("rotationEnabled", rotationOptions.rotationEnabled());
|
||||
optionsJson.put("canDeferUntilRendered", rotationOptions.canDeferUntilRendered());
|
||||
optionsJson.put("useImageMetadata", rotationOptions.useImageMetadata());
|
||||
if (!rotationOptions.useImageMetadata()) {
|
||||
optionsJson.put("forcedAngle", rotationOptions.getForcedAngle());
|
||||
}
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable RoundingParams roundingParams) {
|
||||
if (roundingParams == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder optionsJson = new FlipperObject.Builder();
|
||||
optionsJson.put("borderWidth", roundingParams.getBorderWidth());
|
||||
optionsJson.put("cornersRadii", toSonarArray(roundingParams.getCornersRadii()));
|
||||
optionsJson.put("padding", roundingParams.getPadding());
|
||||
optionsJson.put("roundAsCircle", roundingParams.getRoundAsCircle());
|
||||
optionsJson.put("roundingMethod", roundingParams.getRoundingMethod());
|
||||
optionsJson.put(
|
||||
"borderColor", InspectorValue.immutable(Color, roundingParams.getBorderColor()));
|
||||
optionsJson.put(
|
||||
"overlayColor", InspectorValue.immutable(Color, roundingParams.getOverlayColor()));
|
||||
return optionsJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(@Nullable ImagePerfData imagePerfData) {
|
||||
if (imagePerfData == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder objectJson = new FlipperObject.Builder();
|
||||
objectJson.put("requestId", imagePerfData.getRequestId());
|
||||
objectJson.put("controllerSubmitTimeMs", imagePerfData.getControllerSubmitTimeMs());
|
||||
objectJson.put("controllerFinalTimeMs", imagePerfData.getControllerFinalImageSetTimeMs());
|
||||
objectJson.put("imageRequestStartTimeMs", imagePerfData.getImageRequestStartTimeMs());
|
||||
objectJson.put("imageRequestEndTimeMs", imagePerfData.getImageRequestEndTimeMs());
|
||||
objectJson.put("imageOrigin", ImageOriginUtils.toString(imagePerfData.getImageOrigin()));
|
||||
objectJson.put("isPrefetch", imagePerfData.isPrefetch());
|
||||
objectJson.put("callerContext", imagePerfData.getCallerContext());
|
||||
objectJson.put("imageRequest", toFlipperObject(imagePerfData.getImageRequest()));
|
||||
objectJson.put("imageInfo", toFlipperObject(imagePerfData.getImageInfo()));
|
||||
return objectJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(ImageInfo imageInfo) {
|
||||
if (imageInfo == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder objectJson = new FlipperObject.Builder();
|
||||
objectJson.put("imageWidth", imageInfo.getWidth());
|
||||
objectJson.put("imageHeight", imageInfo.getHeight());
|
||||
objectJson.put("qualityInfo", toFlipperObject(imageInfo.getQualityInfo()));
|
||||
return objectJson.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FlipperObject toFlipperObject(QualityInfo qualityInfo) {
|
||||
if (qualityInfo == null) {
|
||||
return null;
|
||||
}
|
||||
FlipperObject.Builder objectJson = new FlipperObject.Builder();
|
||||
objectJson.put("quality", qualityInfo.getQuality());
|
||||
objectJson.put("isGoodEnoughQuality", qualityInfo.isOfGoodEnoughQuality());
|
||||
objectJson.put("isFullQuality", qualityInfo.isOfFullQuality());
|
||||
return objectJson.build();
|
||||
}
|
||||
|
||||
public FlipperObject.Builder addImageRequestProperties(
|
||||
FlipperObject.Builder builder, @Nullable ImageRequest request) {
|
||||
if (request == null) {
|
||||
return builder;
|
||||
}
|
||||
builder
|
||||
.put("sourceUri", request.getSourceUri())
|
||||
.put("preferredWidth", request.getPreferredWidth())
|
||||
.put("preferredHeight", request.getPreferredHeight())
|
||||
.put("cacheChoice", request.getCacheChoice())
|
||||
.put("diskCacheEnabled", request.isDiskCacheEnabled())
|
||||
.put("localThumbnailPreviewsEnabled", request.getLocalThumbnailPreviewsEnabled())
|
||||
.put("lowestPermittedRequestLevel", request.getLowestPermittedRequestLevel())
|
||||
.put("priority", request.getPriority().name())
|
||||
.put("progressiveRenderingEnabled", request.getProgressiveRenderingEnabled())
|
||||
.put("postprocessor", String.valueOf(request.getPostprocessor()))
|
||||
.put("requestListener", String.valueOf(request.getRequestListener()))
|
||||
.put("imageDecodeOptions", toFlipperObject(request.getImageDecodeOptions()))
|
||||
.put("bytesRange", request.getBytesRange())
|
||||
.put("resizeOptions", toFlipperObject(request.getResizeOptions()))
|
||||
.put("rotationOptions", toFlipperObject(request.getRotationOptions()));
|
||||
return builder;
|
||||
}
|
||||
|
||||
private FlipperArray toSonarArray(float[] floats) {
|
||||
final FlipperArray.Builder builder = new FlipperArray.Builder();
|
||||
for (float f : floats) {
|
||||
builder.put(f);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract FlipperArray fromCallerContext(@Nullable Object callerContext);
|
||||
}
|
||||
@@ -38,6 +38,15 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst "**/libcrypto.so"
|
||||
pickFirst "**/libevent-2.1.so"
|
||||
pickFirst "**/libevent_core-2.1.so"
|
||||
pickFirst "**/libevent_extra-2.1.so"
|
||||
pickFirst "**/libflipper.so"
|
||||
pickFirst "**/libssl.so"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +66,7 @@ dependencies {
|
||||
implementation deps.soloader
|
||||
implementation deps.okhttp3
|
||||
implementation deps.fresco
|
||||
debugImplementation deps.flipperFrescoPlugin
|
||||
|
||||
// Integration test
|
||||
androidTestImplementation deps.testCore
|
||||
@@ -69,7 +79,6 @@ dependencies {
|
||||
testImplementation deps.junit
|
||||
|
||||
debugImplementation project(':android')
|
||||
debugImplementation project(':fresco-plugin')
|
||||
debugImplementation project(':network-plugin')
|
||||
debugImplementation project(':litho-plugin')
|
||||
releaseImplementation project(':noop')
|
||||
|
||||
@@ -36,6 +36,15 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst "**/libcrypto.so"
|
||||
pickFirst "**/libevent-2.1.so"
|
||||
pickFirst "**/libevent_core-2.1.so"
|
||||
pickFirst "**/libevent_extra-2.1.so"
|
||||
pickFirst "**/libflipper.so"
|
||||
pickFirst "**/libssl.so"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -47,9 +56,9 @@ dependencies {
|
||||
// For simplicity, we use Flipper for both debug and release builds here.
|
||||
// Check out the "sample" app to see how to separate your build flavors.
|
||||
implementation project(':android')
|
||||
implementation project(':fresco-plugin')
|
||||
implementation project(':network-plugin')
|
||||
implementation project(':litho-plugin')
|
||||
implementation deps.flipperFrescoPlugin
|
||||
implementation deps.soloader
|
||||
|
||||
// Litho
|
||||
|
||||
@@ -108,7 +108,8 @@ ext.deps = [
|
||||
testCore : 'androidx.test:core:1.4.0',
|
||||
testRules : 'androidx.test:rules:1.5.0',
|
||||
// Plugin dependencies
|
||||
flipperFrescoPlugin: 'com.facebook.flipper:flipper-fresco-plugin:0.182.0',
|
||||
frescoFlipper : 'com.facebook.fresco:flipper:2.6.0',
|
||||
frescoStetho : 'com.facebook.fresco:stetho:2.6.0',
|
||||
fresco : 'com.facebook.fresco:fresco:2.6.0'
|
||||
fresco : 'com.facebook.fresco:fresco:2.6.0',
|
||||
]
|
||||
|
||||
@@ -28,9 +28,6 @@ project(':third-party').projectDir = file('android/third-party/')
|
||||
project(':noop').projectDir = file('android/no-op/')
|
||||
|
||||
// Plugins
|
||||
include ':fresco-plugin'
|
||||
project(':fresco-plugin').projectDir = file('android/plugins/fresco')
|
||||
|
||||
include ':network-plugin'
|
||||
project(':network-plugin').projectDir = file('android/plugins/network')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user