diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 371ad17d55..3f104d5190 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,6 +2,16 @@ ### dev-v2 (not yet released) +* Core library: + * Enable support for Android platform diagnostics via + `MediaMetricsManager`. ExoPlayer will forward playback events and + performance data to the platform, which helps to provide system + performance and debugging information on the device. This data may also + be collected by Google + [if sharing usage and diagnostics data is enabled](https://support.google.com/accounts/answer/6078260) + by the user of the device. Apps can opt-out of contributing to platform + diagnostics for ExoPlayer with + `ExoPlayer.Builder.setUsePlatformDiagnostics(false)`. * Track selection: * Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`, and promote `TrackSelectionOverride` to a top level class. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java index 7e98e3287b..86f24d77d1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java @@ -458,6 +458,7 @@ public interface ExoPlayer extends Player { /* package */ long releaseTimeoutMs; /* package */ long detachSurfaceTimeoutMs; /* package */ boolean pauseAtEndOfMediaItems; + /* package */ boolean usePlatformDiagnostics; /* package */ boolean buildCalled; /** @@ -498,6 +499,7 @@ public interface ExoPlayer extends Player { *
  • {@code releaseTimeoutMs}: {@link #DEFAULT_RELEASE_TIMEOUT_MS} *
  • {@code detachSurfaceTimeoutMs}: {@link #DEFAULT_DETACH_SURFACE_TIMEOUT_MS} *
  • {@code pauseAtEndOfMediaItems}: {@code false} + *
  • {@code usePlatformDiagnostics}: {@code true} *
  • {@link Clock}: {@link Clock#DEFAULT} * * @@ -643,6 +645,7 @@ public interface ExoPlayer extends Player { clock = Clock.DEFAULT; releaseTimeoutMs = DEFAULT_RELEASE_TIMEOUT_MS; detachSurfaceTimeoutMs = DEFAULT_DETACH_SURFACE_TIMEOUT_MS; + usePlatformDiagnostics = true; } /** @@ -1003,6 +1006,27 @@ public interface ExoPlayer extends Player { return this; } + /** + * Sets whether the player reports diagnostics data to the Android platform. + * + *

    If enabled, the player will use the {@link android.media.metrics.MediaMetricsManager} to + * create a {@link android.media.metrics.PlaybackSession} and forward playback events and + * performance data to this session. This helps to provide system performance and debugging + * information for media playback on the device. This data may also be collected by Google if sharing usage and diagnostics + * data is enabled by the user of the device. + * + * @param usePlatformDiagnostics Whether the player reports diagnostics data to the Android + * platform. + * @return This builder. + * @throws IllegalStateException If {@link #build()} has already been called. + */ + public Builder setUsePlatformDiagnostics(boolean usePlatformDiagnostics) { + checkState(!buildCalled); + this.usePlatformDiagnostics = usePlatformDiagnostics; + return this; + } + /** * Sets the {@link Clock} that will be used by the player. Should only be set for testing * purposes. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index b618193d96..3dc4ec43be 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -56,6 +56,7 @@ import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.Renderer.MessageType; import com.google.android.exoplayer2.analytics.AnalyticsCollector; import com.google.android.exoplayer2.analytics.AnalyticsListener; +import com.google.android.exoplayer2.analytics.MediaMetricsListener; import com.google.android.exoplayer2.analytics.PlayerId; import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioRendererEventListener; @@ -306,7 +307,11 @@ import java.util.concurrent.TimeoutException; playbackInfoUpdateHandler.post(() -> handlePlaybackInfo(playbackInfoUpdate)); playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult); analyticsCollector.setPlayer(this.wrappingPlayer, applicationLooper); - PlayerId playerId = Util.SDK_INT < 31 ? new PlayerId() : Api31.createPlayerId(); + PlayerId playerId = + Util.SDK_INT < 31 + ? new PlayerId() + : Api31.registerMediaMetricsListener( + applicationContext, /* player= */ this, builder.usePlatformDiagnostics); internalPlayer = new ExoPlayerImplInternal( renderers, @@ -3063,9 +3068,17 @@ import java.util.concurrent.TimeoutException; private Api31() {} @DoNotInline - public static PlayerId createPlayerId() { - // TODO: Create a MediaMetricsListener and obtain LogSessionId from it. - return new PlayerId(LogSessionId.LOG_SESSION_ID_NONE); + public static PlayerId registerMediaMetricsListener( + Context context, ExoPlayerImpl player, boolean usePlatformDiagnostics) { + @Nullable MediaMetricsListener listener = MediaMetricsListener.create(context); + if (listener == null) { + Log.w(TAG, "MediaMetricsService unavailable."); + return new PlayerId(LogSessionId.LOG_SESSION_ID_NONE); + } + if (usePlatformDiagnostics) { + player.addAnalyticsListener(listener); + } + return new PlayerId(listener.getLogSessionId()); } } }