diff --git a/android/plugins/fresco/build.gradle b/android/plugins/fresco/build.gradle deleted file mode 100644 index 737ae77b1d2..00000000000 --- a/android/plugins/fresco/build.gradle +++ /dev/null @@ -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' diff --git a/android/plugins/fresco/gradle.properties b/android/plugins/fresco/gradle.properties deleted file mode 100644 index 47f4e428c86..00000000000 --- a/android/plugins/fresco/gradle.properties +++ /dev/null @@ -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 - diff --git a/android/plugins/fresco/src/main/AndroidManifest.xml b/android/plugins/fresco/src/main/AndroidManifest.xml deleted file mode 100644 index 0bafe358f93..00000000000 --- a/android/plugins/fresco/src/main/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperDebugPrefHelper.java b/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperDebugPrefHelper.java deleted file mode 100644 index bc17585ae9c..00000000000 --- a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperDebugPrefHelper.java +++ /dev/null @@ -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); -} diff --git a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperPlugin.java b/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperPlugin.java deleted file mode 100644 index 0d9c0f31aab..00000000000 --- a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperPlugin.java +++ /dev/null @@ -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 ALWAYS_TRUE_PREDICATE = - new Predicate() { - @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 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 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 t = - Fresco.getImagePipelineFactory() - .getMainBufferedDiskCache() - .get(cacheKey, new AtomicBoolean(false)); - - t.continueWith( - new Continuation() { - public Void then(Task 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 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> images) { - FlipperArray.Builder builder = new FlipperArray.Builder(); - for (DumpInfoEntry 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 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 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 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 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(); - } -} diff --git a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperRequestListener.java b/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperRequestListener.java deleted file mode 100644 index cba60f81a59..00000000000 --- a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/FrescoFlipperRequestListener.java +++ /dev/null @@ -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); - } -} diff --git a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/objecthelper/FlipperObjectHelper.java b/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/objecthelper/FlipperObjectHelper.java deleted file mode 100644 index 722193d3b95..00000000000 --- a/android/plugins/fresco/src/main/java/com/facebook/flipper/plugins/fresco/objecthelper/FlipperObjectHelper.java +++ /dev/null @@ -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 stringMap) { - if (stringMap == null) { - return null; - } - FlipperObject.Builder optionsJson = new FlipperObject.Builder(); - for (Map.Entry 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); -} diff --git a/android/sample/build.gradle b/android/sample/build.gradle index 4d199132809..123203b200f 100644 --- a/android/sample/build.gradle +++ b/android/sample/build.gradle @@ -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') diff --git a/android/tutorial/build.gradle b/android/tutorial/build.gradle index 11a588072dc..4710cd52231 100644 --- a/android/tutorial/build.gradle +++ b/android/tutorial/build.gradle @@ -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 diff --git a/build.gradle b/build.gradle index b8ae3bba010..3fd403562f8 100644 --- a/build.gradle +++ b/build.gradle @@ -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', ] diff --git a/settings.gradle b/settings.gradle index 8fe83c2f8f0..223366ba16b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -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')