From 17c49e28799b329530796993bc1d38aa4c157cf1 Mon Sep 17 00:00:00 2001 From: Mike Armstrong Date: Mon, 5 Oct 2015 08:02:39 -0700 Subject: [PATCH] systrace of Fresco Differential Revision: D2507874 --- .../react/modules/fresco/FrescoModule.java | 9 + .../fresco/SystraceRequestListener.java | 196 ++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/fresco/SystraceRequestListener.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java index 20f163fe3..9f278ab57 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java @@ -9,6 +9,8 @@ package com.facebook.react.modules.fresco; +import java.util.HashSet; + import android.content.Context; import com.facebook.cache.common.CacheKey; @@ -18,6 +20,7 @@ import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory; import com.facebook.imagepipeline.core.ImagePipelineConfig; import com.facebook.imagepipeline.core.ImagePipelineFactory; +import com.facebook.imagepipeline.listener.RequestListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.modules.common.ModuleDataCleaner; @@ -38,6 +41,7 @@ public class FrescoModule extends ReactContextBaseJavaModule implements super(reactContext); } + @Override public void initialize() { super.initialize(); @@ -50,11 +54,16 @@ public class FrescoModule extends ReactContextBaseJavaModule implements SoLoader.loadLibrary(libraryName); } }); + + HashSet requestListeners = new HashSet<>(); + requestListeners.add(new SystraceRequestListener()); + Context context = this.getReactApplicationContext().getApplicationContext(); OkHttpClient okHttpClient = OkHttpClientProvider.getOkHttpClient(); ImagePipelineConfig config = OkHttpImagePipelineConfigFactory .newBuilder(context, okHttpClient) .setDownsampleEnabled(false) + .setRequestListeners(requestListeners) .build(); Fresco.initialize(context, config); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/SystraceRequestListener.java b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/SystraceRequestListener.java new file mode 100644 index 000000000..314a4dffa --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/SystraceRequestListener.java @@ -0,0 +1,196 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.react.modules.fresco; + +import java.util.HashMap; +import java.util.Map; + +import android.util.Pair; + +import com.facebook.imagepipeline.listener.RequestListener; +import com.facebook.imagepipeline.request.ImageRequest; +import com.facebook.systrace.Systrace; + +/** + * Logs requests to Systrace + */ +public class SystraceRequestListener implements RequestListener { + + int mCurrentID = 0; + Map> mProducerID = new HashMap<>(); + Map> mRequestsID = new HashMap<>(); + + @Override + public void onProducerStart(String requestId, String producerName) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + StringBuilder entryName = new StringBuilder(); + entryName.append("FRESCO_PRODUCER_"); + entryName.append(producerName.replace(':', '_')); + + Pair requestPair = Pair.create(mCurrentID, entryName.toString()); + Systrace.beginAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + requestPair.second, + mCurrentID); + mProducerID.put(requestId, requestPair); + mCurrentID++; + } + + @Override + public void onProducerFinishWithSuccess( + String requestId, + String producerName, + Map extraMap) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mProducerID.containsKey(requestId)) { + Pair entry = mProducerID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mProducerID.remove(requestId); + } + } + + @Override + public void onProducerFinishWithFailure( + String requestId, + String producerName, + Throwable throwable, + Map extraMap) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mProducerID.containsKey(requestId)) { + Pair entry = mProducerID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mProducerID.remove(requestId); + } + } + + @Override + public void onProducerFinishWithCancellation( + String requestId, String producerName, Map extraMap) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mProducerID.containsKey(requestId)) { + Pair entry = mProducerID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mProducerID.remove(requestId); + } + } + + @Override + public void onProducerEvent(String requestId, String producerName, String producerEventName) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + StringBuilder entryName = new StringBuilder(); + entryName.append("FRESCO_PRODUCER_EVENT_"); + entryName.append(requestId.replace(':', '_')); + entryName.append("_"); + entryName.append(producerName.replace(':', '_')); + entryName.append("_"); + entryName.append(producerEventName.replace(':', '_')); + Systrace.traceInstant( + Systrace.TRACE_TAG_REACT_FRESCO, + entryName.toString(), + Systrace.EventScope.THREAD); + } + + @Override + public void onRequestStart( + ImageRequest request, + Object callerContext, + String requestId, + boolean isPrefetch) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + StringBuilder entryName = new StringBuilder(); + entryName.append("FRESCO_REQUEST_"); + entryName.append(request.getSourceUri().toString().replace(':', '_')); + + Pair requestPair = Pair.create(mCurrentID, entryName.toString()); + Systrace.beginAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + requestPair.second, + mCurrentID); + mRequestsID.put(requestId, requestPair); + mCurrentID++; + } + + @Override + public void onRequestSuccess(ImageRequest request, String requestId, boolean isPrefetch) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mRequestsID.containsKey(requestId)) { + Pair entry = mRequestsID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mRequestsID.remove(requestId); + } + } + + @Override + public void onRequestFailure( + ImageRequest request, + String requestId, + Throwable throwable, + boolean isPrefetch) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mRequestsID.containsKey(requestId)) { + Pair entry = mRequestsID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mRequestsID.remove(requestId); + } + } + + @Override + public void onRequestCancellation(String requestId) { + if (!Systrace.isTracing(Systrace.TRACE_TAG_REACT_FRESCO)) { + return; + } + + if (mRequestsID.containsKey(requestId)) { + Pair entry = mRequestsID.get(requestId); + Systrace.endAsyncSection( + Systrace.TRACE_TAG_REACT_FRESCO, + entry.second, + entry.first); + mRequestsID.remove(requestId); + } + } + + @Override + public boolean requiresExtraMap(String id) { + return false; + } +}