From e58d9120bc00f771b65fa56ca3a5d47bc4f9b227 Mon Sep 17 00:00:00 2001 From: shahddaghash Date: Mon, 17 Feb 2025 03:33:05 -0800 Subject: [PATCH] Create a new `MetricsReporter.Factory` This includes creating a new Factory for `MetricsReporter` and adding it to Transformer. This is done as we need to create a new `MetricsReporter` for each export operation, so it makes sense to have a Factory. PiperOrigin-RevId: 727798528 (cherry picked from commit 6d408c2d31bddacb254bb0cc917e4ecd5d0e4b66) --- .../transformer/EditingMetricsCollector.java | 53 ++++++++++++++++--- .../media3/transformer/Transformer.java | 38 ++++++++++--- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/EditingMetricsCollector.java b/libraries/transformer/src/main/java/androidx/media3/transformer/EditingMetricsCollector.java index baa8be2faf..3b79d9f85b 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/EditingMetricsCollector.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/EditingMetricsCollector.java @@ -16,6 +16,7 @@ package androidx.media3.transformer; +import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Util.usToMs; import android.content.Context; @@ -32,6 +33,7 @@ import androidx.media3.common.C; import androidx.media3.common.ColorInfo; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; +import androidx.media3.common.util.Log; import androidx.media3.common.util.SystemClock; import com.google.common.collect.ImmutableList; import java.util.ArrayList; @@ -45,6 +47,11 @@ import java.util.List; /** Reports the collected metrics. */ public interface MetricsReporter extends AutoCloseable { + /** Factory for metrics reporters */ + interface Factory { + /** Returns a new {@link MetricsReporter}. */ + MetricsReporter create(); + } /** * Reports the given {@link EditingEndedEvent}. @@ -59,16 +66,31 @@ import java.util.List; * EditingSession}. */ static final class DefaultMetricsReporter implements MetricsReporter { + /** A {@link MetricsReporter.Factory} for {@link DefaultMetricsReporter}. */ + public static final class Factory implements MetricsReporter.Factory { + private final Context context; + + /** + * Creates an instance. + * + * @param context The {@link Context}. + */ + public Factory(Context context) { + this.context = context; + } + + @Override + public MetricsReporter create() { + return new DefaultMetricsReporter(context); + } + } /** The {@link EditingSession} to report collected metrics to. */ @Nullable private EditingSession editingSession; - /** - * Creates an instance. - * - * @param context A {@link Context}. - */ - public DefaultMetricsReporter(Context context) { + private boolean metricsReported; + + private DefaultMetricsReporter(Context context) { @Nullable MediaMetricsManager mediaMetricsManager = (MediaMetricsManager) context.getSystemService(Context.MEDIA_METRICS_SERVICE); @@ -79,9 +101,10 @@ import java.util.List; @Override public void reportMetrics(EditingEndedEvent editingEndedEvent) { + checkState(!metricsReported, "Metrics have already been reported."); if (editingSession != null) { editingSession.reportEditingEndedEvent(editingEndedEvent); - close(); + metricsReported = true; } } @@ -94,6 +117,7 @@ import java.util.List; } } + private static final String TAG = "EditingMetricsCollector"; // TODO: b/386328723 - Add missing error codes to EditingEndedEvent.ErrorCode. private static final SparseIntArray ERROR_CODE_CONVERSION_MAP = new SparseIntArray(); private static final SparseIntArray DATA_SPACE_STANDARD_CONVERSION_MAP = new SparseIntArray(); @@ -222,6 +246,11 @@ import java.util.List; editingEndedEventBuilder.setOutputMediaItemInfo(getOutputMediaItemInfo(exportResult)); metricsReporter.reportMetrics(editingEndedEventBuilder.build()); + try { + metricsReporter.close(); + } catch (Exception e) { + Log.e(TAG, "error while closing the metrics reporter", e); + } } /** @@ -250,6 +279,11 @@ import java.util.List; editingEndedEventBuilder.setOutputMediaItemInfo(getOutputMediaItemInfo(exportResult)); metricsReporter.reportMetrics(editingEndedEventBuilder.build()); + try { + metricsReporter.close(); + } catch (Exception e) { + Log.e(TAG, "error while closing the metrics reporter", e); + } } /** @@ -266,6 +300,11 @@ import java.util.List; } metricsReporter.reportMetrics(editingEndedEventBuilder.build()); + try { + metricsReporter.close(); + } catch (Exception e) { + Log.e(TAG, "error while closing the metrics reporter", e); + } } private EditingEndedEvent.Builder createEditingEndedEventBuilder(int finalState) { diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java index e7871e38cf..a2692c513a 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java @@ -122,6 +122,8 @@ public final class Transformer { private Looper looper; private DebugViewProvider debugViewProvider; private Clock clock; + private EditingMetricsCollector.MetricsReporter.@MonotonicNonNull Factory + metricsReporterFactory; /** * Creates a builder with default values. @@ -142,6 +144,10 @@ public final class Transformer { debugViewProvider = DebugViewProvider.NONE; clock = Clock.DEFAULT; listeners = new ListenerSet<>(looper, clock, (listener, flags) -> {}); + if (SDK_INT >= 35) { + metricsReporterFactory = + new EditingMetricsCollector.DefaultMetricsReporter.Factory(context); + } } /** Creates a builder with the values of the provided {@link Transformer}. */ @@ -169,6 +175,7 @@ public final class Transformer { this.looper = transformer.looper; this.debugViewProvider = transformer.debugViewProvider; this.clock = transformer.clock; + this.metricsReporterFactory = transformer.metricsReporterFactory; } /** @@ -515,6 +522,23 @@ public final class Transformer { return this; } + /** + * Sets the {@link EditingMetricsCollector.MetricsReporter.Factory} that will be used to report + * the metrics. + * + *

The default value is {@link EditingMetricsCollector.DefaultMetricsReporter.Factory}. + * + * @param metricsReporterFactory A {@link EditingMetricsCollector.MetricsReporter.Factory}. + * @return This builder. + */ + @CanIgnoreReturnValue + @VisibleForTesting + /* package */ Builder setMetricsReporterFactory( + EditingMetricsCollector.MetricsReporter.Factory metricsReporterFactory) { + this.metricsReporterFactory = metricsReporterFactory; + return this; + } + /** * Sets whether transformer reports diagnostics data to the Android platform. * @@ -582,7 +606,8 @@ public final class Transformer { muxerFactory, looper, debugViewProvider, - clock); + clock, + metricsReporterFactory); } private void checkSampleMimeType(String sampleMimeType) { @@ -772,7 +797,7 @@ public final class Transformer { private final HandlerWrapper applicationHandler; private final ComponentListener componentListener; private final ExportResult.Builder exportResultBuilder; - private @MonotonicNonNull EditingMetricsCollector editingMetricsCollector; + @Nullable private final EditingMetricsCollector.MetricsReporter.Factory metricsReporterFactory; @Nullable private TransformerInternal transformerInternal; @Nullable private MuxerWrapper remuxingMuxerWrapper; @@ -783,6 +808,7 @@ public final class Transformer { private TransmuxTranscodeHelper.@MonotonicNonNull ResumeMetadata resumeMetadata; private @MonotonicNonNull ListenableFuture getResumeMetadataFuture; + private @MonotonicNonNull EditingMetricsCollector editingMetricsCollector; private @MonotonicNonNull ListenableFuture copyOutputFuture; @Nullable private Mp4Info mediaItemInfo; @Nullable private WatchdogTimer exportWatchdogTimer; @@ -808,7 +834,8 @@ public final class Transformer { Muxer.Factory muxerFactory, Looper looper, DebugViewProvider debugViewProvider, - Clock clock) { + Clock clock, + @Nullable EditingMetricsCollector.MetricsReporter.Factory metricsReporterFactory) { checkState(!removeAudio || !removeVideo, "Audio and video cannot both be removed."); this.context = context; this.transformationRequest = transformationRequest; @@ -831,6 +858,7 @@ public final class Transformer { this.looper = looper; this.debugViewProvider = debugViewProvider; this.clock = clock; + this.metricsReporterFactory = metricsReporterFactory; transformerState = TRANSFORMER_STATE_PROCESS_FULL_INPUT; applicationHandler = clock.createHandler(looper, /* callback= */ null); componentListener = new ComponentListener(); @@ -1590,9 +1618,7 @@ public final class Transformer { } editingMetricsCollector = new EditingMetricsCollector( - new EditingMetricsCollector.DefaultMetricsReporter(context), - EXPORTER_NAME, - muxerName); + checkNotNull(metricsReporterFactory).create(), EXPORTER_NAME, muxerName); } transformerInternal = new TransformerInternal(